@dosu/cli 0.53.0-beta.3 → 0.53.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/dosu.js +537 -458
  2. package/package.json +1 -1
package/bin/dosu.js CHANGED
@@ -5006,7 +5006,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
5006
5006
  function getVersionString() {
5007
5007
  return `v${VERSION}`;
5008
5008
  }
5009
- var VERSION = "0.53.0-beta.3", INSTALL_CHANNEL = "npm";
5009
+ var VERSION = "0.53.0-beta.5", INSTALL_CHANNEL = "npm";
5010
5010
 
5011
5011
  // src/debug/logger.ts
5012
5012
  import {
@@ -8346,258 +8346,25 @@ var init_agents = __esm(() => {
8346
8346
  init_formats();
8347
8347
  });
8348
8348
 
8349
- // src/sync/lock.ts
8350
- import { existsSync as existsSync9, readFileSync as readFileSync9, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync6 } from "node:fs";
8351
- import { join as join8 } from "node:path";
8352
- function processAlive(pid) {
8353
- try {
8354
- process.kill(pid, 0);
8355
- return true;
8356
- } catch (err) {
8357
- return err.code === "EPERM";
8358
- }
8359
- }
8360
- function lockPath(configDir = getConfigDir()) {
8361
- return join8(configDir, LOCK_FILENAME);
8362
- }
8363
- function fileLock(configDir = getConfigDir(), now = () => new Date) {
8364
- const path3 = lockPath(configDir);
8365
- let held = false;
8366
- const tryCreate = () => {
8367
- try {
8368
- writeFileSync6(path3, String(process.pid), { flag: "wx" });
8369
- return true;
8370
- } catch {
8371
- return false;
8372
- }
8373
- };
8374
- return {
8375
- acquire() {
8376
- if (tryCreate()) {
8377
- held = true;
8378
- return true;
8379
- }
8380
- try {
8381
- const age = now().getTime() - statSync3(path3).mtimeMs;
8382
- const holder = Number.parseInt(readFileSync9(path3, "utf8"), 10);
8383
- const holderDead = Number.isInteger(holder) && holder > 0 && !processAlive(holder);
8384
- if (age > STALE_LOCK_MS || holderDead) {
8385
- rmSync2(path3, { force: true });
8386
- held = tryCreate();
8387
- return held;
8388
- }
8389
- } catch {}
8390
- return false;
8391
- },
8392
- release() {
8393
- if (!held)
8394
- return;
8395
- held = false;
8396
- try {
8397
- if (existsSync9(path3) && readFileSync9(path3, "utf8") === String(process.pid)) {
8398
- rmSync2(path3, { force: true });
8399
- }
8400
- } catch {}
8401
- }
8402
- };
8403
- }
8404
- var LOCK_FILENAME = "knowledge-sync.lock", STALE_LOCK_MS;
8405
- var init_lock = __esm(() => {
8406
- init_config();
8407
- STALE_LOCK_MS = 15 * 60 * 1000;
8408
- });
8409
-
8410
- // src/sync/watermark.ts
8411
- import { existsSync as existsSync10, mkdirSync as mkdirSync6, readFileSync as readFileSync10, renameSync as renameSync2, writeFileSync as writeFileSync7 } from "node:fs";
8412
- import { join as join9 } from "node:path";
8413
- function syncStatePath(configDir = getConfigDir()) {
8414
- return join9(configDir, STATE_FILENAME);
8415
- }
8416
- function loadSyncState(configDir = getConfigDir()) {
8417
- const empty = {
8418
- schema_version: STATE_SCHEMA_VERSION,
8419
- watermark: null,
8420
- consecutive_failures: 0
8421
- };
8422
- const path3 = syncStatePath(configDir);
8423
- if (!existsSync10(path3))
8424
- return empty;
8425
- try {
8426
- const raw = JSON.parse(readFileSync10(path3, "utf-8"));
8427
- if (raw.schema_version !== STATE_SCHEMA_VERSION)
8428
- return empty;
8429
- const minedSessions = Array.isArray(raw.mined_sessions) ? raw.mined_sessions.filter((record) => typeof record === "object" && record !== null && typeof record.at === "string" && typeof record.session === "string").map((record) => ({
8430
- at: record.at,
8431
- session: record.session,
8432
- ...typeof record.project === "string" ? { project: record.project } : {}
8433
- })) : [];
8434
- const rawRefusal = raw.last_refusal;
8435
- const lastRefusal = rawRefusal && typeof rawRefusal.at === "string" && typeof rawRefusal.outcome === "string" && typeof rawRefusal.message === "string" ? { at: rawRefusal.at, outcome: rawRefusal.outcome, message: rawRefusal.message } : undefined;
8436
- const rawRun = raw.run;
8437
- const run2 = rawRun && typeof rawRun.pid === "number" && typeof rawRun.started_at === "string" && typeof rawRun.baseline_mined === "number" && rawRun.baseline_mined >= 0 ? { pid: rawRun.pid, started_at: rawRun.started_at, baseline_mined: rawRun.baseline_mined } : undefined;
8438
- return {
8439
- schema_version: STATE_SCHEMA_VERSION,
8440
- watermark: typeof raw.watermark === "string" ? raw.watermark : null,
8441
- last_attempt_at: typeof raw.last_attempt_at === "string" ? raw.last_attempt_at : undefined,
8442
- consecutive_failures: typeof raw.consecutive_failures === "number" && raw.consecutive_failures >= 0 ? raw.consecutive_failures : 0,
8443
- mined_sessions: minedSessions,
8444
- total_mined: typeof raw.total_mined === "number" && raw.total_mined >= 0 ? raw.total_mined : minedSessions.length,
8445
- total_notes: typeof raw.total_notes === "number" && raw.total_notes >= 0 ? raw.total_notes : 0,
8446
- total_learning_tokens: typeof raw.total_learning_tokens === "number" && raw.total_learning_tokens >= 0 ? raw.total_learning_tokens : 0,
8447
- ...lastRefusal ? { last_refusal: lastRefusal } : {},
8448
- ...run2 ? { run: run2 } : {},
8449
- ...Array.isArray(raw.project_filter) ? {
8450
- project_filter: raw.project_filter.filter((p2) => typeof p2 === "string")
8451
- } : {}
8452
- };
8453
- } catch {
8454
- return empty;
8455
- }
8456
- }
8457
- function saveSyncState(state, configDir = getConfigDir()) {
8458
- if (!existsSync10(configDir))
8459
- mkdirSync6(configDir, { recursive: true, mode: 448 });
8460
- const path3 = syncStatePath(configDir);
8461
- const tmp = `${path3}.${process.pid}.tmp`;
8462
- writeFileSync7(tmp, JSON.stringify(state, null, 2), { mode: 384 });
8463
- renameSync2(tmp, path3);
8464
- }
8465
- function backoffUntil(state) {
8466
- if (state.consecutive_failures === 0 || !state.last_attempt_at)
8467
- return null;
8468
- const last = Date.parse(state.last_attempt_at);
8469
- if (Number.isNaN(last))
8470
- return null;
8471
- const delay = Math.min(BACKOFF_BASE_MS * 2 ** (state.consecutive_failures - 1), BACKOFF_MAX_MS);
8472
- return new Date(last + delay);
8473
- }
8474
- function isUnderDir(dir, base) {
8475
- const root = base.endsWith("/") ? base.slice(0, -1) : base;
8476
- return dir === root || dir.startsWith(`${root}/`);
8477
- }
8478
- function filterSessionsByProject(sessions, filter, resolveDir) {
8479
- if (!filter || filter.length === 0)
8480
- return [...sessions];
8481
- const includeUnknown = filter.includes(UNKNOWN_PROJECT);
8482
- const dirs = filter.filter((entry) => entry !== UNKNOWN_PROJECT);
8483
- return sessions.filter((session) => {
8484
- const dir = resolveDir(session);
8485
- if (!dir)
8486
- return includeUnknown;
8487
- return dirs.some((base) => isUnderDir(dir, base));
8488
- });
8489
- }
8490
- function gateSessions(sessions, watermark, now = new Date, quietPeriodMs = DEFAULT_QUIET_PERIOD_MS) {
8491
- const watermarkMs = watermark ? Date.parse(watermark) : Number.NEGATIVE_INFINITY;
8492
- const completedBefore = now.getTime() - quietPeriodMs;
8493
- const ready = [];
8494
- const open2 = [];
8495
- for (const session of sessions) {
8496
- const updated = Date.parse(session.updated);
8497
- if (Number.isNaN(updated) || updated <= watermarkMs)
8498
- continue;
8499
- if (updated > completedBefore) {
8500
- open2.push(session);
8501
- } else {
8502
- ready.push(session);
8503
- }
8504
- }
8505
- return { ready, open: open2 };
8506
- }
8507
- var STATE_FILENAME = "knowledge-sync.json", STATE_SCHEMA_VERSION = 1, DEFAULT_QUIET_PERIOD_MS, BACKOFF_BASE_MS, BACKOFF_MAX_MS, MINED_HISTORY_LIMIT = 500, UNKNOWN_PROJECT = "(unknown)";
8508
- var init_watermark = __esm(() => {
8509
- init_config();
8510
- DEFAULT_QUIET_PERIOD_MS = 5 * 60 * 1000;
8511
- BACKOFF_BASE_MS = 15 * 60 * 1000;
8512
- BACKOFF_MAX_MS = 24 * 60 * 60 * 1000;
8513
- });
8514
-
8515
- // src/sync/status.ts
8516
- import { readFileSync as readFileSync11, statSync as statSync4 } from "node:fs";
8517
- function formatTokenCount(tokens) {
8518
- if (tokens < 1000)
8519
- return String(tokens);
8520
- if (tokens < 1e6) {
8521
- const k = tokens / 1000;
8522
- return `~${k >= 100 ? Math.round(k) : k.toFixed(1).replace(/\.0$/, "")}k`;
8523
- }
8524
- const m3 = tokens / 1e6;
8525
- return `~${m3 >= 100 ? Math.round(m3) : m3.toFixed(1).replace(/\.0$/, "")}M`;
8526
- }
8527
- function defaultIsProcessAlive2(pid) {
8528
- if (!Number.isInteger(pid) || pid <= 0)
8529
- return false;
8530
- try {
8531
- process.kill(pid, 0);
8532
- return true;
8533
- } catch (err) {
8534
- return err.code === "EPERM";
8535
- }
8536
- }
8537
- function defaultReadLog() {
8538
- try {
8539
- return readFileSync11(logger.getLogPath(), "utf-8");
8540
- } catch {
8541
- return "";
8542
- }
8543
- }
8544
- function readLockFile(configDir) {
8545
- const path3 = lockPath(configDir);
8546
- try {
8547
- const pid = Number.parseInt(readFileSync11(path3, "utf-8"), 10);
8548
- return { pid: Number.isNaN(pid) ? -1 : pid, mtime: statSync4(path3).mtime };
8549
- } catch {
8550
- return null;
8551
- }
8552
- }
8553
- function recentSyncActivity(log3) {
8554
- return log3.split(`
8555
- `).filter((line) => line.includes("[sync]") || line.includes("[miner]")).slice(-ACTIVITY_LINES).map((line) => line.replace(/ \[(DEBUG|INFO|WARN|ERROR)\]/, ""));
8556
- }
8557
- function getSyncStatus(deps = {}) {
8558
- const configDir = deps.configDir ?? getConfigDir();
8559
- const isProcessAlive = deps.isProcessAlive ?? defaultIsProcessAlive2;
8560
- const readLog = deps.readLog ?? defaultReadLog;
8561
- const lock = readLockFile(configDir);
8562
- const running = lock !== null && isProcessAlive(lock.pid);
8563
- const state = loadSyncState(configDir);
8564
- const retryAt = backoffUntil(state);
8565
- return {
8566
- running,
8567
- ...lock ? { pid: lock.pid, startedAt: lock.mtime.toISOString() } : {},
8568
- ...lock && !running ? { staleLock: true } : {},
8569
- state,
8570
- ...retryAt ? { backoffUntil: retryAt.toISOString() } : {},
8571
- recentActivity: recentSyncActivity(readLog())
8572
- };
8573
- }
8574
- var ACTIVITY_LINES = 10;
8575
- var init_status = __esm(() => {
8576
- init_config();
8577
- init_logger();
8578
- init_lock();
8579
- init_watermark();
8580
- });
8581
-
8582
8349
  // src/sessions/project-dir.ts
8583
8350
  import {
8584
8351
  closeSync as closeSync2,
8585
- existsSync as existsSync11,
8586
- mkdirSync as mkdirSync7,
8352
+ existsSync as existsSync9,
8353
+ mkdirSync as mkdirSync6,
8587
8354
  openSync as openSync2,
8588
- readFileSync as readFileSync12,
8355
+ readFileSync as readFileSync9,
8589
8356
  readSync,
8590
- renameSync as renameSync3,
8591
- statSync as statSync5,
8592
- writeFileSync as writeFileSync8
8357
+ renameSync as renameSync2,
8358
+ statSync as statSync3,
8359
+ writeFileSync as writeFileSync6
8593
8360
  } from "node:fs";
8594
- import { join as join10 } from "node:path";
8361
+ import { join as join8 } from "node:path";
8595
8362
  function cachePath(configDir) {
8596
- return join10(configDir, CACHE_FILENAME2);
8363
+ return join8(configDir, CACHE_FILENAME2);
8597
8364
  }
8598
8365
  function loadCacheFile(configDir) {
8599
8366
  try {
8600
- const raw = JSON.parse(readFileSync12(cachePath(configDir), "utf-8"));
8367
+ const raw = JSON.parse(readFileSync9(cachePath(configDir), "utf-8"));
8601
8368
  if (raw.schema_version !== CACHE_SCHEMA_VERSION || typeof raw.entries !== "object")
8602
8369
  return {};
8603
8370
  return raw.entries;
@@ -8607,13 +8374,13 @@ function loadCacheFile(configDir) {
8607
8374
  }
8608
8375
  function saveCacheFile(configDir, entries) {
8609
8376
  try {
8610
- if (!existsSync11(configDir))
8611
- mkdirSync7(configDir, { recursive: true, mode: 448 });
8377
+ if (!existsSync9(configDir))
8378
+ mkdirSync6(configDir, { recursive: true, mode: 448 });
8612
8379
  const path3 = cachePath(configDir);
8613
8380
  const tmp = `${path3}.${process.pid}.tmp`;
8614
8381
  const file = { schema_version: CACHE_SCHEMA_VERSION, entries };
8615
- writeFileSync8(tmp, JSON.stringify(file), { mode: 384 });
8616
- renameSync3(tmp, path3);
8382
+ writeFileSync6(tmp, JSON.stringify(file), { mode: 384 });
8383
+ renameSync2(tmp, path3);
8617
8384
  } catch {}
8618
8385
  }
8619
8386
  function readHead(path3, bytes = HEAD_BYTES) {
@@ -8647,7 +8414,7 @@ function cwdFromJsonlHead(text) {
8647
8414
  }
8648
8415
  return null;
8649
8416
  }
8650
- function unmungeSlug(slug, exists = existsSync11) {
8417
+ function unmungeSlug(slug, exists = existsSync9) {
8651
8418
  const tokens = slug.replace(/^-/, "").split("-");
8652
8419
  if (tokens.length === 0 || tokens[0] === "")
8653
8420
  return null;
@@ -8666,13 +8433,13 @@ function unmungeSlug(slug, exists = existsSync11) {
8666
8433
  }
8667
8434
  function fileMtime(path3) {
8668
8435
  try {
8669
- return statSync5(path3).mtime.toISOString();
8436
+ return statSync3(path3).mtime.toISOString();
8670
8437
  } catch {
8671
8438
  return "";
8672
8439
  }
8673
8440
  }
8674
8441
  function createProjectDirResolver(configDir = getConfigDir(), deps = {}) {
8675
- const exists = deps.exists ?? existsSync11;
8442
+ const exists = deps.exists ?? existsSync9;
8676
8443
  const head = deps.readHead ?? readHead;
8677
8444
  const mtime = deps.mtime ?? fileMtime;
8678
8445
  const entries = loadCacheFile(configDir);
@@ -8725,15 +8492,15 @@ var init_project_dir = __esm(() => {
8725
8492
  });
8726
8493
 
8727
8494
  // src/sessions/scan.ts
8728
- import { existsSync as existsSync12, readdirSync, statSync as statSync6 } from "node:fs";
8495
+ import { existsSync as existsSync10, readdirSync, statSync as statSync4 } from "node:fs";
8729
8496
  import { createRequire as createRequire2 } from "node:module";
8730
8497
  import { homedir as homedir3 } from "node:os";
8731
- import { basename, join as join11 } from "node:path";
8498
+ import { basename, join as join9 } from "node:path";
8732
8499
  function listDir(dir) {
8733
8500
  try {
8734
8501
  return readdirSync(dir, { withFileTypes: true }).map((entry) => ({
8735
8502
  name: entry.name,
8736
- path: join11(dir, entry.name),
8503
+ path: join9(dir, entry.name),
8737
8504
  isDir: entry.isDirectory()
8738
8505
  }));
8739
8506
  } catch {
@@ -8746,7 +8513,7 @@ function sessionFromFile(filePath, harness, project) {
8746
8513
  return null;
8747
8514
  let mtime;
8748
8515
  try {
8749
- mtime = statSync6(filePath).mtime;
8516
+ mtime = statSync4(filePath).mtime;
8750
8517
  } catch {
8751
8518
  return null;
8752
8519
  }
@@ -8760,7 +8527,7 @@ function sessionFromFile(filePath, harness, project) {
8760
8527
  }
8761
8528
  function scanClaude(home) {
8762
8529
  const sessions = [];
8763
- for (const project of listDir(join11(home, ".claude", "projects"))) {
8530
+ for (const project of listDir(join9(home, ".claude", "projects"))) {
8764
8531
  if (!project.isDir)
8765
8532
  continue;
8766
8533
  for (const entry of listDir(project.path)) {
@@ -8775,10 +8542,10 @@ function scanClaude(home) {
8775
8542
  }
8776
8543
  function scanCursor(home) {
8777
8544
  const sessions = [];
8778
- for (const project of listDir(join11(home, ".cursor", "projects"))) {
8545
+ for (const project of listDir(join9(home, ".cursor", "projects"))) {
8779
8546
  if (!project.isDir)
8780
8547
  continue;
8781
- for (const entry of listDir(join11(project.path, "agent-transcripts"))) {
8548
+ for (const entry of listDir(join9(project.path, "agent-transcripts"))) {
8782
8549
  const files = entry.isDir ? listDir(entry.path).filter((f2) => !f2.isDir) : [entry];
8783
8550
  for (const file of files) {
8784
8551
  const session = sessionFromFile(file.path, "cursor", project.name);
@@ -8790,9 +8557,9 @@ function scanCursor(home) {
8790
8557
  return sessions;
8791
8558
  }
8792
8559
  function scanCodex(home, env) {
8793
- const codexHome2 = env.CODEX_HOME ?? join11(home, ".codex");
8560
+ const codexHome2 = env.CODEX_HOME ?? join9(home, ".codex");
8794
8561
  const sessions = [];
8795
- for (const year of listDir(join11(codexHome2, "sessions"))) {
8562
+ for (const year of listDir(join9(codexHome2, "sessions"))) {
8796
8563
  if (!year.isDir)
8797
8564
  continue;
8798
8565
  for (const month of listDir(year.path)) {
@@ -8848,9 +8615,9 @@ function querySqlite(dbPath, sql) {
8848
8615
  }
8849
8616
  }
8850
8617
  function scanOpencode(home, env) {
8851
- const dataDir = env.XDG_DATA_HOME ?? join11(home, ".local", "share");
8852
- const dbPath = join11(dataDir, "opencode", "opencode.db");
8853
- if (!existsSync12(dbPath))
8618
+ const dataDir = env.XDG_DATA_HOME ?? join9(home, ".local", "share");
8619
+ const dbPath = join9(dataDir, "opencode", "opencode.db");
8620
+ if (!existsSync10(dbPath))
8854
8621
  return [];
8855
8622
  const rows = querySqlite(dbPath, "SELECT id, directory, time_updated FROM session WHERE parent_id IS NULL");
8856
8623
  if (!rows)
@@ -8887,6 +8654,291 @@ function scanAgentSessions(options = {}) {
8887
8654
  }
8888
8655
  var init_scan = () => {};
8889
8656
 
8657
+ // src/sync/watermark.ts
8658
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync10, renameSync as renameSync3, writeFileSync as writeFileSync7 } from "node:fs";
8659
+ import { join as join10 } from "node:path";
8660
+ function syncStatePath(configDir = getConfigDir()) {
8661
+ return join10(configDir, STATE_FILENAME);
8662
+ }
8663
+ function loadSyncState(configDir = getConfigDir()) {
8664
+ const empty = {
8665
+ schema_version: STATE_SCHEMA_VERSION,
8666
+ watermark: null,
8667
+ consecutive_failures: 0
8668
+ };
8669
+ const path3 = syncStatePath(configDir);
8670
+ if (!existsSync11(path3))
8671
+ return empty;
8672
+ try {
8673
+ const raw = JSON.parse(readFileSync10(path3, "utf-8"));
8674
+ if (raw.schema_version !== STATE_SCHEMA_VERSION)
8675
+ return empty;
8676
+ const minedSessions = Array.isArray(raw.mined_sessions) ? raw.mined_sessions.filter((record) => typeof record === "object" && record !== null && typeof record.at === "string" && typeof record.session === "string").map((record) => ({
8677
+ at: record.at,
8678
+ session: record.session,
8679
+ ...typeof record.project === "string" ? { project: record.project } : {}
8680
+ })) : [];
8681
+ const rawRefusal = raw.last_refusal;
8682
+ const lastRefusal = rawRefusal && typeof rawRefusal.at === "string" && typeof rawRefusal.outcome === "string" && typeof rawRefusal.message === "string" ? { at: rawRefusal.at, outcome: rawRefusal.outcome, message: rawRefusal.message } : undefined;
8683
+ const rawRun = raw.run;
8684
+ const run2 = rawRun && typeof rawRun.pid === "number" && typeof rawRun.started_at === "string" && typeof rawRun.baseline_mined === "number" && rawRun.baseline_mined >= 0 ? { pid: rawRun.pid, started_at: rawRun.started_at, baseline_mined: rawRun.baseline_mined } : undefined;
8685
+ return {
8686
+ schema_version: STATE_SCHEMA_VERSION,
8687
+ watermark: typeof raw.watermark === "string" ? raw.watermark : null,
8688
+ last_attempt_at: typeof raw.last_attempt_at === "string" ? raw.last_attempt_at : undefined,
8689
+ consecutive_failures: typeof raw.consecutive_failures === "number" && raw.consecutive_failures >= 0 ? raw.consecutive_failures : 0,
8690
+ mined_sessions: minedSessions,
8691
+ total_mined: typeof raw.total_mined === "number" && raw.total_mined >= 0 ? raw.total_mined : minedSessions.length,
8692
+ total_notes: typeof raw.total_notes === "number" && raw.total_notes >= 0 ? raw.total_notes : 0,
8693
+ total_learning_tokens: typeof raw.total_learning_tokens === "number" && raw.total_learning_tokens >= 0 ? raw.total_learning_tokens : 0,
8694
+ ...lastRefusal ? { last_refusal: lastRefusal } : {},
8695
+ ...run2 ? { run: run2 } : {},
8696
+ ...raw.paused === true ? { paused: true } : {},
8697
+ ...Array.isArray(raw.project_filter) ? {
8698
+ project_filter: raw.project_filter.filter((p2) => typeof p2 === "string")
8699
+ } : {}
8700
+ };
8701
+ } catch {
8702
+ return empty;
8703
+ }
8704
+ }
8705
+ function setSyncPaused(paused, configDir = getConfigDir()) {
8706
+ const state = loadSyncState(configDir);
8707
+ if (paused)
8708
+ state.paused = true;
8709
+ else
8710
+ delete state.paused;
8711
+ saveSyncState(state, configDir);
8712
+ }
8713
+ function saveSyncState(state, configDir = getConfigDir()) {
8714
+ if (!existsSync11(configDir))
8715
+ mkdirSync7(configDir, { recursive: true, mode: 448 });
8716
+ const path3 = syncStatePath(configDir);
8717
+ const tmp = `${path3}.${process.pid}.tmp`;
8718
+ writeFileSync7(tmp, JSON.stringify(state, null, 2), { mode: 384 });
8719
+ renameSync3(tmp, path3);
8720
+ }
8721
+ function backoffUntil(state) {
8722
+ if (state.consecutive_failures === 0 || !state.last_attempt_at)
8723
+ return null;
8724
+ const last = Date.parse(state.last_attempt_at);
8725
+ if (Number.isNaN(last))
8726
+ return null;
8727
+ const delay = Math.min(BACKOFF_BASE_MS * 2 ** (state.consecutive_failures - 1), BACKOFF_MAX_MS);
8728
+ return new Date(last + delay);
8729
+ }
8730
+ function isUnderDir(dir, base) {
8731
+ const root = base.endsWith("/") ? base.slice(0, -1) : base;
8732
+ return dir === root || dir.startsWith(`${root}/`);
8733
+ }
8734
+ function filterSessionsByProject(sessions, filter, resolveDir) {
8735
+ if (!filter || filter.length === 0)
8736
+ return [...sessions];
8737
+ const includeUnknown = filter.includes(UNKNOWN_PROJECT);
8738
+ const dirs = filter.filter((entry) => entry !== UNKNOWN_PROJECT);
8739
+ return sessions.filter((session) => {
8740
+ const dir = resolveDir(session);
8741
+ if (!dir)
8742
+ return includeUnknown;
8743
+ return dirs.some((base) => isUnderDir(dir, base));
8744
+ });
8745
+ }
8746
+ function gateSessions(sessions, watermark, now = new Date, quietPeriodMs = DEFAULT_QUIET_PERIOD_MS) {
8747
+ const watermarkMs = watermark ? Date.parse(watermark) : Number.NEGATIVE_INFINITY;
8748
+ const completedBefore = now.getTime() - quietPeriodMs;
8749
+ const ready = [];
8750
+ const open2 = [];
8751
+ for (const session of sessions) {
8752
+ const updated = Date.parse(session.updated);
8753
+ if (Number.isNaN(updated) || updated <= watermarkMs)
8754
+ continue;
8755
+ if (updated > completedBefore) {
8756
+ open2.push(session);
8757
+ } else {
8758
+ ready.push(session);
8759
+ }
8760
+ }
8761
+ return { ready, open: open2 };
8762
+ }
8763
+ var STATE_FILENAME = "knowledge-sync.json", STATE_SCHEMA_VERSION = 1, DEFAULT_QUIET_PERIOD_MS, BACKOFF_BASE_MS, BACKOFF_MAX_MS, MINED_HISTORY_LIMIT = 500, UNKNOWN_PROJECT = "(unknown)";
8764
+ var init_watermark = __esm(() => {
8765
+ init_config();
8766
+ DEFAULT_QUIET_PERIOD_MS = 5 * 60 * 1000;
8767
+ BACKOFF_BASE_MS = 15 * 60 * 1000;
8768
+ BACKOFF_MAX_MS = 24 * 60 * 60 * 1000;
8769
+ });
8770
+
8771
+ // src/sync/backlog.ts
8772
+ function listSessionBacklog() {
8773
+ try {
8774
+ const state = loadSyncState();
8775
+ let sessions = scanAgentSessions({});
8776
+ if (state.project_filter?.length) {
8777
+ const resolver = createProjectDirResolver();
8778
+ sessions = filterSessionsByProject(sessions, state.project_filter, resolver.resolve);
8779
+ resolver.flush();
8780
+ }
8781
+ const gate = gateSessions(sessions, state.watermark);
8782
+ return { queued: gate.ready.reverse(), open: gate.open.reverse() };
8783
+ } catch {
8784
+ return { queued: [], open: [] };
8785
+ }
8786
+ }
8787
+ var init_backlog = __esm(() => {
8788
+ init_project_dir();
8789
+ init_scan();
8790
+ init_watermark();
8791
+ });
8792
+
8793
+ // src/sync/lock.ts
8794
+ import { existsSync as existsSync12, readFileSync as readFileSync11, rmSync as rmSync2, statSync as statSync5, writeFileSync as writeFileSync8 } from "node:fs";
8795
+ import { join as join11 } from "node:path";
8796
+ function processAlive(pid) {
8797
+ try {
8798
+ process.kill(pid, 0);
8799
+ return true;
8800
+ } catch (err) {
8801
+ return err.code === "EPERM";
8802
+ }
8803
+ }
8804
+ function lockPath(configDir = getConfigDir()) {
8805
+ return join11(configDir, LOCK_FILENAME);
8806
+ }
8807
+ function stopSyncRun(pid, configDir = getConfigDir(), kill = process.kill.bind(process)) {
8808
+ if (!Number.isInteger(pid) || pid <= 0)
8809
+ return false;
8810
+ let killed = false;
8811
+ try {
8812
+ kill(-pid, "SIGTERM");
8813
+ killed = true;
8814
+ } catch {
8815
+ try {
8816
+ kill(pid, "SIGTERM");
8817
+ killed = true;
8818
+ } catch {}
8819
+ }
8820
+ try {
8821
+ const path3 = lockPath(configDir);
8822
+ if (existsSync12(path3) && readFileSync11(path3, "utf8") === String(pid)) {
8823
+ rmSync2(path3, { force: true });
8824
+ }
8825
+ } catch {}
8826
+ return killed;
8827
+ }
8828
+ function fileLock(configDir = getConfigDir(), now = () => new Date) {
8829
+ const path3 = lockPath(configDir);
8830
+ let held = false;
8831
+ const tryCreate = () => {
8832
+ try {
8833
+ writeFileSync8(path3, String(process.pid), { flag: "wx" });
8834
+ return true;
8835
+ } catch {
8836
+ return false;
8837
+ }
8838
+ };
8839
+ return {
8840
+ acquire() {
8841
+ if (tryCreate()) {
8842
+ held = true;
8843
+ return true;
8844
+ }
8845
+ try {
8846
+ const age = now().getTime() - statSync5(path3).mtimeMs;
8847
+ const holder = Number.parseInt(readFileSync11(path3, "utf8"), 10);
8848
+ const holderDead = Number.isInteger(holder) && holder > 0 && !processAlive(holder);
8849
+ if (age > STALE_LOCK_MS || holderDead) {
8850
+ rmSync2(path3, { force: true });
8851
+ held = tryCreate();
8852
+ return held;
8853
+ }
8854
+ } catch {}
8855
+ return false;
8856
+ },
8857
+ release() {
8858
+ if (!held)
8859
+ return;
8860
+ held = false;
8861
+ try {
8862
+ if (existsSync12(path3) && readFileSync11(path3, "utf8") === String(process.pid)) {
8863
+ rmSync2(path3, { force: true });
8864
+ }
8865
+ } catch {}
8866
+ }
8867
+ };
8868
+ }
8869
+ var LOCK_FILENAME = "knowledge-sync.lock", STALE_LOCK_MS;
8870
+ var init_lock = __esm(() => {
8871
+ init_config();
8872
+ STALE_LOCK_MS = 15 * 60 * 1000;
8873
+ });
8874
+
8875
+ // src/sync/status.ts
8876
+ import { readFileSync as readFileSync12, statSync as statSync6 } from "node:fs";
8877
+ function formatTokenCount(tokens) {
8878
+ if (tokens < 1000)
8879
+ return String(tokens);
8880
+ if (tokens < 1e6) {
8881
+ const k = tokens / 1000;
8882
+ return `~${k >= 100 ? Math.round(k) : k.toFixed(1).replace(/\.0$/, "")}k`;
8883
+ }
8884
+ const m3 = tokens / 1e6;
8885
+ return `~${m3 >= 100 ? Math.round(m3) : m3.toFixed(1).replace(/\.0$/, "")}M`;
8886
+ }
8887
+ function defaultIsProcessAlive2(pid) {
8888
+ if (!Number.isInteger(pid) || pid <= 0)
8889
+ return false;
8890
+ try {
8891
+ process.kill(pid, 0);
8892
+ return true;
8893
+ } catch (err) {
8894
+ return err.code === "EPERM";
8895
+ }
8896
+ }
8897
+ function defaultReadLog() {
8898
+ try {
8899
+ return readFileSync12(logger.getLogPath(), "utf-8");
8900
+ } catch {
8901
+ return "";
8902
+ }
8903
+ }
8904
+ function readLockFile(configDir) {
8905
+ const path3 = lockPath(configDir);
8906
+ try {
8907
+ const pid = Number.parseInt(readFileSync12(path3, "utf-8"), 10);
8908
+ return { pid: Number.isNaN(pid) ? -1 : pid, mtime: statSync6(path3).mtime };
8909
+ } catch {
8910
+ return null;
8911
+ }
8912
+ }
8913
+ function recentSyncActivity(log3) {
8914
+ return log3.split(`
8915
+ `).filter((line) => line.includes("[sync]") || line.includes("[miner]")).slice(-ACTIVITY_LINES).map((line) => line.replace(/ \[(DEBUG|INFO|WARN|ERROR)\]/, ""));
8916
+ }
8917
+ function getSyncStatus(deps = {}) {
8918
+ const configDir = deps.configDir ?? getConfigDir();
8919
+ const isProcessAlive = deps.isProcessAlive ?? defaultIsProcessAlive2;
8920
+ const readLog = deps.readLog ?? defaultReadLog;
8921
+ const lock = readLockFile(configDir);
8922
+ const running = lock !== null && isProcessAlive(lock.pid);
8923
+ const state = loadSyncState(configDir);
8924
+ const retryAt = backoffUntil(state);
8925
+ return {
8926
+ running,
8927
+ ...lock ? { pid: lock.pid, startedAt: lock.mtime.toISOString() } : {},
8928
+ ...lock && !running ? { staleLock: true } : {},
8929
+ state,
8930
+ ...retryAt ? { backoffUntil: retryAt.toISOString() } : {},
8931
+ recentActivity: recentSyncActivity(readLog())
8932
+ };
8933
+ }
8934
+ var ACTIVITY_LINES = 10;
8935
+ var init_status = __esm(() => {
8936
+ init_config();
8937
+ init_logger();
8938
+ init_lock();
8939
+ init_watermark();
8940
+ });
8941
+
8890
8942
  // src/sessions/read.ts
8891
8943
  import { readFileSync as readFileSync13 } from "node:fs";
8892
8944
  function asRecord(value) {
@@ -9062,11 +9114,18 @@ async function runKnowledgeSync(options = {}) {
9062
9114
  const now = deps.now ?? (() => new Date);
9063
9115
  const state = loadState();
9064
9116
  if (options.quiet) {
9117
+ if (state.paused) {
9118
+ logger.debug("sync", "skipping quiet sync: mining is paused");
9119
+ return { status: "skipped-paused", readySessions: 0, inFlightSessions: 0, sessions: [] };
9120
+ }
9065
9121
  const retryAt = backoffUntil(state);
9066
9122
  if (retryAt && now() < retryAt) {
9067
9123
  logger.debug("sync", `skipping quiet sync: backoff until ${retryAt.toISOString()}`);
9068
9124
  return { status: "skipped-backoff", readySessions: 0, inFlightSessions: 0, sessions: [] };
9069
9125
  }
9126
+ } else if (state.paused) {
9127
+ delete state.paused;
9128
+ logger.debug("sync", "manual sync resumes paused mining");
9070
9129
  }
9071
9130
  let ready;
9072
9131
  let open2;
@@ -9420,20 +9479,12 @@ Read each session with read_session, decide what (if anything) is durable per yo
9420
9479
  }
9421
9480
 
9422
9481
  // src/miner/prompt-core.ts
9423
- function extractMinerCore(markdown) {
9424
- const start = markdown.indexOf(MINER_CORE_START);
9425
- const end = markdown.indexOf(MINER_CORE_END);
9426
- if (start === -1 || end === -1 || end <= start) {
9427
- throw new Error(`miner-core markers not found (expected ${MINER_CORE_START} … ${MINER_CORE_END})`);
9428
- }
9429
- return markdown.slice(start + MINER_CORE_START.length, end).trim();
9430
- }
9431
- var MINER_CORE_START = "<!-- dosu:miner-core:start -->", MINER_CORE_END = "<!-- dosu:miner-core:end -->";
9432
-
9433
- // src/miner/prompt-core.generated.ts
9434
9482
  var MINER_CORE_RULES = `Rules — non-negotiable:
9435
- 1. Before writing anything, call read_knowledge with the candidate topic to check whether the
9436
- knowledge already exists. Never write a duplicate or near-duplicate.
9483
+ 1. Before writing anything, call read_knowledge with the candidate topic. If the same fact is
9484
+ already recorded, skip it — never write a duplicate or near-duplicate. If the topic exists but
9485
+ the session shows it has changed or been superseded, do write: a note stating the current state
9486
+ and what changed. Only restatements of already-recorded facts are duplicates; an update to an
9487
+ existing topic is not.
9437
9488
  2. Write ONLY durable, non-obvious knowledge:
9438
9489
  - decisions and their rationale (chose A over B because ...)
9439
9490
  - non-obvious constraints (API, schema, RLS, feature flags, deploy quirks)
@@ -9461,43 +9512,6 @@ verified, omit both.
9461
9512
  long verbatim transcript spans. Summarize in your own words.
9462
9513
  9. A trivial session with no real user query is normal: skip it silently.`;
9463
9514
 
9464
- // src/miner/prompt-source.ts
9465
- import { readFileSync as readFileSync15 } from "node:fs";
9466
- import { homedir as homedir5 } from "node:os";
9467
- import { join as join14 } from "node:path";
9468
- function candidateSkillPromptPaths(env = process.env) {
9469
- const paths = [];
9470
- if (env.DOSU_SKILL_REPO?.trim()) {
9471
- paths.push(join14(env.DOSU_SKILL_REPO.trim(), "skills", SKILL_PROMPT_RELPATH));
9472
- }
9473
- paths.push(join14(homedir5(), ".agents", "skills", SKILL_PROMPT_RELPATH));
9474
- const claudeConfigDir = env.CLAUDE_CONFIG_DIR?.trim() || join14(homedir5(), ".claude");
9475
- paths.push(join14(claudeConfigDir, "skills", SKILL_PROMPT_RELPATH));
9476
- paths.push(join14(homedir5(), ".codeium", "windsurf", "skills", SKILL_PROMPT_RELPATH));
9477
- return paths;
9478
- }
9479
- function resolveMinerCoreRules(env = process.env) {
9480
- for (const path3 of candidateSkillPromptPaths(env)) {
9481
- let markdown;
9482
- try {
9483
- markdown = readFileSync15(path3, "utf-8");
9484
- } catch {
9485
- continue;
9486
- }
9487
- try {
9488
- return { rules: extractMinerCore(markdown), source: path3 };
9489
- } catch (err) {
9490
- logger.debug("miner", `skipping unusable skill rules at ${path3}: ${err}`);
9491
- }
9492
- }
9493
- return { rules: MINER_CORE_RULES, source: "bundled" };
9494
- }
9495
- var SKILL_PROMPT_RELPATH;
9496
- var init_prompt_source = __esm(() => {
9497
- init_logger();
9498
- SKILL_PROMPT_RELPATH = join14("log-to-dosu-knowledge", "references", "miner-system-prompt.md");
9499
- });
9500
-
9501
9515
  // node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
9502
9516
  var exports_sdk = {};
9503
9517
  __export(exports_sdk, {
@@ -71410,13 +71424,11 @@ async function runMiner(options) {
71410
71424
  cliVersion: getVersionString(),
71411
71425
  deploymentID: options.deploymentID
71412
71426
  });
71413
- const coreRules = resolveMinerCoreRules();
71414
- logger.debug("miner", `write-knowledge rules source: ${coreRules.source}`);
71415
71427
  try {
71416
71428
  const run2 = query({
71417
71429
  prompt: buildMinerPrompt(options.sessions),
71418
71430
  options: {
71419
- systemPrompt: buildMinerSystemPrompt(coreRules.rules),
71431
+ systemPrompt: buildMinerSystemPrompt(MINER_CORE_RULES),
71420
71432
  env,
71421
71433
  abortController: abort,
71422
71434
  maxTurns: options.maxTurns ?? DEFAULT_MAX_TURNS,
@@ -71517,7 +71529,6 @@ var init_runner = __esm(() => {
71517
71529
  init_conflicts();
71518
71530
  init_env();
71519
71531
  init_executable();
71520
- init_prompt_source();
71521
71532
  init_tools();
71522
71533
  DEFAULT_TIMEOUT_MS2 = 30 * 60 * 1000;
71523
71534
  GATEWAY_ERRORS = {
@@ -71537,17 +71548,17 @@ var init_runner = __esm(() => {
71537
71548
  });
71538
71549
 
71539
71550
  // src/version/skill-update-check.ts
71540
- import { existsSync as existsSync17, mkdirSync as mkdirSync9, readFileSync as readFileSync18, writeFileSync as writeFileSync10 } from "node:fs";
71541
- import { join as join20 } from "node:path";
71551
+ import { existsSync as existsSync17, mkdirSync as mkdirSync9, readFileSync as readFileSync17, writeFileSync as writeFileSync10 } from "node:fs";
71552
+ import { join as join19 } from "node:path";
71542
71553
  function getCachePath2() {
71543
- return join20(getConfigDir(), CACHE_FILENAME3);
71554
+ return join19(getConfigDir(), CACHE_FILENAME3);
71544
71555
  }
71545
71556
  function readSkillCache() {
71546
71557
  try {
71547
71558
  const path3 = getCachePath2();
71548
71559
  if (!existsSync17(path3))
71549
71560
  return null;
71550
- const data = JSON.parse(readFileSync18(path3, "utf-8"));
71561
+ const data = JSON.parse(readFileSync17(path3, "utf-8"));
71551
71562
  if (typeof data.lastCheck === "number" && typeof data.latestSha === "string" && typeof data.installedSha === "string") {
71552
71563
  return data;
71553
71564
  }
@@ -71635,8 +71646,8 @@ var init_skill_update_check = __esm(() => {
71635
71646
 
71636
71647
  // src/commands/skill.ts
71637
71648
  import { exec as exec2, execSync as execSync2 } from "node:child_process";
71638
- import { homedir as homedir7 } from "node:os";
71639
- import { join as join21 } from "node:path";
71649
+ import { homedir as homedir6 } from "node:os";
71650
+ import { join as join20 } from "node:path";
71640
71651
  function skillAgentIDsForProviders(providerIDs) {
71641
71652
  return [
71642
71653
  ...new Set(providerIDs.map((providerID) => SKILL_AGENT_BY_PROVIDER[providerID]).filter((agent) => Boolean(agent)))
@@ -71647,17 +71658,17 @@ function skillInstallTargetForProvider(providerID) {
71647
71658
  if (!agentID)
71648
71659
  return null;
71649
71660
  if (agentID === "claude-code") {
71650
- const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join21(homedir7(), ".claude");
71651
- return { path: join21(claudeConfigDir, "skills", SKILL_NAME), symlink: true };
71661
+ const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join20(homedir6(), ".claude");
71662
+ return { path: join20(claudeConfigDir, "skills", SKILL_NAME), symlink: true };
71652
71663
  }
71653
71664
  if (agentID === "windsurf") {
71654
71665
  return {
71655
- path: join21(homedir7(), ".codeium", "windsurf", "skills", SKILL_NAME),
71666
+ path: join20(homedir6(), ".codeium", "windsurf", "skills", SKILL_NAME),
71656
71667
  symlink: true
71657
71668
  };
71658
71669
  }
71659
71670
  return {
71660
- path: join21(homedir7(), ".agents", "skills", SKILL_NAME),
71671
+ path: join20(homedir6(), ".agents", "skills", SKILL_NAME),
71661
71672
  symlink: false
71662
71673
  };
71663
71674
  }
@@ -71819,14 +71830,14 @@ import {
71819
71830
  existsSync as existsSync18,
71820
71831
  lstatSync as lstatSync2,
71821
71832
  mkdirSync as mkdirSync10,
71822
- readFileSync as readFileSync19,
71833
+ readFileSync as readFileSync18,
71823
71834
  renameSync as renameSync5,
71824
71835
  unlinkSync as unlinkSync3,
71825
71836
  writeFileSync as writeFileSync11
71826
71837
  } from "node:fs";
71827
- import { join as join22 } from "node:path";
71838
+ import { join as join21 } from "node:path";
71828
71839
  function getTelemetrySettingsPath() {
71829
- return join22(getConfigDir(), TELEMETRY_SETTINGS_FILENAME);
71840
+ return join21(getConfigDir(), TELEMETRY_SETTINGS_FILENAME);
71830
71841
  }
71831
71842
  function loadTelemetrySettings() {
71832
71843
  return readTelemetrySettings().settings;
@@ -71894,7 +71905,7 @@ function readTelemetrySettings() {
71894
71905
  }
71895
71906
  let content;
71896
71907
  try {
71897
- content = readFileSync19(path3, "utf-8");
71908
+ content = readFileSync18(path3, "utf-8");
71898
71909
  } catch {
71899
71910
  return { status: "error", settings: disabledTelemetrySettings() };
71900
71911
  }
@@ -71972,7 +71983,7 @@ var init_settings = __esm(() => {
71972
71983
  });
71973
71984
 
71974
71985
  // src/telemetry/debug-id.ts
71975
- var BUNDLE_DEBUG_ID_PLACEHOLDER = "49488d75-f9b7-7b0e-6475-6e2164756e21";
71986
+ var BUNDLE_DEBUG_ID_PLACEHOLDER = "858ed0b9-5f8c-23ca-6475-6e2164756e21";
71976
71987
 
71977
71988
  // src/telemetry/telemetry.ts
71978
71989
  import { randomUUID as randomUUID4 } from "node:crypto";
@@ -72840,7 +72851,7 @@ var init_antigravity = __esm(() => {
72840
72851
  });
72841
72852
 
72842
72853
  // src/mcp/providers/claude.ts
72843
- import { join as join23 } from "node:path";
72854
+ import { join as join22 } from "node:path";
72844
72855
  var ClaudeProvider = () => createJSONProvider({
72845
72856
  providerName: "Claude Code",
72846
72857
  providerID: "claude",
@@ -72849,24 +72860,24 @@ var ClaudeProvider = () => createJSONProvider({
72849
72860
  paths: ["~/.claude"],
72850
72861
  globalPath: "~/.claude.json",
72851
72862
  topKey: "mcpServers",
72852
- localConfigPath: (cwd) => join23(cwd, ".mcp.json")
72863
+ localConfigPath: (cwd) => join22(cwd, ".mcp.json")
72853
72864
  });
72854
72865
  var init_claude = __esm(() => {
72855
72866
  init_base();
72856
72867
  });
72857
72868
 
72858
72869
  // src/mcp/providers/claude-desktop.ts
72859
- import { join as join24 } from "node:path";
72870
+ import { join as join23 } from "node:path";
72860
72871
  function configPath() {
72861
- return join24(appSupportDir(), "Claude", "claude_desktop_config.json");
72872
+ return join23(appSupportDir(), "Claude", "claude_desktop_config.json");
72862
72873
  }
72863
72874
  var ClaudeDesktopProvider = () => ({
72864
72875
  name: () => "Claude Desktop",
72865
72876
  id: () => "claude-desktop",
72866
72877
  supportsLocal: () => false,
72867
72878
  priority: () => 2,
72868
- detectPaths: () => [join24(appSupportDir(), "Claude")],
72869
- isInstalled: () => isInstalled([join24(appSupportDir(), "Claude")]),
72879
+ detectPaths: () => [join23(appSupportDir(), "Claude")],
72880
+ isInstalled: () => isInstalled([join23(appSupportDir(), "Claude")]),
72870
72881
  globalConfigPath: () => configPath(),
72871
72882
  isConfigured: () => isJSONKeyConfigured(configPath(), "mcpServers"),
72872
72883
  install(cfg, global2) {
@@ -72896,14 +72907,14 @@ var init_claude_desktop = __esm(() => {
72896
72907
  });
72897
72908
 
72898
72909
  // src/mcp/providers/cline.ts
72899
- import { join as join25 } from "node:path";
72900
- var extensionDir = () => join25(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
72910
+ import { join as join24 } from "node:path";
72911
+ var extensionDir = () => join24(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
72901
72912
  providerName: "Cline",
72902
72913
  providerID: "cline",
72903
72914
  local: false,
72904
72915
  priorityValue: 11,
72905
72916
  paths: [extensionDir()],
72906
- globalPath: join25(extensionDir(), "settings", "cline_mcp_settings.json"),
72917
+ globalPath: join24(extensionDir(), "settings", "cline_mcp_settings.json"),
72907
72918
  topKey: "mcpServers",
72908
72919
  buildServer: (cfg) => ({
72909
72920
  url: mcpURL(cfg.active_account.target.deployment_id),
@@ -72919,7 +72930,7 @@ var init_cline = __esm(() => {
72919
72930
  });
72920
72931
 
72921
72932
  // src/mcp/providers/cline-cli.ts
72922
- import { join as join26 } from "node:path";
72933
+ import { join as join25 } from "node:path";
72923
72934
  function clineDir() {
72924
72935
  return process.env.CLINE_DIR ?? expandHome("~/.cline");
72925
72936
  }
@@ -72929,7 +72940,7 @@ var ClineCliProvider = () => createJSONProvider({
72929
72940
  local: false,
72930
72941
  priorityValue: 12,
72931
72942
  paths: [clineDir()],
72932
- globalPath: join26(clineDir(), "data", "settings", "cline_mcp_settings.json"),
72943
+ globalPath: join25(clineDir(), "data", "settings", "cline_mcp_settings.json"),
72933
72944
  topKey: "mcpServers",
72934
72945
  buildServer: (cfg) => ({
72935
72946
  url: mcpURL(cfg.active_account.target.deployment_id),
@@ -72945,20 +72956,20 @@ var init_cline_cli = __esm(() => {
72945
72956
  });
72946
72957
 
72947
72958
  // src/mcp/providers/codex.ts
72948
- import { existsSync as existsSync20, readFileSync as readFileSync20 } from "node:fs";
72949
- import { join as join27 } from "node:path";
72959
+ import { existsSync as existsSync20, readFileSync as readFileSync19 } from "node:fs";
72960
+ import { join as join26 } from "node:path";
72950
72961
  function codexHome2() {
72951
72962
  return process.env.CODEX_HOME ?? expandHome("~/.codex");
72952
72963
  }
72953
72964
  function getConfigPath2(global2) {
72954
72965
  if (global2)
72955
- return join27(codexHome2(), "config.toml");
72956
- return join27(process.cwd(), ".codex", "config.toml");
72966
+ return join26(codexHome2(), "config.toml");
72967
+ return join26(process.cwd(), ".codex", "config.toml");
72957
72968
  }
72958
72969
  function readTOML(path3) {
72959
72970
  if (!existsSync20(path3))
72960
72971
  return "";
72961
- return readFileSync20(path3, "utf-8");
72972
+ return readFileSync19(path3, "utf-8");
72962
72973
  }
72963
72974
  function writeTOML(path3, content) {
72964
72975
  writeSecureFile(path3, content);
@@ -73021,9 +73032,9 @@ var CodexProvider = () => ({
73021
73032
  priority: () => 8,
73022
73033
  detectPaths: () => ["~/.codex"],
73023
73034
  isInstalled: () => isInstalled(["~/.codex"]),
73024
- globalConfigPath: () => join27(codexHome2(), "config.toml"),
73035
+ globalConfigPath: () => join26(codexHome2(), "config.toml"),
73025
73036
  isConfigured: () => {
73026
- const content = readTOML(join27(codexHome2(), "config.toml"));
73037
+ const content = readTOML(join26(codexHome2(), "config.toml"));
73027
73038
  return content.includes("[mcp_servers.dosu]");
73028
73039
  },
73029
73040
  install(cfg, global2) {
@@ -73045,10 +73056,10 @@ var init_codex = __esm(() => {
73045
73056
  });
73046
73057
 
73047
73058
  // src/mcp/providers/copilot.ts
73048
- import { join as join28 } from "node:path";
73059
+ import { join as join27 } from "node:path";
73049
73060
  function globalPath() {
73050
73061
  if (process.env.XDG_CONFIG_HOME) {
73051
- return join28(process.env.XDG_CONFIG_HOME, "mcp-config.json");
73062
+ return join27(process.env.XDG_CONFIG_HOME, "mcp-config.json");
73052
73063
  }
73053
73064
  return expandHome("~/.copilot/mcp-config.json");
73054
73065
  }
@@ -73079,7 +73090,7 @@ var CopilotProvider = () => ({
73079
73090
  };
73080
73091
  installJSONServer(globalPath(), "mcpServers", server);
73081
73092
  } else {
73082
- const configPath2 = join28(process.cwd(), ".vscode", "mcp.json");
73093
+ const configPath2 = join27(process.cwd(), ".vscode", "mcp.json");
73083
73094
  const server = {
73084
73095
  type: "http",
73085
73096
  url: url2,
@@ -73092,7 +73103,7 @@ var CopilotProvider = () => ({
73092
73103
  if (global2) {
73093
73104
  removeJSONServer(globalPath(), "mcpServers");
73094
73105
  } else {
73095
- const configPath2 = join28(process.cwd(), ".vscode", "mcp.json");
73106
+ const configPath2 = join27(process.cwd(), ".vscode", "mcp.json");
73096
73107
  removeJSONServer(configPath2, "servers");
73097
73108
  }
73098
73109
  }
@@ -73104,7 +73115,7 @@ var init_copilot = __esm(() => {
73104
73115
  });
73105
73116
 
73106
73117
  // src/mcp/providers/cursor.ts
73107
- import { join as join29 } from "node:path";
73118
+ import { join as join28 } from "node:path";
73108
73119
  var CursorProvider = () => createJSONProvider({
73109
73120
  providerName: "Cursor",
73110
73121
  providerID: "cursor",
@@ -73117,7 +73128,7 @@ var CursorProvider = () => createJSONProvider({
73117
73128
  url: mcpURL(cfg.active_account.target.deployment_id),
73118
73129
  headers: mcpHeaders(cfg.active_account.target.api_key)
73119
73130
  }),
73120
- localConfigPath: (cwd) => join29(cwd, ".cursor", "mcp.json")
73131
+ localConfigPath: (cwd) => join28(cwd, ".cursor", "mcp.json")
73121
73132
  });
73122
73133
  var init_cursor = __esm(() => {
73123
73134
  init_config_helpers();
@@ -73125,7 +73136,7 @@ var init_cursor = __esm(() => {
73125
73136
  });
73126
73137
 
73127
73138
  // src/mcp/providers/factory.ts
73128
- import { join as join30 } from "node:path";
73139
+ import { join as join29 } from "node:path";
73129
73140
  var FactoryProvider = () => createJSONProvider({
73130
73141
  providerName: "Factory",
73131
73142
  providerID: "factory",
@@ -73134,14 +73145,14 @@ var FactoryProvider = () => createJSONProvider({
73134
73145
  paths: ["~/.factory"],
73135
73146
  globalPath: "~/.factory/mcp.json",
73136
73147
  topKey: "mcpServers",
73137
- localConfigPath: (cwd) => join30(cwd, ".factory", "mcp.json")
73148
+ localConfigPath: (cwd) => join29(cwd, ".factory", "mcp.json")
73138
73149
  });
73139
73150
  var init_factory = __esm(() => {
73140
73151
  init_base();
73141
73152
  });
73142
73153
 
73143
73154
  // src/mcp/providers/gemini.ts
73144
- import { join as join31 } from "node:path";
73155
+ import { join as join30 } from "node:path";
73145
73156
  var GeminiProvider = () => createJSONProvider({
73146
73157
  providerName: "Gemini CLI",
73147
73158
  providerID: "gemini",
@@ -73150,7 +73161,7 @@ var GeminiProvider = () => createJSONProvider({
73150
73161
  paths: ["~/.gemini"],
73151
73162
  globalPath: "~/.gemini/settings.json",
73152
73163
  topKey: "mcpServers",
73153
- localConfigPath: (cwd) => join31(cwd, ".gemini", "settings.json")
73164
+ localConfigPath: (cwd) => join30(cwd, ".gemini", "settings.json")
73154
73165
  });
73155
73166
  var init_gemini = __esm(() => {
73156
73167
  init_base();
@@ -73201,7 +73212,7 @@ var init_manual = __esm(() => {
73201
73212
 
73202
73213
  // src/mcp/providers/mcporter.ts
73203
73214
  import { existsSync as existsSync21 } from "node:fs";
73204
- import { join as join32 } from "node:path";
73215
+ import { join as join31 } from "node:path";
73205
73216
  function resolveGlobalConfigPath() {
73206
73217
  const jsonPath = expandHome("~/.mcporter/mcporter.json");
73207
73218
  if (existsSync21(jsonPath))
@@ -73228,7 +73239,7 @@ var MCPorterProvider = () => ({
73228
73239
  globalConfigPath: () => resolveGlobalConfigPath(),
73229
73240
  isConfigured: () => isJSONKeyConfigured(resolveGlobalConfigPath(), "mcpServers"),
73230
73241
  install(cfg, global2) {
73231
- const configPath2 = global2 ? resolveGlobalConfigPath() : join32(process.cwd(), "config", "mcporter.json");
73242
+ const configPath2 = global2 ? resolveGlobalConfigPath() : join31(process.cwd(), "config", "mcporter.json");
73232
73243
  const server = {
73233
73244
  type: "http",
73234
73245
  url: mcpEndpoint4(cfg),
@@ -73237,7 +73248,7 @@ var MCPorterProvider = () => ({
73237
73248
  installJSONServer(configPath2, "mcpServers", server);
73238
73249
  },
73239
73250
  remove(global2) {
73240
- const configPath2 = global2 ? resolveGlobalConfigPath() : join32(process.cwd(), "config", "mcporter.json");
73251
+ const configPath2 = global2 ? resolveGlobalConfigPath() : join31(process.cwd(), "config", "mcporter.json");
73241
73252
  removeJSONServer(configPath2, "mcpServers");
73242
73253
  }
73243
73254
  });
@@ -73248,7 +73259,7 @@ var init_mcporter = __esm(() => {
73248
73259
  });
73249
73260
 
73250
73261
  // src/mcp/providers/opencode.ts
73251
- import { join as join33 } from "node:path";
73262
+ import { join as join32 } from "node:path";
73252
73263
  var OpenCodeProvider = () => createJSONProvider({
73253
73264
  providerName: "OpenCode",
73254
73265
  providerID: "opencode",
@@ -73263,7 +73274,7 @@ var OpenCodeProvider = () => createJSONProvider({
73263
73274
  enabled: true,
73264
73275
  headers: mcpHeaders(cfg.active_account.target.api_key)
73265
73276
  }),
73266
- localConfigPath: (cwd) => join33(cwd, "opencode.json")
73277
+ localConfigPath: (cwd) => join32(cwd, "opencode.json")
73267
73278
  });
73268
73279
  var init_opencode = __esm(() => {
73269
73280
  init_config_helpers();
@@ -73271,16 +73282,16 @@ var init_opencode = __esm(() => {
73271
73282
  });
73272
73283
 
73273
73284
  // src/mcp/providers/vscode.ts
73274
- import { join as join34 } from "node:path";
73285
+ import { join as join33 } from "node:path";
73275
73286
  var VSCodeProvider = () => createJSONProvider({
73276
73287
  providerName: "VS Code",
73277
73288
  providerID: "vscode",
73278
73289
  local: true,
73279
73290
  priorityValue: 6,
73280
- paths: [join34(appSupportDir(), "Code")],
73281
- globalPath: join34(appSupportDir(), "Code", "User", "mcp.json"),
73291
+ paths: [join33(appSupportDir(), "Code")],
73292
+ globalPath: join33(appSupportDir(), "Code", "User", "mcp.json"),
73282
73293
  topKey: "servers",
73283
- localConfigPath: (cwd) => join34(cwd, ".vscode", "mcp.json")
73294
+ localConfigPath: (cwd) => join33(cwd, ".vscode", "mcp.json")
73284
73295
  });
73285
73296
  var init_vscode = __esm(() => {
73286
73297
  init_detect();
@@ -73288,15 +73299,15 @@ var init_vscode = __esm(() => {
73288
73299
  });
73289
73300
 
73290
73301
  // src/mcp/providers/windsurf.ts
73291
- import { homedir as homedir9 } from "node:os";
73292
- import { join as join35 } from "node:path";
73302
+ import { homedir as homedir8 } from "node:os";
73303
+ import { join as join34 } from "node:path";
73293
73304
  var WindsurfProvider = () => createJSONProvider({
73294
73305
  providerName: "Windsurf",
73295
73306
  providerID: "windsurf",
73296
73307
  local: false,
73297
73308
  priorityValue: 9,
73298
- paths: [join35(homedir9(), ".codeium", "windsurf")],
73299
- globalPath: join35(homedir9(), ".codeium", "windsurf", "mcp_config.json"),
73309
+ paths: [join34(homedir8(), ".codeium", "windsurf")],
73310
+ globalPath: join34(homedir8(), ".codeium", "windsurf", "mcp_config.json"),
73300
73311
  topKey: "mcpServers"
73301
73312
  });
73302
73313
  var init_windsurf = __esm(() => {
@@ -73305,12 +73316,12 @@ var init_windsurf = __esm(() => {
73305
73316
 
73306
73317
  // src/mcp/providers/zed.ts
73307
73318
  import { platform as platform3 } from "node:os";
73308
- import { join as join36 } from "node:path";
73319
+ import { join as join35 } from "node:path";
73309
73320
  function zedConfigDir() {
73310
73321
  const os3 = platform3();
73311
73322
  if (os3 === "darwin" || os3 === "win32")
73312
- return join36(appSupportDir(), "Zed");
73313
- return join36(appSupportDir(), "zed");
73323
+ return join35(appSupportDir(), "Zed");
73324
+ return join35(appSupportDir(), "zed");
73314
73325
  }
73315
73326
  var ZedProvider = () => createJSONProvider({
73316
73327
  providerName: "Zed",
@@ -73318,7 +73329,7 @@ var ZedProvider = () => createJSONProvider({
73318
73329
  local: true,
73319
73330
  priorityValue: 10,
73320
73331
  paths: [zedConfigDir()],
73321
- globalPath: join36(zedConfigDir(), "settings.json"),
73332
+ globalPath: join35(zedConfigDir(), "settings.json"),
73322
73333
  topKey: "context_servers",
73323
73334
  buildServer: (cfg) => ({
73324
73335
  source: "custom",
@@ -73326,7 +73337,7 @@ var ZedProvider = () => createJSONProvider({
73326
73337
  url: mcpURL(cfg.active_account.target.deployment_id),
73327
73338
  headers: mcpHeaders(cfg.active_account.target.api_key)
73328
73339
  }),
73329
- localConfigPath: (cwd) => join36(cwd, ".zed", "settings.json")
73340
+ localConfigPath: (cwd) => join35(cwd, ".zed", "settings.json")
73330
73341
  });
73331
73342
  var init_zed = __esm(() => {
73332
73343
  init_config_helpers();
@@ -73385,8 +73396,8 @@ var init_providers = __esm(() => {
73385
73396
  });
73386
73397
 
73387
73398
  // src/version/update-check.ts
73388
- import { existsSync as existsSync22, mkdirSync as mkdirSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync12 } from "node:fs";
73389
- import { join as join37 } from "node:path";
73399
+ import { existsSync as existsSync22, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "node:fs";
73400
+ import { join as join36 } from "node:path";
73390
73401
  function isValidVersion(value) {
73391
73402
  return typeof value === "string" && SEMVER_PATTERN.test(value);
73392
73403
  }
@@ -73408,14 +73419,14 @@ function isNewerVersion(latest, current) {
73408
73419
  return false;
73409
73420
  }
73410
73421
  function getCachePath3() {
73411
- return join37(getConfigDir(), CACHE_FILENAME4);
73422
+ return join36(getConfigDir(), CACHE_FILENAME4);
73412
73423
  }
73413
73424
  function readCache() {
73414
73425
  try {
73415
73426
  const path3 = getCachePath3();
73416
73427
  if (!existsSync22(path3))
73417
73428
  return null;
73418
- const data = JSON.parse(readFileSync21(path3, "utf-8"));
73429
+ const data = JSON.parse(readFileSync20(path3, "utf-8"));
73419
73430
  if (typeof data.lastCheck === "number" && isValidVersion(data.latestVersion)) {
73420
73431
  return data;
73421
73432
  }
@@ -73540,14 +73551,14 @@ var init_update_check = __esm(() => {
73540
73551
  });
73541
73552
 
73542
73553
  // src/rules/installer.ts
73543
- import { existsSync as existsSync23, mkdirSync as mkdirSync12, readFileSync as readFileSync22, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "node:fs";
73544
- import { homedir as homedir10 } from "node:os";
73545
- import { dirname as dirname8, join as join38 } from "node:path";
73554
+ import { existsSync as existsSync23, mkdirSync as mkdirSync12, readFileSync as readFileSync21, unlinkSync as unlinkSync4, writeFileSync as writeFileSync13 } from "node:fs";
73555
+ import { homedir as homedir9 } from "node:os";
73556
+ import { dirname as dirname8, join as join37 } from "node:path";
73546
73557
  function claudeConfigDir() {
73547
- return process.env.CLAUDE_CONFIG_DIR || join38(homedir10(), ".claude");
73558
+ return process.env.CLAUDE_CONFIG_DIR || join37(homedir9(), ".claude");
73548
73559
  }
73549
73560
  function codexHome3() {
73550
- return process.env.CODEX_HOME || join38(homedir10(), ".codex");
73561
+ return process.env.CODEX_HOME || join37(homedir9(), ".codex");
73551
73562
  }
73552
73563
  function isRuleAgent(agent) {
73553
73564
  return Object.hasOwn(RULE_TARGETS, agent);
@@ -73581,7 +73592,7 @@ function writeIfChanged(path3, content) {
73581
73592
  writeFileSync13(path3, content, "utf-8");
73582
73593
  return "created";
73583
73594
  }
73584
- if (readFileSync22(path3, "utf-8") === content)
73595
+ if (readFileSync21(path3, "utf-8") === content)
73585
73596
  return "unchanged";
73586
73597
  writeFileSync13(path3, content, "utf-8");
73587
73598
  return "updated";
@@ -73616,7 +73627,7 @@ function upsertSection(path3, content) {
73616
73627
  `, "utf-8");
73617
73628
  return "created";
73618
73629
  }
73619
- const existing = readFileSync22(path3, "utf-8");
73630
+ const existing = readFileSync21(path3, "utf-8");
73620
73631
  const lineEnding = lineEndingFor(existing);
73621
73632
  const section = buildSection(content, lineEnding);
73622
73633
  const location = findSection(existing);
@@ -73652,7 +73663,7 @@ function removeRuleForAgent(agent) {
73652
73663
  unlinkSync4(path3);
73653
73664
  return { agent, path: path3, action: "removed" };
73654
73665
  }
73655
- const existing = readFileSync22(path3, "utf-8");
73666
+ const existing = readFileSync21(path3, "utf-8");
73656
73667
  const lineEnding = lineEndingFor(existing);
73657
73668
  const location = findSection(existing);
73658
73669
  if (!location)
@@ -73689,36 +73700,36 @@ var init_installer = __esm(() => {
73689
73700
  RULE_TARGETS = {
73690
73701
  claude: {
73691
73702
  kind: "file",
73692
- path: () => join38(claudeConfigDir(), "rules", "dosu.md")
73703
+ path: () => join37(claudeConfigDir(), "rules", "dosu.md")
73693
73704
  },
73694
73705
  cursor: {
73695
73706
  kind: "file",
73696
- path: () => join38(homedir10(), ".cursor", "rules", "dosu.mdc"),
73707
+ path: () => join37(homedir9(), ".cursor", "rules", "dosu.mdc"),
73697
73708
  cursorFrontmatter: true
73698
73709
  },
73699
73710
  codex: {
73700
73711
  kind: "section",
73701
- path: () => join38(codexHome3(), "AGENTS.md")
73712
+ path: () => join37(codexHome3(), "AGENTS.md")
73702
73713
  },
73703
73714
  opencode: {
73704
73715
  kind: "section",
73705
- path: () => join38(homedir10(), ".config", "opencode", "AGENTS.md")
73716
+ path: () => join37(homedir9(), ".config", "opencode", "AGENTS.md")
73706
73717
  },
73707
73718
  gemini: {
73708
73719
  kind: "section",
73709
- path: () => join38(homedir10(), ".gemini", "GEMINI.md")
73720
+ path: () => join37(homedir9(), ".gemini", "GEMINI.md")
73710
73721
  },
73711
73722
  antigravity: {
73712
73723
  kind: "section",
73713
- path: () => join38(homedir10(), ".gemini", "GEMINI.md")
73724
+ path: () => join37(homedir9(), ".gemini", "GEMINI.md")
73714
73725
  }
73715
73726
  };
73716
73727
  });
73717
73728
 
73718
73729
  // src/setup/agents-md-step.ts
73719
73730
  import { execSync as execSync3 } from "node:child_process";
73720
- import { existsSync as existsSync24, readFileSync as readFileSync23, writeFileSync as writeFileSync14 } from "node:fs";
73721
- import { join as join39 } from "node:path";
73731
+ import { existsSync as existsSync24, readFileSync as readFileSync22, writeFileSync as writeFileSync14 } from "node:fs";
73732
+ import { join as join38 } from "node:path";
73722
73733
  function inGitWorkTree(cwd = process.cwd()) {
73723
73734
  try {
73724
73735
  const stdout2 = execSync3("git rev-parse --is-inside-work-tree", {
@@ -73732,10 +73743,10 @@ function inGitWorkTree(cwd = process.cwd()) {
73732
73743
  }
73733
73744
  function dosuAgentsSectionState(cwd = process.cwd()) {
73734
73745
  try {
73735
- const path3 = join39(cwd, "AGENTS.md");
73746
+ const path3 = join38(cwd, "AGENTS.md");
73736
73747
  if (!existsSync24(path3))
73737
73748
  return "missing";
73738
- const content = readFileSync23(path3, "utf-8");
73749
+ const content = readFileSync22(path3, "utf-8");
73739
73750
  const startMatch = content.match(SECTION_START_RE);
73740
73751
  if (!startMatch || !content.includes(DOSU_SECTION_END))
73741
73752
  return "missing";
@@ -73770,14 +73781,14 @@ function findSection2(content) {
73770
73781
  return { start, end };
73771
73782
  }
73772
73783
  function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
73773
- const path3 = join39(cwd, "AGENTS.md");
73784
+ const path3 = join38(cwd, "AGENTS.md");
73774
73785
  if (!existsSync24(path3)) {
73775
73786
  const section2 = buildDosuAgentsSection(content);
73776
73787
  writeFileSync14(path3, `${section2}
73777
73788
  `);
73778
73789
  return { path: path3, action: "created" };
73779
73790
  }
73780
- const existing = readFileSync23(path3, "utf-8");
73791
+ const existing = readFileSync22(path3, "utf-8");
73781
73792
  const lineEnding = lineEndingFor2(existing);
73782
73793
  const section = renderDosuAgentsSection(content, lineEnding);
73783
73794
  const location = findSection2(existing);
@@ -73871,7 +73882,7 @@ var init_alt_screen = __esm(() => {
73871
73882
  });
73872
73883
 
73873
73884
  // src/tui/activity-view.ts
73874
- import { readFileSync as readFileSync24 } from "node:fs";
73885
+ import { readFileSync as readFileSync23 } from "node:fs";
73875
73886
  function reduceActivityViewKey(key) {
73876
73887
  if (key === "q" || key === ESC7 || key === CTRL_C4)
73877
73888
  return "back";
@@ -73900,6 +73911,13 @@ function reduceSyncConfirmKey(key) {
73900
73911
  return "cancel";
73901
73912
  return "none";
73902
73913
  }
73914
+ function syncConfirmMode(status) {
73915
+ if (status.running)
73916
+ return "stop";
73917
+ if (status.state.paused)
73918
+ return "resume";
73919
+ return "start";
73920
+ }
73903
73921
  function formatActivityLine(line, width) {
73904
73922
  const compact = stripAnsiCodes(line).replace(/^\[(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})[^\]]*\]/, (_match, _date2, time3) => time3);
73905
73923
  if (compact.length <= width)
@@ -73928,21 +73946,6 @@ function formatQueuedRow(session) {
73928
73946
  const project = clip(session.project ?? "-", 28);
73929
73947
  return `${session.harness.padEnd(8)} ${stamp} ${project} ${clip(session.id, 24)}`;
73930
73948
  }
73931
- function defaultListBacklog() {
73932
- try {
73933
- const state = loadSyncState();
73934
- let sessions = scanAgentSessions({});
73935
- if (state.project_filter?.length) {
73936
- const resolver = createProjectDirResolver();
73937
- sessions = filterSessionsByProject(sessions, state.project_filter, resolver.resolve);
73938
- resolver.flush();
73939
- }
73940
- const gate = gateSessions(sessions, state.watermark);
73941
- return { queued: gate.ready.reverse(), open: gate.open.reverse() };
73942
- } catch {
73943
- return { queued: [], open: [] };
73944
- }
73945
- }
73946
73949
  function windowList(lines, scroll, height = ACTIVITY_VIEW_LIST_LINES) {
73947
73950
  const clamped = Math.max(0, Math.min(scroll, Math.max(0, lines.length - height)));
73948
73951
  const end = lines.length - clamped;
@@ -74001,6 +74004,9 @@ function statusLine(status) {
74001
74004
  const pid = status.pid !== undefined ? ` (pid ${status.pid})` : "";
74002
74005
  return `⛏️ ${import_picocolors30.default.bold(brand("Mining sessions..."))}${import_picocolors30.default.dim(`${pid}${since}`)}`;
74003
74006
  }
74007
+ if (status.state.paused) {
74008
+ return `${import_picocolors30.default.yellow("○")} ${import_picocolors30.default.bold("Paused")} ${import_picocolors30.default.dim("· mining stays off until you resume")}`;
74009
+ }
74004
74010
  if (status.staleLock) {
74005
74011
  return `${import_picocolors30.default.yellow("○")} ${import_picocolors30.default.bold("Not running")} ${import_picocolors30.default.dim("· a previous run exited without cleaning up")}`;
74006
74012
  }
@@ -74044,15 +74050,17 @@ function wrapLine(text, width, indent = " ") {
74044
74050
  out.push(line);
74045
74051
  return out;
74046
74052
  }
74047
- function confirmBox(queuedCount, backlog, width) {
74053
+ function confirmBox(queuedCount, backlog, width, mode = "start") {
74048
74054
  const inFlight = backlog && backlog.inFlight > 0 ? ` (+${backlog.inFlight} open, mined once ${backlog.inFlight === 1 ? "it goes" : "they go"} quiet)` : "";
74049
- const scope = queuedCount > 0 ? `${queuedCount} session${queuedCount === 1 ? "" : "s"} queued${inFlight} · runs in the background` : `queue empty${inFlight} · a run would only pick up sessions that finish from here`;
74055
+ const scope = mode === "stop" ? "the run is killed mid-batch · mining stays paused until you resume" : queuedCount > 0 ? `${queuedCount} session${queuedCount === 1 ? "" : "s"} queued${inFlight} · runs in the background` : `queue empty${inFlight} · a run would only pick up sessions that finish from here`;
74056
+ const title = mode === "stop" ? "Stop mining?" : mode === "resume" ? "Resume mining?" : "Start mining now?";
74057
+ const verb = mode === "stop" ? "stop" : mode === "resume" ? "resume" : "start";
74050
74058
  const maxInner = Math.max(20, Math.min(width, contentWidth()) - 4);
74051
74059
  const rows = [
74052
- `⛏ ${import_picocolors30.default.bold(brand("Start mining now?"))}`,
74060
+ import_picocolors30.default.bold(brand(title)),
74053
74061
  ...wrapLine(scope, maxInner, "").map((line) => import_picocolors30.default.dim(line)),
74054
74062
  "",
74055
- `${import_picocolors30.default.bold("enter")} start · ${import_picocolors30.default.bold("esc")} cancel`
74063
+ `${import_picocolors30.default.bold("enter")} ${verb} · ${import_picocolors30.default.bold("esc")} cancel`
74056
74064
  ];
74057
74065
  const inner = Math.min(maxInner, Math.max(...rows.map(visibleWidth)));
74058
74066
  const pad = (row) => row + " ".repeat(Math.max(0, inner - visibleWidth(row)));
@@ -74089,6 +74097,9 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
74089
74097
  scrollParts.push(`↑ ${above} earlier`);
74090
74098
  if (below > 0)
74091
74099
  scrollParts.push(`↓ ${below} newer`);
74100
+ if (pane.tab !== "activity" && visible.length > 0) {
74101
+ scrollParts.push(`full rows: dosu knowledge sessions --${pane.tab}`);
74102
+ }
74092
74103
  const lines = [
74093
74104
  breadcrumb(["Home", "Activity"], width),
74094
74105
  "",
@@ -74102,11 +74113,11 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
74102
74113
  ...listRows,
74103
74114
  ...scrollParts.length > 0 ? [import_picocolors30.default.dim(scrollParts.join(" · "))] : [],
74104
74115
  "",
74105
- ...pane.confirm ? centerBlock(confirmBox(queued.length, backlog, width), width) : [
74116
+ ...pane.confirm ? centerBlock(confirmBox(queued.length, backlog, width, pane.confirm), width) : [
74106
74117
  import_picocolors30.default.dim([
74107
74118
  "tab switch",
74108
74119
  "↑↓ scroll",
74109
- ...status.running ? [] : ["s sync now"],
74120
+ status.running ? "s stop" : status.state.paused ? "s resume" : "s sync now",
74110
74121
  "esc back"
74111
74122
  ].join(" · "))
74112
74123
  ]
@@ -74116,7 +74127,7 @@ function renderActivityFrame(status, activity, width, backlog = null, pane = DEF
74116
74127
  }
74117
74128
  function defaultReadLog2() {
74118
74129
  try {
74119
- return readFileSync24(logger.getLogPath(), "utf-8");
74130
+ return readFileSync23(logger.getLogPath(), "utf-8");
74120
74131
  } catch {
74121
74132
  return "";
74122
74133
  }
@@ -74130,7 +74141,9 @@ function runActivityView(io2 = {}) {
74130
74141
  const readLog = io2.readLog ?? defaultReadLog2;
74131
74142
  const createFollower = io2.createFollower ?? ((emit) => createLogFollower(logger.getLogPath(), emit));
74132
74143
  const startSync = io2.startSync ?? (() => spawnDetachedSelf(["knowledge", "sync", "--quiet", "--bootstrap"]));
74133
- const listBacklog = io2.listBacklog ?? defaultListBacklog;
74144
+ const stopSync = io2.stopSync ?? stopSyncRun;
74145
+ const setPaused = io2.setPaused ?? setSyncPaused;
74146
+ const listBacklog = io2.listBacklog ?? listSessionBacklog;
74134
74147
  const pollMs = io2.pollMs ?? ACTIVITY_VIEW_POLL_MS;
74135
74148
  const seed = readLog();
74136
74149
  let activity = appendSyncActivity([], seed);
@@ -74138,7 +74151,7 @@ function runActivityView(io2 = {}) {
74138
74151
  let runProgress = foldRunProgress(null, seed);
74139
74152
  let tab = "activity";
74140
74153
  let scroll = 0;
74141
- let confirmSync = false;
74154
+ let confirmSync = null;
74142
74155
  let status = getStatus();
74143
74156
  let sessions = listBacklog();
74144
74157
  let queuedWatermark = status.state.watermark;
@@ -74174,10 +74187,12 @@ function runActivityView(io2 = {}) {
74174
74187
  queuedWatermark = status.state.watermark;
74175
74188
  sessions = listBacklog();
74176
74189
  }
74177
- if (confirmSync && status.running)
74178
- confirmSync = false;
74190
+ if ((confirmSync === "start" || confirmSync === "resume") && status.running)
74191
+ confirmSync = null;
74192
+ if (confirmSync === "stop" && !status.running)
74193
+ confirmSync = null;
74179
74194
  const width = activityWidth(output2.columns ?? 80);
74180
- const frame = renderActivityFrame(status, activity, width, backlog, { tab, scroll, confirm: confirmSync }, sessions.queued, minedBeforeRun ?? 0, sessions.open, runProgress);
74195
+ const frame = renderActivityFrame(status, activity, width, backlog, { tab, scroll, confirm: confirmSync ?? undefined }, sessions.queued, minedBeforeRun ?? 0, sessions.open, runProgress);
74181
74196
  if (frame === lastFrame)
74182
74197
  return;
74183
74198
  lastFrame = frame;
@@ -74221,14 +74236,25 @@ ${CLEAR_BELOW}`);
74221
74236
  if (confirmSync) {
74222
74237
  const decision = reduceSyncConfirmKey(key);
74223
74238
  if (decision === "start") {
74224
- confirmSync = false;
74225
- const ok2 = startSync();
74226
- const note = ok2 ? "[sync] sync requested · starting a background run" : "[sync] could not start a background run · try `dosu knowledge sync`";
74239
+ const mode = confirmSync;
74240
+ confirmSync = null;
74241
+ let note;
74242
+ if (mode === "stop") {
74243
+ const ok2 = status.pid !== undefined && stopSync(status.pid);
74244
+ if (ok2)
74245
+ setPaused(true);
74246
+ note = ok2 ? "[sync] mining stopped · paused until you resume" : "[sync] could not stop the run · it may have just finished";
74247
+ } else {
74248
+ if (mode === "resume")
74249
+ setPaused(false);
74250
+ const ok2 = startSync();
74251
+ note = ok2 ? "[sync] sync requested · starting a background run" : "[sync] could not start a background run · try `dosu knowledge sync`";
74252
+ }
74227
74253
  activity = appendSyncActivity(activity, `[${new Date().toISOString()}] [INFO] ${note}
74228
74254
  `);
74229
74255
  draw();
74230
74256
  } else if (decision === "cancel") {
74231
- confirmSync = false;
74257
+ confirmSync = null;
74232
74258
  draw();
74233
74259
  }
74234
74260
  continue;
@@ -74239,10 +74265,8 @@ ${CLEAR_BELOW}`);
74239
74265
  return;
74240
74266
  }
74241
74267
  if (action === "sync") {
74242
- if (!status.running) {
74243
- confirmSync = true;
74244
- draw();
74245
- }
74268
+ confirmSync = syncConfirmMode(status);
74269
+ draw();
74246
74270
  } else if (action === "tab" || action === "tab-back") {
74247
74271
  tab = cycleTab(tab, action === "tab" ? 1 : -1);
74248
74272
  scroll = 0;
@@ -74270,10 +74294,10 @@ var import_picocolors30, ESC7, HIDE_CURSOR3, SHOW_CURSOR3, CTRL_C4, KEY_UP4, KEY
74270
74294
  var init_activity_view = __esm(() => {
74271
74295
  init_follow();
74272
74296
  init_logger();
74273
- init_project_dir();
74274
- init_scan();
74275
74297
  init_styles();
74298
+ init_backlog();
74276
74299
  init_detach();
74300
+ init_lock();
74277
74301
  init_status();
74278
74302
  init_watermark();
74279
74303
  init_alt_screen();
@@ -75982,18 +76006,19 @@ function projectRows(state) {
75982
76006
  const key = record2.project ?? "(unknown)";
75983
76007
  byProject.set(key, (byProject.get(key) ?? 0) + 1);
75984
76008
  }
75985
- return [...byProject.entries()].sort((a9, b2) => b2[1] - a9[1]).map(([project, count]) => `${label(clip2(project, 24))}${count}`);
76009
+ const data = [...byProject.entries()].sort((a9, b2) => b2[1] - a9[1]).map(([project, count]) => `${label(clip2(project, 24))}${count}`);
76010
+ return data.length > 0 ? [`${label("Project")}Sessions`, ...data] : [];
75986
76011
  }
75987
76012
  function pageRows(pageStats) {
75988
76013
  const rows = [];
75989
76014
  if (pageStats && pageStats.topCited.length > 0) {
75990
- rows.push(`Top cited pages (${TOP_CITED_DAYS}d)`);
76015
+ rows.push(`${label(`Top cited (${TOP_CITED_DAYS}d)`)}Citations`);
75991
76016
  for (const row of pageStats.topCited) {
75992
76017
  rows.push(`${label(clip2(row.title, 24))}${row.citation_count}`);
75993
76018
  }
75994
76019
  }
75995
76020
  if (pageStats && pageStats.topUpdated.length > 0) {
75996
- rows.push(...rows.length > 0 ? [""] : [], "Recently updated pages");
76021
+ rows.push(...rows.length > 0 ? [""] : [], `${label("Recently updated")}Updated`);
75997
76022
  for (const row of pageStats.topUpdated) {
75998
76023
  rows.push(`${label(clip2(row.title, 24))}${row.updated_at.slice(0, 10)}`);
75999
76024
  }
@@ -76033,6 +76058,7 @@ function renderAnalyticsFrame(state, tab, scroll, pageStats = null, pagesPending
76033
76058
  ["projects", "Projects"],
76034
76059
  ["pages", "Pages"]
76035
76060
  ], tab, width, { spread: false }),
76061
+ "",
76036
76062
  ...listRows,
76037
76063
  ...scrollParts.length > 0 ? [import_picocolors32.default.dim(scrollParts.join(" · "))] : [],
76038
76064
  "",
@@ -76131,7 +76157,7 @@ ${CLEAR_BELOW2}`);
76131
76157
  input2.on("data", onData);
76132
76158
  });
76133
76159
  }
76134
- var import_picocolors32, ESC8, HIDE_CURSOR4, SHOW_CURSOR4, CTRL_C5, KEY_UP5, KEY_DOWN5, KEY_RIGHT4, KEY_LEFT4, CURSOR_HOME2, CLEAR_BELOW2, CLEAR_EOL2, ANALYTICS_VIEW_POLL_MS = 1000, ANALYTICS_VIEW_LINES = 12, ANALYTICS_VIEW_TABS, TOP_PAGES_LIMIT = 5, TOP_CITED_DAYS = 30, label = (text) => text.padEnd(26);
76160
+ var import_picocolors32, ESC8, HIDE_CURSOR4, SHOW_CURSOR4, CTRL_C5, KEY_UP5, KEY_DOWN5, KEY_RIGHT4, KEY_LEFT4, CURSOR_HOME2, CLEAR_BELOW2, CLEAR_EOL2, ANALYTICS_VIEW_POLL_MS = 1000, ANALYTICS_VIEW_LINES = 14, ANALYTICS_VIEW_TABS, TOP_PAGES_LIMIT = 5, TOP_CITED_DAYS = 30, label = (text) => text.padEnd(26);
76135
76161
  var init_analytics_view = __esm(() => {
76136
76162
  init_trpc();
76137
76163
  init_config();
@@ -76586,7 +76612,7 @@ __export(exports_tui, {
76586
76612
  runTUI: () => runTUI,
76587
76613
  handleLogout: () => handleLogout
76588
76614
  });
76589
- import { homedir as homedir11 } from "node:os";
76615
+ import { homedir as homedir10 } from "node:os";
76590
76616
  import { basename as basename4 } from "node:path";
76591
76617
  function bannerContext(cfg) {
76592
76618
  let webAppHost = "app.dosu.dev";
@@ -76812,7 +76838,7 @@ async function runSettings(cfg) {
76812
76838
  }
76813
76839
  }
76814
76840
  function displayDir(dir) {
76815
- const home = homedir11();
76841
+ const home = homedir10();
76816
76842
  return dir === home ? "~" : dir.startsWith(`${home}/`) ? `~${dir.slice(home.length)}` : dir;
76817
76843
  }
76818
76844
  function discoverProjectDirs() {
@@ -77552,7 +77578,7 @@ import {
77552
77578
  constants as constants3,
77553
77579
  fstatSync,
77554
77580
  openSync as openSync5,
77555
- readFileSync as readFileSync25,
77581
+ readFileSync as readFileSync24,
77556
77582
  readSync as readSync4,
77557
77583
  unlinkSync as unlinkSync5
77558
77584
  } from "node:fs";
@@ -80682,13 +80708,15 @@ init_trpc();
80682
80708
  init_config();
80683
80709
  init_agents();
80684
80710
  init_formats();
80711
+ init_backlog();
80685
80712
  init_detach();
80686
80713
  init_status();
80687
80714
  init_sync();
80715
+ init_watermark();
80688
80716
  var import_picocolors18 = __toESM(require_picocolors(), 1);
80689
80717
  import { existsSync as existsSync16 } from "node:fs";
80690
- import { homedir as homedir6 } from "node:os";
80691
- import { delimiter as delimiter4, join as join19 } from "node:path";
80718
+ import { homedir as homedir5 } from "node:os";
80719
+ import { delimiter as delimiter4, join as join18 } from "node:path";
80692
80720
  function requireConfig7() {
80693
80721
  const cfg = requireLoginConfig();
80694
80722
  if (!cfg.active_account?.target?.org_id || !cfg.active_account?.target?.space_id) {
@@ -80751,6 +80779,50 @@ ${results.length - opts.limit} more results not shown.`));
80751
80779
  console.log(` ID: ${store.id}`);
80752
80780
  console.log(` Space ID: ${store.space_id}`);
80753
80781
  });
80782
+ cmd.command("sessions").description("List local agent sessions with full project and session ids (the untruncated view of the Activity screen's tabs)").option("--queued", "Only sessions queued for mining").option("--open", "Only live sessions still inside the quiet period").option("--mined", "Only recent mined-session history").option("--json", "Output as JSON").action((opts) => {
80783
+ const all = !opts.queued && !opts.open && !opts.mined;
80784
+ const wantQueued = all || Boolean(opts.queued);
80785
+ const wantOpen = all || Boolean(opts.open);
80786
+ const wantMined = all || Boolean(opts.mined);
80787
+ const backlog = wantQueued || wantOpen ? listSessionBacklog() : { queued: [], open: [] };
80788
+ const mined = wantMined ? loadSyncState().mined_sessions ?? [] : [];
80789
+ if (opts.json) {
80790
+ printResult({
80791
+ ...wantQueued ? { queued: backlog.queued } : {},
80792
+ ...wantOpen ? { open: backlog.open } : {},
80793
+ ...wantMined ? { mined } : {}
80794
+ }, opts);
80795
+ return;
80796
+ }
80797
+ const sessionRows = (sessions) => sessions.map((s) => [s.harness, s.updated, s.project ?? "-", s.id]);
80798
+ const minedRows = mined.map((record2) => {
80799
+ const slash = record2.session.indexOf("/");
80800
+ const harness = slash > 0 ? record2.session.slice(0, slash) : "-";
80801
+ const id2 = slash > 0 ? record2.session.slice(slash + 1) : record2.session;
80802
+ return [harness, record2.at, record2.project ?? "-", id2];
80803
+ });
80804
+ let first = true;
80805
+ const section = (title, rows, stamp, emptyMsg) => {
80806
+ if (!first)
80807
+ console.log();
80808
+ first = false;
80809
+ console.log(import_picocolors18.default.bold(`${title} (${rows.length})`));
80810
+ if (rows.length === 0) {
80811
+ console.log(import_picocolors18.default.dim(` ${emptyMsg}`));
80812
+ return;
80813
+ }
80814
+ printTable(["Agent", stamp, "Project", "Session"], rows);
80815
+ };
80816
+ if (wantQueued) {
80817
+ section("Queued", sessionRows(backlog.queued), "Updated", "Queue empty. Finished agent sessions appear here.");
80818
+ }
80819
+ if (wantOpen) {
80820
+ section("Open", sessionRows(backlog.open), "Updated", "No open sessions. Live agent sessions sit here until they go quiet.");
80821
+ }
80822
+ if (wantMined) {
80823
+ section("Mined", minedRows, "Mined at", "No mined sessions recorded yet.");
80824
+ }
80825
+ });
80754
80826
  cmd.command("sync").description("Scan local agent session history and report the mining backlog").option("--quiet", "Background mode for hooks: honor backoff, exit 0, print nothing").option("--detach", "Re-spawn detached and return immediately (used by agent hooks)").option("--bootstrap", "Backfill mode: mine the full local session history regardless of age and drain the backlog (used by setup)").option("--status", "Show whether a sync is running now, plus watermark and recent activity").option("--json", "Output as JSON").action(async (opts) => {
80755
80827
  if (opts.status) {
80756
80828
  const status = getSyncStatus();
@@ -80832,10 +80904,13 @@ function printSyncStatus(status, now = new Date) {
80832
80904
  } else {
80833
80905
  console.log("○ No sync running.");
80834
80906
  }
80907
+ if (status.state.paused) {
80908
+ console.log(import_picocolors18.default.yellow(" Mining paused: stopped by you. Resume from the Activity screen or run 'dosu knowledge sync'."));
80909
+ }
80835
80910
  const wm2 = status.state.watermark;
80836
80911
  console.log(` Mined through: ${wm2 ? `${wm2} (${formatAge(wm2, now)})` : "nothing mined yet"}`);
80837
80912
  if (status.state.project_filter?.length) {
80838
- const home = homedir6();
80913
+ const home = homedir5();
80839
80914
  const scope = status.state.project_filter.map((dir) => dir.startsWith(`${home}/`) ? `~${dir.slice(home.length)}` : dir).join(", ");
80840
80915
  console.log(` Mining scope: ${scope}`);
80841
80916
  }
@@ -80908,6 +80983,10 @@ function printSyncOutcome(outcome) {
80908
80983
  console.log(import_picocolors18.default.dim("Skipped: a recent sync failed; waiting out the retry backoff."));
80909
80984
  break;
80910
80985
  }
80986
+ case "skipped-paused": {
80987
+ console.log(import_picocolors18.default.dim("Skipped: mining is paused. Run 'dosu knowledge sync' to resume."));
80988
+ break;
80989
+ }
80911
80990
  }
80912
80991
  }
80913
80992
  function resolveHookAgents(ids) {
@@ -81003,7 +81082,7 @@ function reportHookFailure(agent, err) {
81003
81082
  }
81004
81083
  function dosuOnPath() {
81005
81084
  const bin = process.platform === "win32" ? "dosu.cmd" : "dosu";
81006
- return (process.env.PATH ?? "").split(delimiter4).some((dir) => dir !== "" && existsSync16(join19(dir, bin)));
81085
+ return (process.env.PATH ?? "").split(delimiter4).some((dir) => dir !== "" && existsSync16(join18(dir, bin)));
81007
81086
  }
81008
81087
 
81009
81088
  // src/commands/libraries.ts
@@ -81343,7 +81422,7 @@ init_dist();
81343
81422
  init_commander();
81344
81423
  init_trpc();
81345
81424
  var import_picocolors22 = __toESM(require_picocolors(), 1);
81346
- import { readFileSync as readFileSync17 } from "node:fs";
81425
+ import { readFileSync as readFileSync16 } from "node:fs";
81347
81426
  function requireConfig10() {
81348
81427
  return requireLoginConfig();
81349
81428
  }
@@ -81519,7 +81598,7 @@ function reviewCommand() {
81519
81598
  let body = opts.body;
81520
81599
  if (opts.bodyFile) {
81521
81600
  try {
81522
- body = readFileSync17(opts.bodyFile, "utf-8");
81601
+ body = readFileSync16(opts.bodyFile, "utf-8");
81523
81602
  } catch (err) {
81524
81603
  console.error(import_picocolors22.default.red(`Failed to read --body-file: ${err.message}`));
81525
81604
  process.exit(1);
@@ -82017,7 +82096,7 @@ init_skill();
82017
82096
  var import_picocolors28 = __toESM(require_picocolors(), 1);
82018
82097
  import { spawnSync } from "node:child_process";
82019
82098
  import { realpathSync as realpathSync2 } from "node:fs";
82020
- import { homedir as homedir8 } from "node:os";
82099
+ import { homedir as homedir7 } from "node:os";
82021
82100
  import { posix, win32 as win322 } from "node:path";
82022
82101
  var PACKAGE_NAME = "@dosu/cli";
82023
82102
  var LATEST_PACKAGE = `${PACKAGE_NAME}@latest`;
@@ -82094,7 +82173,7 @@ function packageRoots(manager, platform3, comSpec, env, cwd) {
82094
82173
  manager === "npm" ? path3.join(lines[0], "@dosu", "cli") : path3.join(lines[0], "node_modules", "@dosu", "cli")
82095
82174
  ];
82096
82175
  }
82097
- function owningPackageManager(entrypoint, platform3, comSpec, env = process.env, cwd = homedir8()) {
82176
+ function owningPackageManager(entrypoint, platform3, comSpec, env = process.env, cwd = homedir7()) {
82098
82177
  const path3 = platform3 === "win32" ? win322 : posix;
82099
82178
  if (!entrypoint || !path3.isAbsolute(entrypoint))
82100
82179
  return null;
@@ -82147,7 +82226,7 @@ Or install Dosu globally with your package manager:`);
82147
82226
  function runUpgrade(channel = INSTALL_CHANNEL, options = {}) {
82148
82227
  const platform3 = options.platform ?? process.platform;
82149
82228
  const env = options.env ?? process.env;
82150
- const cwd = options.cwd ?? homedir8();
82229
+ const cwd = options.cwd ?? homedir7();
82151
82230
  let manager = null;
82152
82231
  if (channel === "npm") {
82153
82232
  if (isNpxInvocation(channel, env)) {
@@ -82663,7 +82742,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
82663
82742
  }
82664
82743
  if (opts.follow) {
82665
82744
  try {
82666
- const lines = readFileSync25(logPath, "utf-8").split(`
82745
+ const lines = readFileSync24(logPath, "utf-8").split(`
82667
82746
  `);
82668
82747
  if (lines.at(-1) === "")
82669
82748
  lines.pop();
@@ -82679,7 +82758,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
82679
82758
  if (opts.tail !== undefined) {
82680
82759
  const n5 = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
82681
82760
  try {
82682
- const content = readFileSync25(logPath, "utf-8");
82761
+ const content = readFileSync24(logPath, "utf-8");
82683
82762
  const lines = content.split(`
82684
82763
  `);
82685
82764
  console.log(lines.slice(-n5).join(`
@@ -82750,4 +82829,4 @@ execute().catch((err) => {
82750
82829
  process.exit(1);
82751
82830
  });
82752
82831
 
82753
- //# debugId=49488d75-f9b7-7b0e-6475-6e2164756e21
82832
+ //# debugId=858ed0b9-5f8c-23ca-6475-6e2164756e21