@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.
- package/bin/dosu.js +537 -458
- 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.
|
|
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
|
|
8586
|
-
mkdirSync as
|
|
8352
|
+
existsSync as existsSync9,
|
|
8353
|
+
mkdirSync as mkdirSync6,
|
|
8587
8354
|
openSync as openSync2,
|
|
8588
|
-
readFileSync as
|
|
8355
|
+
readFileSync as readFileSync9,
|
|
8589
8356
|
readSync,
|
|
8590
|
-
renameSync as
|
|
8591
|
-
statSync as
|
|
8592
|
-
writeFileSync as
|
|
8357
|
+
renameSync as renameSync2,
|
|
8358
|
+
statSync as statSync3,
|
|
8359
|
+
writeFileSync as writeFileSync6
|
|
8593
8360
|
} from "node:fs";
|
|
8594
|
-
import { join as
|
|
8361
|
+
import { join as join8 } from "node:path";
|
|
8595
8362
|
function cachePath(configDir) {
|
|
8596
|
-
return
|
|
8363
|
+
return join8(configDir, CACHE_FILENAME2);
|
|
8597
8364
|
}
|
|
8598
8365
|
function loadCacheFile(configDir) {
|
|
8599
8366
|
try {
|
|
8600
|
-
const raw = JSON.parse(
|
|
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 (!
|
|
8611
|
-
|
|
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
|
-
|
|
8616
|
-
|
|
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 =
|
|
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
|
|
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 ??
|
|
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
|
|
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
|
|
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:
|
|
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 =
|
|
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(
|
|
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(
|
|
8545
|
+
for (const project of listDir(join9(home, ".cursor", "projects"))) {
|
|
8779
8546
|
if (!project.isDir)
|
|
8780
8547
|
continue;
|
|
8781
|
-
for (const entry of listDir(
|
|
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 ??
|
|
8560
|
+
const codexHome2 = env.CODEX_HOME ?? join9(home, ".codex");
|
|
8794
8561
|
const sessions = [];
|
|
8795
|
-
for (const year of listDir(
|
|
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 ??
|
|
8852
|
-
const dbPath =
|
|
8853
|
-
if (!
|
|
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
|
|
9436
|
-
|
|
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(
|
|
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
|
|
71541
|
-
import { join as
|
|
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
|
|
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(
|
|
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
|
|
71639
|
-
import { join as
|
|
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() ||
|
|
71651
|
-
return { path:
|
|
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:
|
|
71666
|
+
path: join20(homedir6(), ".codeium", "windsurf", "skills", SKILL_NAME),
|
|
71656
71667
|
symlink: true
|
|
71657
71668
|
};
|
|
71658
71669
|
}
|
|
71659
71670
|
return {
|
|
71660
|
-
path:
|
|
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
|
|
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
|
|
71838
|
+
import { join as join21 } from "node:path";
|
|
71828
71839
|
function getTelemetrySettingsPath() {
|
|
71829
|
-
return
|
|
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 =
|
|
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 = "
|
|
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
|
|
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) =>
|
|
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
|
|
72870
|
+
import { join as join23 } from "node:path";
|
|
72860
72871
|
function configPath() {
|
|
72861
|
-
return
|
|
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: () => [
|
|
72869
|
-
isInstalled: () => isInstalled([
|
|
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
|
|
72900
|
-
var extensionDir = () =>
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
72949
|
-
import { join as
|
|
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
|
|
72956
|
-
return
|
|
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
|
|
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: () =>
|
|
73035
|
+
globalConfigPath: () => join26(codexHome2(), "config.toml"),
|
|
73025
73036
|
isConfigured: () => {
|
|
73026
|
-
const content = readTOML(
|
|
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
|
|
73059
|
+
import { join as join27 } from "node:path";
|
|
73049
73060
|
function globalPath() {
|
|
73050
73061
|
if (process.env.XDG_CONFIG_HOME) {
|
|
73051
|
-
return
|
|
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 =
|
|
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 =
|
|
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
|
|
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) =>
|
|
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
|
|
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) =>
|
|
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
|
|
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) =>
|
|
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
|
|
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() :
|
|
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() :
|
|
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
|
|
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) =>
|
|
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
|
|
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: [
|
|
73281
|
-
globalPath:
|
|
73291
|
+
paths: [join33(appSupportDir(), "Code")],
|
|
73292
|
+
globalPath: join33(appSupportDir(), "Code", "User", "mcp.json"),
|
|
73282
73293
|
topKey: "servers",
|
|
73283
|
-
localConfigPath: (cwd) =>
|
|
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
|
|
73292
|
-
import { join as
|
|
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: [
|
|
73299
|
-
globalPath:
|
|
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
|
|
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
|
|
73313
|
-
return
|
|
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:
|
|
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) =>
|
|
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
|
|
73389
|
-
import { join as
|
|
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
|
|
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(
|
|
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
|
|
73544
|
-
import { homedir as
|
|
73545
|
-
import { dirname as dirname8, join as
|
|
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 ||
|
|
73558
|
+
return process.env.CLAUDE_CONFIG_DIR || join37(homedir9(), ".claude");
|
|
73548
73559
|
}
|
|
73549
73560
|
function codexHome3() {
|
|
73550
|
-
return process.env.CODEX_HOME ||
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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: () =>
|
|
73703
|
+
path: () => join37(claudeConfigDir(), "rules", "dosu.md")
|
|
73693
73704
|
},
|
|
73694
73705
|
cursor: {
|
|
73695
73706
|
kind: "file",
|
|
73696
|
-
path: () =>
|
|
73707
|
+
path: () => join37(homedir9(), ".cursor", "rules", "dosu.mdc"),
|
|
73697
73708
|
cursorFrontmatter: true
|
|
73698
73709
|
},
|
|
73699
73710
|
codex: {
|
|
73700
73711
|
kind: "section",
|
|
73701
|
-
path: () =>
|
|
73712
|
+
path: () => join37(codexHome3(), "AGENTS.md")
|
|
73702
73713
|
},
|
|
73703
73714
|
opencode: {
|
|
73704
73715
|
kind: "section",
|
|
73705
|
-
path: () =>
|
|
73716
|
+
path: () => join37(homedir9(), ".config", "opencode", "AGENTS.md")
|
|
73706
73717
|
},
|
|
73707
73718
|
gemini: {
|
|
73708
73719
|
kind: "section",
|
|
73709
|
-
path: () =>
|
|
73720
|
+
path: () => join37(homedir9(), ".gemini", "GEMINI.md")
|
|
73710
73721
|
},
|
|
73711
73722
|
antigravity: {
|
|
73712
73723
|
kind: "section",
|
|
73713
|
-
path: () =>
|
|
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
|
|
73721
|
-
import { join as
|
|
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 =
|
|
73746
|
+
const path3 = join38(cwd, "AGENTS.md");
|
|
73736
73747
|
if (!existsSync24(path3))
|
|
73737
73748
|
return "missing";
|
|
73738
|
-
const content =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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")}
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
74225
|
-
|
|
74226
|
-
|
|
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 =
|
|
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
|
-
|
|
74243
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
80691
|
-
import { delimiter as delimiter4, join as
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 ??
|
|
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 =
|
|
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 =
|
|
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=
|
|
82832
|
+
//# debugId=858ed0b9-5f8c-23ca-6475-6e2164756e21
|