@dosu/cli 0.62.1 → 0.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/bin/dosu.js +745 -414
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -1083,7 +1083,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
1083
1083
|
function getVersionString() {
|
|
1084
1084
|
return `v${VERSION}`;
|
|
1085
1085
|
}
|
|
1086
|
-
var VERSION = "0.
|
|
1086
|
+
var VERSION = "0.64.0", INSTALL_CHANNEL = "npm";
|
|
1087
1087
|
|
|
1088
1088
|
// src/debug/logger.ts
|
|
1089
1089
|
import {
|
|
@@ -1472,6 +1472,70 @@ var init_agents = __esm(() => {
|
|
|
1472
1472
|
init_formats();
|
|
1473
1473
|
});
|
|
1474
1474
|
|
|
1475
|
+
// src/sessions/repo.ts
|
|
1476
|
+
import { execFileSync } from "node:child_process";
|
|
1477
|
+
function normalizeRepoRemote(remote) {
|
|
1478
|
+
const value = remote.trim();
|
|
1479
|
+
if (!value)
|
|
1480
|
+
return null;
|
|
1481
|
+
let host;
|
|
1482
|
+
let path;
|
|
1483
|
+
const scp = value.includes("://") ? null : /^(?:[^@/]+@)?([^:/]+):(.+)$/.exec(value);
|
|
1484
|
+
if (scp) {
|
|
1485
|
+
host = scp[1];
|
|
1486
|
+
path = scp[2];
|
|
1487
|
+
} else {
|
|
1488
|
+
try {
|
|
1489
|
+
const url = new URL(value);
|
|
1490
|
+
if (url.protocol === "file:")
|
|
1491
|
+
return null;
|
|
1492
|
+
host = url.hostname;
|
|
1493
|
+
path = url.pathname;
|
|
1494
|
+
} catch {
|
|
1495
|
+
return null;
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
path = path.replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
|
|
1499
|
+
if (!host || !path.includes("/"))
|
|
1500
|
+
return null;
|
|
1501
|
+
const lowerHost = host.toLowerCase();
|
|
1502
|
+
return `${lowerHost}/${lowerHost === "github.com" ? path.toLowerCase() : path}`;
|
|
1503
|
+
}
|
|
1504
|
+
function gitOutput(dir, args, timeout) {
|
|
1505
|
+
const env = { ...process.env };
|
|
1506
|
+
for (const name of GIT_LOCATION_ENV)
|
|
1507
|
+
delete env[name];
|
|
1508
|
+
try {
|
|
1509
|
+
return execFileSync("git", ["-C", dir, ...args], {
|
|
1510
|
+
encoding: "utf-8",
|
|
1511
|
+
env,
|
|
1512
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
1513
|
+
timeout,
|
|
1514
|
+
maxBuffer: 16 * 1024 * 1024
|
|
1515
|
+
});
|
|
1516
|
+
} catch {
|
|
1517
|
+
return null;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
function originRepoOfDir(dir) {
|
|
1521
|
+
const out = gitOutput(dir, ["remote", "get-url", "origin"], 1000);
|
|
1522
|
+
return out === null ? null : normalizeRepoRemote(out);
|
|
1523
|
+
}
|
|
1524
|
+
function currentBranchOfDir(dir) {
|
|
1525
|
+
const out = gitOutput(dir, ["symbolic-ref", "--short", "-q", "HEAD"], 1000)?.trim();
|
|
1526
|
+
return out ? out : null;
|
|
1527
|
+
}
|
|
1528
|
+
function headReflogOfDir(dir) {
|
|
1529
|
+
return gitOutput(dir, ["reflog", "show", "--date=unix", "--format=%gd%x09%gs", "HEAD"], 5000);
|
|
1530
|
+
}
|
|
1531
|
+
function displayRepo(repo) {
|
|
1532
|
+
return repo.split("/").slice(1).join("/") || repo;
|
|
1533
|
+
}
|
|
1534
|
+
var GIT_LOCATION_ENV;
|
|
1535
|
+
var init_repo = __esm(() => {
|
|
1536
|
+
GIT_LOCATION_ENV = ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE"];
|
|
1537
|
+
});
|
|
1538
|
+
|
|
1475
1539
|
// src/sessions/scan.ts
|
|
1476
1540
|
import { existsSync as existsSync6, readdirSync, statSync as statSync2 } from "node:fs";
|
|
1477
1541
|
import { createRequire as createRequire2 } from "node:module";
|
|
@@ -1919,6 +1983,9 @@ import { join as join6 } from "node:path";
|
|
|
1919
1983
|
function syncStatePath(configDir = getConfigDir()) {
|
|
1920
1984
|
return join6(configDir, STATE_FILENAME);
|
|
1921
1985
|
}
|
|
1986
|
+
function stringsOf(values) {
|
|
1987
|
+
return values.filter((v) => typeof v === "string");
|
|
1988
|
+
}
|
|
1922
1989
|
function loadSyncState(configDir = getConfigDir()) {
|
|
1923
1990
|
const empty = {
|
|
1924
1991
|
schema_version: STATE_SCHEMA_VERSION,
|
|
@@ -1954,9 +2021,8 @@ function loadSyncState(configDir = getConfigDir()) {
|
|
|
1954
2021
|
...lastRefusal ? { last_refusal: lastRefusal } : {},
|
|
1955
2022
|
...run ? { run } : {},
|
|
1956
2023
|
...raw.paused === true ? { paused: true } : {},
|
|
1957
|
-
...Array.isArray(raw.
|
|
1958
|
-
|
|
1959
|
-
} : {}
|
|
2024
|
+
...Array.isArray(raw.repo_filter) ? { repo_filter: stringsOf(raw.repo_filter) } : {},
|
|
2025
|
+
...Array.isArray(raw.project_filter) ? { project_filter: stringsOf(raw.project_filter) } : {}
|
|
1960
2026
|
};
|
|
1961
2027
|
} catch {
|
|
1962
2028
|
return empty;
|
|
@@ -1976,6 +2042,7 @@ function resetSyncState(configDir = getConfigDir()) {
|
|
|
1976
2042
|
schema_version: STATE_SCHEMA_VERSION,
|
|
1977
2043
|
watermark: null,
|
|
1978
2044
|
consecutive_failures: 0,
|
|
2045
|
+
...previous.repo_filter ? { repo_filter: previous.repo_filter } : {},
|
|
1979
2046
|
...previous.project_filter ? { project_filter: previous.project_filter } : {},
|
|
1980
2047
|
...previous.paused ? { paused: true } : {}
|
|
1981
2048
|
};
|
|
@@ -2002,17 +2069,34 @@ function isUnderDir(dir, base) {
|
|
|
2002
2069
|
const root = base.endsWith("/") ? base.slice(0, -1) : base;
|
|
2003
2070
|
return dir === root || dir.startsWith(`${root}/`);
|
|
2004
2071
|
}
|
|
2005
|
-
function
|
|
2006
|
-
if (
|
|
2007
|
-
return
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2072
|
+
function studyRepoFilter(state, listSessions, locator) {
|
|
2073
|
+
if (state.repo_filter)
|
|
2074
|
+
return state.repo_filter;
|
|
2075
|
+
const folders = state.project_filter;
|
|
2076
|
+
if (!folders?.length)
|
|
2077
|
+
return null;
|
|
2078
|
+
const repos = new Set;
|
|
2079
|
+
for (const session of listSessions()) {
|
|
2080
|
+
const dir = locator.resolve(session);
|
|
2081
|
+
if (!dir || !folders.some((base) => isUnderDir(dir, base)))
|
|
2082
|
+
continue;
|
|
2083
|
+
const repo = locator.resolveRepo(session);
|
|
2084
|
+
if (repo)
|
|
2085
|
+
repos.add(repo);
|
|
2086
|
+
}
|
|
2087
|
+
return [...repos].sort();
|
|
2088
|
+
}
|
|
2089
|
+
function filterSessionsByRepo(sessions, filter, resolveRepo) {
|
|
2090
|
+
const kept = [];
|
|
2091
|
+
for (const session of sessions) {
|
|
2092
|
+
const repo = resolveRepo(session);
|
|
2093
|
+
if (repo !== null && (filter === null || filter.includes(repo))) {
|
|
2094
|
+
kept.push({ ...session, repo });
|
|
2095
|
+
} else if (filter === null) {
|
|
2096
|
+
kept.push(session);
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
return kept;
|
|
2016
2100
|
}
|
|
2017
2101
|
function gateSessions(sessions, watermark, now = new Date, quietPeriodMs = DEFAULT_QUIET_PERIOD_MS) {
|
|
2018
2102
|
const watermarkMs = watermark ? Date.parse(watermark) : Number.NEGATIVE_INFINITY;
|
|
@@ -2031,7 +2115,7 @@ function gateSessions(sessions, watermark, now = new Date, quietPeriodMs = DEFAU
|
|
|
2031
2115
|
}
|
|
2032
2116
|
return { ready, open };
|
|
2033
2117
|
}
|
|
2034
|
-
var STATE_FILENAME = "knowledge-sync.json", STATE_SCHEMA_VERSION = 1, DEFAULT_QUIET_PERIOD_MS, BACKOFF_BASE_MS, BACKOFF_MAX_MS, STUDIED_HISTORY_LIMIT = 500
|
|
2118
|
+
var STATE_FILENAME = "knowledge-sync.json", STATE_SCHEMA_VERSION = 1, DEFAULT_QUIET_PERIOD_MS, BACKOFF_BASE_MS, BACKOFF_MAX_MS, STUDIED_HISTORY_LIMIT = 500;
|
|
2035
2119
|
var init_watermark = __esm(() => {
|
|
2036
2120
|
init_config();
|
|
2037
2121
|
DEFAULT_QUIET_PERIOD_MS = 5 * 60 * 1000;
|
|
@@ -2067,12 +2151,15 @@ function defaultHookEnabled(agentId) {
|
|
|
2067
2151
|
return false;
|
|
2068
2152
|
}
|
|
2069
2153
|
}
|
|
2070
|
-
function cwdIsStudied(cwd,
|
|
2071
|
-
if (
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2154
|
+
function cwdIsStudied(cwd, state, repoOfDir) {
|
|
2155
|
+
if (state.repo_filter) {
|
|
2156
|
+
const repo = cwd ? repoOfDir(cwd) : null;
|
|
2157
|
+
return repo !== null && state.repo_filter.includes(repo);
|
|
2158
|
+
}
|
|
2159
|
+
if (state.project_filter?.length) {
|
|
2160
|
+
return cwd !== undefined && state.project_filter.some((base) => isUnderDir(cwd, base));
|
|
2161
|
+
}
|
|
2162
|
+
return true;
|
|
2076
2163
|
}
|
|
2077
2164
|
function resolveStatuslineState(payload, agentId, deps = {}) {
|
|
2078
2165
|
const hookEnabled = deps.hookEnabled ?? defaultHookEnabled;
|
|
@@ -2085,7 +2172,7 @@ function resolveStatuslineState(payload, agentId, deps = {}) {
|
|
|
2085
2172
|
const state = (deps.loadState ?? loadSyncState)();
|
|
2086
2173
|
if (state.paused)
|
|
2087
2174
|
return "paused";
|
|
2088
|
-
if (!cwdIsStudied(payload.cwd, state.
|
|
2175
|
+
if (!cwdIsStudied(payload.cwd, state, deps.repoOfDir ?? originRepoOfDir))
|
|
2089
2176
|
return "not-studied";
|
|
2090
2177
|
return "on";
|
|
2091
2178
|
}
|
|
@@ -2099,13 +2186,14 @@ function renderStatusline(raw, agentId, deps = {}) {
|
|
|
2099
2186
|
var STATUSLINE_LABELS;
|
|
2100
2187
|
var init_render = __esm(() => {
|
|
2101
2188
|
init_agents();
|
|
2189
|
+
init_repo();
|
|
2102
2190
|
init_incognito();
|
|
2103
2191
|
init_watermark();
|
|
2104
2192
|
STATUSLINE_LABELS = {
|
|
2105
2193
|
on: "\uD83D\uDCDA Dosu studying…",
|
|
2106
2194
|
incognito: "\uD83D\uDC7B Dosu incognito",
|
|
2107
2195
|
paused: "⚪ Dosu paused",
|
|
2108
|
-
"not-studied": "⚪ Dosu not studying this
|
|
2196
|
+
"not-studied": "⚪ Dosu not studying this repo",
|
|
2109
2197
|
off: "⚪ Dosu off"
|
|
2110
2198
|
};
|
|
2111
2199
|
});
|
|
@@ -9863,7 +9951,7 @@ var init_default_browser_id = __esm(() => {
|
|
|
9863
9951
|
// node_modules/run-applescript/index.js
|
|
9864
9952
|
import process6 from "node:process";
|
|
9865
9953
|
import { promisify as promisify4 } from "node:util";
|
|
9866
|
-
import { execFile as execFile4, execFileSync } from "node:child_process";
|
|
9954
|
+
import { execFile as execFile4, execFileSync as execFileSync2 } from "node:child_process";
|
|
9867
9955
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
9868
9956
|
if (process6.platform !== "darwin") {
|
|
9869
9957
|
throw new Error("macOS only");
|
|
@@ -11881,25 +11969,218 @@ var init_integrations = __esm(() => {
|
|
|
11881
11969
|
};
|
|
11882
11970
|
});
|
|
11883
11971
|
|
|
11972
|
+
// src/sessions/branch.ts
|
|
11973
|
+
function recordedBranch(value) {
|
|
11974
|
+
if (typeof value !== "string")
|
|
11975
|
+
return null;
|
|
11976
|
+
const branch = value.trim();
|
|
11977
|
+
return branch && branch !== "HEAD" ? branch : null;
|
|
11978
|
+
}
|
|
11979
|
+
function branchFromClaudeTranscript(text) {
|
|
11980
|
+
let last = null;
|
|
11981
|
+
for (const match of text.matchAll(/"gitBranch":\s*("(?:[^"\\]|\\.)*")/g)) {
|
|
11982
|
+
try {
|
|
11983
|
+
last = recordedBranch(JSON.parse(match[1])) ?? last;
|
|
11984
|
+
} catch {}
|
|
11985
|
+
}
|
|
11986
|
+
return last;
|
|
11987
|
+
}
|
|
11988
|
+
function branchFromCodexTranscript(text) {
|
|
11989
|
+
for (const line of text.split(`
|
|
11990
|
+
`, CODEX_META_LINES)) {
|
|
11991
|
+
if (!line.includes('"session_meta"'))
|
|
11992
|
+
continue;
|
|
11993
|
+
try {
|
|
11994
|
+
const record = JSON.parse(line);
|
|
11995
|
+
if (record.type === "session_meta")
|
|
11996
|
+
return recordedBranch(record.payload?.git?.branch);
|
|
11997
|
+
} catch {}
|
|
11998
|
+
}
|
|
11999
|
+
return null;
|
|
12000
|
+
}
|
|
12001
|
+
function parseReflog(out) {
|
|
12002
|
+
const entries = [];
|
|
12003
|
+
for (const line of out.split(`
|
|
12004
|
+
`)) {
|
|
12005
|
+
const match = /^HEAD@\{(\d+)\}\t(.*)$/.exec(line);
|
|
12006
|
+
if (match)
|
|
12007
|
+
entries.push({ at: Number(match[1]), subject: match[2] });
|
|
12008
|
+
}
|
|
12009
|
+
return entries;
|
|
12010
|
+
}
|
|
12011
|
+
function checkoutBranch(name) {
|
|
12012
|
+
return /^[0-9a-f]{7,40}$/.test(name) ? null : recordedBranch(name);
|
|
12013
|
+
}
|
|
12014
|
+
function branchFromReflog(entries, endSec, currentBranch) {
|
|
12015
|
+
if (entries.length === 0)
|
|
12016
|
+
return null;
|
|
12017
|
+
let oldest = Number.POSITIVE_INFINITY;
|
|
12018
|
+
let before = null;
|
|
12019
|
+
let after = null;
|
|
12020
|
+
for (const entry of entries) {
|
|
12021
|
+
oldest = Math.min(oldest, entry.at);
|
|
12022
|
+
const match = CHECKOUT.exec(entry.subject);
|
|
12023
|
+
if (!match)
|
|
12024
|
+
continue;
|
|
12025
|
+
if (entry.at <= endSec) {
|
|
12026
|
+
if (!before || entry.at > before.at)
|
|
12027
|
+
before = { at: entry.at, to: match[2] };
|
|
12028
|
+
} else if (!after || entry.at <= after.at) {
|
|
12029
|
+
after = { at: entry.at, from: match[1] };
|
|
12030
|
+
}
|
|
12031
|
+
}
|
|
12032
|
+
if (endSec < oldest)
|
|
12033
|
+
return null;
|
|
12034
|
+
if (before)
|
|
12035
|
+
return checkoutBranch(before.to);
|
|
12036
|
+
if (after)
|
|
12037
|
+
return checkoutBranch(after.from);
|
|
12038
|
+
return currentBranch();
|
|
12039
|
+
}
|
|
12040
|
+
var CODEX_META_LINES = 50, CHECKOUT;
|
|
12041
|
+
var init_branch = __esm(() => {
|
|
12042
|
+
CHECKOUT = /^checkout: moving from (\S+) to (\S+)$/;
|
|
12043
|
+
});
|
|
12044
|
+
|
|
12045
|
+
// src/sessions/capture.ts
|
|
12046
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync11, renameSync as renameSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
12047
|
+
import { basename as basename2, join as join10 } from "node:path";
|
|
12048
|
+
function capturePath(configDir, key) {
|
|
12049
|
+
const [harness, id, ...rest] = key.split("/");
|
|
12050
|
+
if (rest.length > 0 || !SAFE_SEGMENT.test(harness ?? "") || !SAFE_SEGMENT.test(id ?? "")) {
|
|
12051
|
+
return null;
|
|
12052
|
+
}
|
|
12053
|
+
return join10(configDir, CAPTURE_DIRNAME, harness, `${id}.json`);
|
|
12054
|
+
}
|
|
12055
|
+
function readCapturedSession(key, configDir = getConfigDir()) {
|
|
12056
|
+
const path = capturePath(configDir, key);
|
|
12057
|
+
if (!path)
|
|
12058
|
+
return null;
|
|
12059
|
+
try {
|
|
12060
|
+
const raw = JSON.parse(readFileSync11(path, "utf-8"));
|
|
12061
|
+
return {
|
|
12062
|
+
...typeof raw.dir === "string" ? { dir: raw.dir } : {},
|
|
12063
|
+
...typeof raw.branch === "string" ? { branch: raw.branch } : {},
|
|
12064
|
+
at: typeof raw.at === "string" ? raw.at : ""
|
|
12065
|
+
};
|
|
12066
|
+
} catch {
|
|
12067
|
+
return null;
|
|
12068
|
+
}
|
|
12069
|
+
}
|
|
12070
|
+
function recordCapturedSession(key, update, configDir = getConfigDir(), now = new Date) {
|
|
12071
|
+
const path = capturePath(configDir, key);
|
|
12072
|
+
if (!path)
|
|
12073
|
+
return false;
|
|
12074
|
+
const previous = readCapturedSession(key, configDir);
|
|
12075
|
+
const dir = update.dir ?? previous?.dir;
|
|
12076
|
+
const branch = update.branch ?? previous?.branch;
|
|
12077
|
+
const record = {
|
|
12078
|
+
...dir ? { dir } : {},
|
|
12079
|
+
...branch ? { branch } : {},
|
|
12080
|
+
at: now.toISOString()
|
|
12081
|
+
};
|
|
12082
|
+
try {
|
|
12083
|
+
const parent = join10(path, "..");
|
|
12084
|
+
if (!existsSync11(parent))
|
|
12085
|
+
mkdirSync7(parent, { recursive: true, mode: 448 });
|
|
12086
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
12087
|
+
writeFileSync7(tmp, JSON.stringify(record), { mode: 384 });
|
|
12088
|
+
renameSync3(tmp, path);
|
|
12089
|
+
return true;
|
|
12090
|
+
} catch (err) {
|
|
12091
|
+
logger.debug("sync", `could not record ${key}: ${err.message}`);
|
|
12092
|
+
return false;
|
|
12093
|
+
}
|
|
12094
|
+
}
|
|
12095
|
+
function captureCursorStop(payload, deps = {}) {
|
|
12096
|
+
if (typeof payload !== "object" || payload === null)
|
|
12097
|
+
return false;
|
|
12098
|
+
const hook = payload;
|
|
12099
|
+
if (hook.cursor_version === undefined)
|
|
12100
|
+
return false;
|
|
12101
|
+
const id = typeof hook.transcript_path === "string" && hook.transcript_path.endsWith(".jsonl") ? basename2(hook.transcript_path, ".jsonl") : hook.conversation_id;
|
|
12102
|
+
if (typeof id !== "string")
|
|
12103
|
+
return false;
|
|
12104
|
+
const roots = hook.workspace_roots;
|
|
12105
|
+
const dir = Array.isArray(roots) && typeof roots[0] === "string" ? roots[0] : undefined;
|
|
12106
|
+
if (!dir?.startsWith("/"))
|
|
12107
|
+
return false;
|
|
12108
|
+
const branch = (deps.currentBranch ?? currentBranchOfDir)(dir);
|
|
12109
|
+
return recordCapturedSession(`cursor/${id}`, { dir, branch }, deps.configDir, deps.now);
|
|
12110
|
+
}
|
|
12111
|
+
function readHookStdin(stream = process.stdin, timeoutMs = HOOK_STDIN_TIMEOUT_MS, maxBytes = HOOK_STDIN_MAX_BYTES) {
|
|
12112
|
+
if (stream.isTTY)
|
|
12113
|
+
return Promise.resolve(null);
|
|
12114
|
+
return new Promise((resolve) => {
|
|
12115
|
+
const chunks = [];
|
|
12116
|
+
let size = 0;
|
|
12117
|
+
let done = false;
|
|
12118
|
+
let timer;
|
|
12119
|
+
const finish = (value) => {
|
|
12120
|
+
if (done)
|
|
12121
|
+
return;
|
|
12122
|
+
done = true;
|
|
12123
|
+
clearTimeout(timer);
|
|
12124
|
+
stream.removeAllListeners("data");
|
|
12125
|
+
stream.pause();
|
|
12126
|
+
stream.destroy?.();
|
|
12127
|
+
resolve(value);
|
|
12128
|
+
};
|
|
12129
|
+
stream.on("data", (chunk) => {
|
|
12130
|
+
const buf = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
12131
|
+
size += buf.length;
|
|
12132
|
+
if (size > maxBytes)
|
|
12133
|
+
return finish(null);
|
|
12134
|
+
chunks.push(buf);
|
|
12135
|
+
});
|
|
12136
|
+
stream.on("end", () => {
|
|
12137
|
+
try {
|
|
12138
|
+
finish(JSON.parse(Buffer.concat(chunks).toString("utf-8")));
|
|
12139
|
+
} catch {
|
|
12140
|
+
finish(null);
|
|
12141
|
+
}
|
|
12142
|
+
});
|
|
12143
|
+
stream.on("error", () => finish(null));
|
|
12144
|
+
timer = setTimeout(() => finish(null), timeoutMs);
|
|
12145
|
+
});
|
|
12146
|
+
}
|
|
12147
|
+
async function captureHookSession(stream) {
|
|
12148
|
+
try {
|
|
12149
|
+
const payload = await readHookStdin(stream);
|
|
12150
|
+
if (payload !== null)
|
|
12151
|
+
captureCursorStop(payload);
|
|
12152
|
+
} catch (err) {
|
|
12153
|
+
logger.debug("sync", `hook capture failed: ${err instanceof Error ? err.message : err}`);
|
|
12154
|
+
}
|
|
12155
|
+
}
|
|
12156
|
+
var CAPTURE_DIRNAME = "session-captures", HOOK_STDIN_TIMEOUT_MS = 500, HOOK_STDIN_MAX_BYTES, SAFE_SEGMENT;
|
|
12157
|
+
var init_capture = __esm(() => {
|
|
12158
|
+
init_config();
|
|
12159
|
+
init_logger();
|
|
12160
|
+
init_repo();
|
|
12161
|
+
HOOK_STDIN_MAX_BYTES = 1024 * 1024;
|
|
12162
|
+
SAFE_SEGMENT = /^[A-Za-z0-9_-]+$/;
|
|
12163
|
+
});
|
|
12164
|
+
|
|
11884
12165
|
// src/sessions/project-dir.ts
|
|
11885
12166
|
import {
|
|
11886
12167
|
closeSync as closeSync4,
|
|
11887
|
-
existsSync as
|
|
11888
|
-
mkdirSync as
|
|
12168
|
+
existsSync as existsSync12,
|
|
12169
|
+
mkdirSync as mkdirSync8,
|
|
11889
12170
|
openSync as openSync4,
|
|
11890
|
-
readFileSync as
|
|
12171
|
+
readFileSync as readFileSync12,
|
|
11891
12172
|
readSync as readSync3,
|
|
11892
|
-
renameSync as
|
|
12173
|
+
renameSync as renameSync4,
|
|
11893
12174
|
statSync as statSync4,
|
|
11894
|
-
writeFileSync as
|
|
12175
|
+
writeFileSync as writeFileSync8
|
|
11895
12176
|
} from "node:fs";
|
|
11896
|
-
import { join as
|
|
12177
|
+
import { join as join11 } from "node:path";
|
|
11897
12178
|
function cachePath(configDir) {
|
|
11898
|
-
return
|
|
12179
|
+
return join11(configDir, CACHE_FILENAME2);
|
|
11899
12180
|
}
|
|
11900
12181
|
function loadCacheFile(configDir) {
|
|
11901
12182
|
try {
|
|
11902
|
-
const raw = JSON.parse(
|
|
12183
|
+
const raw = JSON.parse(readFileSync12(cachePath(configDir), "utf-8"));
|
|
11903
12184
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION || typeof raw.entries !== "object")
|
|
11904
12185
|
return {};
|
|
11905
12186
|
return raw.entries;
|
|
@@ -11909,13 +12190,13 @@ function loadCacheFile(configDir) {
|
|
|
11909
12190
|
}
|
|
11910
12191
|
function saveCacheFile(configDir, entries) {
|
|
11911
12192
|
try {
|
|
11912
|
-
if (!
|
|
11913
|
-
|
|
12193
|
+
if (!existsSync12(configDir))
|
|
12194
|
+
mkdirSync8(configDir, { recursive: true, mode: 448 });
|
|
11914
12195
|
const path = cachePath(configDir);
|
|
11915
12196
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
11916
12197
|
const file = { schema_version: CACHE_SCHEMA_VERSION, entries };
|
|
11917
|
-
|
|
11918
|
-
|
|
12198
|
+
writeFileSync8(tmp, JSON.stringify(file), { mode: 384 });
|
|
12199
|
+
renameSync4(tmp, path);
|
|
11919
12200
|
} catch {}
|
|
11920
12201
|
}
|
|
11921
12202
|
function readHead(path, bytes = HEAD_BYTES) {
|
|
@@ -11949,7 +12230,7 @@ function cwdFromJsonlHead(text) {
|
|
|
11949
12230
|
}
|
|
11950
12231
|
return null;
|
|
11951
12232
|
}
|
|
11952
|
-
function unmungeSlug(slug, exists =
|
|
12233
|
+
function unmungeSlug(slug, exists = existsSync12) {
|
|
11953
12234
|
const tokens = slug.replace(/^-/, "").split("-");
|
|
11954
12235
|
if (tokens.length === 0 || tokens[0] === "")
|
|
11955
12236
|
return null;
|
|
@@ -11966,6 +12247,13 @@ function unmungeSlug(slug, exists = existsSync11) {
|
|
|
11966
12247
|
};
|
|
11967
12248
|
return walk("", 0);
|
|
11968
12249
|
}
|
|
12250
|
+
function readWholeFile(path) {
|
|
12251
|
+
try {
|
|
12252
|
+
return readFileSync12(path, "utf-8");
|
|
12253
|
+
} catch {
|
|
12254
|
+
return null;
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
11969
12257
|
function fileMtime(path) {
|
|
11970
12258
|
try {
|
|
11971
12259
|
return statSync4(path).mtime.toISOString();
|
|
@@ -11974,9 +12262,10 @@ function fileMtime(path) {
|
|
|
11974
12262
|
}
|
|
11975
12263
|
}
|
|
11976
12264
|
function createProjectDirResolver(configDir = getConfigDir(), deps = {}) {
|
|
11977
|
-
const exists = deps.exists ??
|
|
12265
|
+
const exists = deps.exists ?? existsSync12;
|
|
11978
12266
|
const head = deps.readHead ?? readHead;
|
|
11979
12267
|
const mtime = deps.mtime ?? fileMtime;
|
|
12268
|
+
const captured = deps.captured ?? ((key) => readCapturedSession(key, configDir));
|
|
11980
12269
|
const entries = loadCacheFile(configDir);
|
|
11981
12270
|
let dirty = false;
|
|
11982
12271
|
const compute = (session) => {
|
|
@@ -11994,26 +12283,81 @@ function createProjectDirResolver(configDir = getConfigDir(), deps = {}) {
|
|
|
11994
12283
|
const text = head(session.path);
|
|
11995
12284
|
return text ? cwdFromJsonlHead(text) : null;
|
|
11996
12285
|
}
|
|
11997
|
-
case "cursor":
|
|
12286
|
+
case "cursor": {
|
|
12287
|
+
const hookDir = captured(`cursor/${session.id}`)?.dir;
|
|
12288
|
+
if (hookDir)
|
|
12289
|
+
return hookDir;
|
|
11998
12290
|
return session.project ? unmungeSlug(session.project, exists) : null;
|
|
12291
|
+
}
|
|
11999
12292
|
default:
|
|
12000
12293
|
return null;
|
|
12001
12294
|
}
|
|
12002
12295
|
};
|
|
12296
|
+
const repoOfDir = deps.repoOfDir ?? originRepoOfDir;
|
|
12297
|
+
const repoByDir = new Map;
|
|
12298
|
+
const readTranscript = deps.readTranscript ?? readWholeFile;
|
|
12299
|
+
const reflogOfDir = deps.reflogOfDir ?? headReflogOfDir;
|
|
12300
|
+
const currentBranch = deps.currentBranch ?? currentBranchOfDir;
|
|
12301
|
+
const reflogByDir = new Map;
|
|
12302
|
+
const currentByDir = new Map;
|
|
12303
|
+
const transcriptBranch = (session) => {
|
|
12304
|
+
if (session.harness !== "claude" && session.harness !== "codex")
|
|
12305
|
+
return null;
|
|
12306
|
+
const text = readTranscript(session.path);
|
|
12307
|
+
if (text === null)
|
|
12308
|
+
return null;
|
|
12309
|
+
return session.harness === "claude" ? branchFromClaudeTranscript(text) : branchFromCodexTranscript(text);
|
|
12310
|
+
};
|
|
12311
|
+
const reflogBranch = (session) => {
|
|
12312
|
+
const dir = resolve(session);
|
|
12313
|
+
const end = Date.parse(session.updated);
|
|
12314
|
+
if (dir === null || Number.isNaN(end))
|
|
12315
|
+
return null;
|
|
12316
|
+
let entries = reflogByDir.get(dir);
|
|
12317
|
+
if (!entries) {
|
|
12318
|
+
entries = parseReflog(reflogOfDir(dir) ?? "");
|
|
12319
|
+
reflogByDir.set(dir, entries);
|
|
12320
|
+
}
|
|
12321
|
+
return branchFromReflog(entries, Math.floor(end / 1000), () => {
|
|
12322
|
+
if (!currentByDir.has(dir))
|
|
12323
|
+
currentByDir.set(dir, currentBranch(dir));
|
|
12324
|
+
return currentByDir.get(dir) ?? null;
|
|
12325
|
+
});
|
|
12326
|
+
};
|
|
12327
|
+
const resolve = (session) => {
|
|
12328
|
+
const key = `${session.harness}/${session.id}`;
|
|
12329
|
+
const cached = entries[key];
|
|
12330
|
+
if (cached && (cached.dir !== null || cached.mtime === mtime(session.path))) {
|
|
12331
|
+
return cached.dir;
|
|
12332
|
+
}
|
|
12333
|
+
const dir = compute(session);
|
|
12334
|
+
entries[key] = { dir, mtime: mtime(session.path) };
|
|
12335
|
+
dirty = true;
|
|
12336
|
+
return dir;
|
|
12337
|
+
};
|
|
12003
12338
|
return {
|
|
12004
12339
|
cached(key) {
|
|
12005
12340
|
return entries[key]?.dir ?? null;
|
|
12006
12341
|
},
|
|
12007
|
-
resolve
|
|
12008
|
-
|
|
12009
|
-
const
|
|
12010
|
-
if (
|
|
12011
|
-
return
|
|
12012
|
-
}
|
|
12013
|
-
|
|
12014
|
-
|
|
12342
|
+
resolve,
|
|
12343
|
+
resolveRepo(session) {
|
|
12344
|
+
const dir = resolve(session);
|
|
12345
|
+
if (dir === null)
|
|
12346
|
+
return null;
|
|
12347
|
+
const entry = entries[`${session.harness}/${session.id}`];
|
|
12348
|
+
if (entry.repo !== undefined && (entry.repo !== null || entry.mtime === mtime(session.path))) {
|
|
12349
|
+
return entry.repo;
|
|
12350
|
+
}
|
|
12351
|
+
if (!repoByDir.has(dir))
|
|
12352
|
+
repoByDir.set(dir, repoOfDir(dir));
|
|
12353
|
+
const repo = repoByDir.get(dir) ?? null;
|
|
12354
|
+
entry.repo = repo;
|
|
12355
|
+
entry.mtime = mtime(session.path);
|
|
12015
12356
|
dirty = true;
|
|
12016
|
-
return
|
|
12357
|
+
return repo;
|
|
12358
|
+
},
|
|
12359
|
+
resolveBranch(session) {
|
|
12360
|
+
return transcriptBranch(session) ?? captured(`${session.harness}/${session.id}`)?.branch ?? reflogBranch(session);
|
|
12017
12361
|
},
|
|
12018
12362
|
flush() {
|
|
12019
12363
|
if (!dirty)
|
|
@@ -12026,6 +12370,9 @@ function createProjectDirResolver(configDir = getConfigDir(), deps = {}) {
|
|
|
12026
12370
|
var CACHE_FILENAME2 = "project-dirs.json", CACHE_SCHEMA_VERSION = 1, HEAD_BYTES, HEAD_LINES = 50;
|
|
12027
12371
|
var init_project_dir = __esm(() => {
|
|
12028
12372
|
init_config();
|
|
12373
|
+
init_branch();
|
|
12374
|
+
init_capture();
|
|
12375
|
+
init_repo();
|
|
12029
12376
|
HEAD_BYTES = 128 * 1024;
|
|
12030
12377
|
});
|
|
12031
12378
|
|
|
@@ -12766,7 +13113,7 @@ var init_queries = __esm(() => {
|
|
|
12766
13113
|
});
|
|
12767
13114
|
|
|
12768
13115
|
// src/report/digest.ts
|
|
12769
|
-
import { readFileSync as
|
|
13116
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
12770
13117
|
function asRecord2(value) {
|
|
12771
13118
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
12772
13119
|
}
|
|
@@ -12997,11 +13344,11 @@ function sessionToDigest(session) {
|
|
|
12997
13344
|
try {
|
|
12998
13345
|
switch (session.harness) {
|
|
12999
13346
|
case "claude":
|
|
13000
|
-
return { turns: digestClaude(
|
|
13347
|
+
return { turns: digestClaude(readFileSync13(session.path, "utf8")) };
|
|
13001
13348
|
case "cursor":
|
|
13002
|
-
return { turns: digestCursor(
|
|
13349
|
+
return { turns: digestCursor(readFileSync13(session.path, "utf8")) };
|
|
13003
13350
|
case "codex":
|
|
13004
|
-
return { turns: digestCodex(
|
|
13351
|
+
return { turns: digestCodex(readFileSync13(session.path, "utf8")) };
|
|
13005
13352
|
case "opencode": {
|
|
13006
13353
|
const turns = readSessionTurns(session).map((turn, index) => ({
|
|
13007
13354
|
role: turn.role,
|
|
@@ -13222,17 +13569,17 @@ var init_notes = __esm(() => {
|
|
|
13222
13569
|
});
|
|
13223
13570
|
|
|
13224
13571
|
// src/report/write.ts
|
|
13225
|
-
import { mkdirSync as
|
|
13572
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
13226
13573
|
import { tmpdir } from "node:os";
|
|
13227
|
-
import { dirname as dirname4, join as
|
|
13574
|
+
import { dirname as dirname4, join as join12, resolve } from "node:path";
|
|
13228
13575
|
import { pathToFileURL } from "node:url";
|
|
13229
13576
|
function defaultReportPath() {
|
|
13230
|
-
return
|
|
13577
|
+
return join12(tmpdir(), "dosu-knowledge-report.html");
|
|
13231
13578
|
}
|
|
13232
13579
|
async function writeAndOpenReport(options) {
|
|
13233
13580
|
const out = resolve(options.out ?? defaultReportPath());
|
|
13234
|
-
|
|
13235
|
-
|
|
13581
|
+
mkdirSync9(dirname4(out), { recursive: true });
|
|
13582
|
+
writeFileSync9(out, options.html, "utf8");
|
|
13236
13583
|
if (options.open !== false) {
|
|
13237
13584
|
const url = pathToFileURL(out).href;
|
|
13238
13585
|
if (options.openUrl) {
|
|
@@ -13247,7 +13594,7 @@ async function writeAndOpenReport(options) {
|
|
|
13247
13594
|
var init_write = () => {};
|
|
13248
13595
|
|
|
13249
13596
|
// src/report/generate.ts
|
|
13250
|
-
import { basename as
|
|
13597
|
+
import { basename as basename3 } from "node:path";
|
|
13251
13598
|
function sessionsForNotes(notes, sessions) {
|
|
13252
13599
|
const ids = new Set(notes.map((n) => n.transcript_id).filter((id) => Boolean(id)));
|
|
13253
13600
|
return sessions.filter((s) => ids.has(s.id));
|
|
@@ -13256,7 +13603,7 @@ function defaultProjectName() {
|
|
|
13256
13603
|
const resolver = createProjectDirResolver();
|
|
13257
13604
|
return (session) => {
|
|
13258
13605
|
const dir = resolver.resolve(session);
|
|
13259
|
-
return dir ?
|
|
13606
|
+
return dir ? basename3(dir) : null;
|
|
13260
13607
|
};
|
|
13261
13608
|
}
|
|
13262
13609
|
function noteTime(note) {
|
|
@@ -13309,12 +13656,11 @@ var init_generate = __esm(() => {
|
|
|
13309
13656
|
function listSessionBacklog() {
|
|
13310
13657
|
try {
|
|
13311
13658
|
const state = loadSyncState();
|
|
13312
|
-
|
|
13313
|
-
|
|
13314
|
-
|
|
13315
|
-
|
|
13316
|
-
|
|
13317
|
-
}
|
|
13659
|
+
const scanned = scanAgentSessions({});
|
|
13660
|
+
const resolver = createProjectDirResolver();
|
|
13661
|
+
const filter = studyRepoFilter(state, () => scanned, resolver);
|
|
13662
|
+
const sessions = filterSessionsByRepo(scanned, filter, resolver.resolveRepo);
|
|
13663
|
+
resolver.flush();
|
|
13318
13664
|
const gate = gateSessions(sessions, state.watermark);
|
|
13319
13665
|
const { kept, skipped } = partitionIncognitoSessions(gate.ready);
|
|
13320
13666
|
return { queued: kept.reverse(), open: gate.open.reverse(), incognito: skipped.reverse() };
|
|
@@ -13330,8 +13676,8 @@ var init_backlog = __esm(() => {
|
|
|
13330
13676
|
});
|
|
13331
13677
|
|
|
13332
13678
|
// src/sync/lock.ts
|
|
13333
|
-
import { existsSync as
|
|
13334
|
-
import { join as
|
|
13679
|
+
import { existsSync as existsSync13, readFileSync as readFileSync14, rmSync as rmSync2, statSync as statSync5, writeFileSync as writeFileSync10 } from "node:fs";
|
|
13680
|
+
import { join as join13 } from "node:path";
|
|
13335
13681
|
function processAlive(pid) {
|
|
13336
13682
|
try {
|
|
13337
13683
|
process.kill(pid, 0);
|
|
@@ -13341,7 +13687,7 @@ function processAlive(pid) {
|
|
|
13341
13687
|
}
|
|
13342
13688
|
}
|
|
13343
13689
|
function lockPath(configDir = getConfigDir()) {
|
|
13344
|
-
return
|
|
13690
|
+
return join13(configDir, LOCK_FILENAME);
|
|
13345
13691
|
}
|
|
13346
13692
|
function stopSyncRun(pid, configDir = getConfigDir(), kill = process.kill.bind(process)) {
|
|
13347
13693
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
@@ -13358,7 +13704,7 @@ function stopSyncRun(pid, configDir = getConfigDir(), kill = process.kill.bind(p
|
|
|
13358
13704
|
}
|
|
13359
13705
|
try {
|
|
13360
13706
|
const path = lockPath(configDir);
|
|
13361
|
-
if (
|
|
13707
|
+
if (existsSync13(path) && readFileSync14(path, "utf8") === String(pid)) {
|
|
13362
13708
|
rmSync2(path, { force: true });
|
|
13363
13709
|
}
|
|
13364
13710
|
} catch {}
|
|
@@ -13369,7 +13715,7 @@ function fileLock(configDir = getConfigDir(), now = () => new Date) {
|
|
|
13369
13715
|
let held = false;
|
|
13370
13716
|
const tryCreate = () => {
|
|
13371
13717
|
try {
|
|
13372
|
-
|
|
13718
|
+
writeFileSync10(path, String(process.pid), { flag: "wx" });
|
|
13373
13719
|
return true;
|
|
13374
13720
|
} catch {
|
|
13375
13721
|
return false;
|
|
@@ -13383,7 +13729,7 @@ function fileLock(configDir = getConfigDir(), now = () => new Date) {
|
|
|
13383
13729
|
}
|
|
13384
13730
|
try {
|
|
13385
13731
|
const age = now().getTime() - statSync5(path).mtimeMs;
|
|
13386
|
-
const holder = Number.parseInt(
|
|
13732
|
+
const holder = Number.parseInt(readFileSync14(path, "utf8"), 10);
|
|
13387
13733
|
const holderDead = Number.isInteger(holder) && holder > 0 && !processAlive(holder);
|
|
13388
13734
|
if (age > STALE_LOCK_MS || holderDead) {
|
|
13389
13735
|
rmSync2(path, { force: true });
|
|
@@ -13398,7 +13744,7 @@ function fileLock(configDir = getConfigDir(), now = () => new Date) {
|
|
|
13398
13744
|
return;
|
|
13399
13745
|
held = false;
|
|
13400
13746
|
try {
|
|
13401
|
-
if (
|
|
13747
|
+
if (existsSync13(path) && readFileSync14(path, "utf8") === String(process.pid)) {
|
|
13402
13748
|
rmSync2(path, { force: true });
|
|
13403
13749
|
}
|
|
13404
13750
|
} catch {}
|
|
@@ -13412,7 +13758,7 @@ var init_lock = __esm(() => {
|
|
|
13412
13758
|
});
|
|
13413
13759
|
|
|
13414
13760
|
// src/sync/status.ts
|
|
13415
|
-
import { readFileSync as
|
|
13761
|
+
import { readFileSync as readFileSync15, statSync as statSync6 } from "node:fs";
|
|
13416
13762
|
function formatTokenCount(tokens) {
|
|
13417
13763
|
if (tokens < 1000)
|
|
13418
13764
|
return String(tokens);
|
|
@@ -13435,7 +13781,7 @@ function defaultIsProcessAlive2(pid) {
|
|
|
13435
13781
|
}
|
|
13436
13782
|
function defaultReadLog() {
|
|
13437
13783
|
try {
|
|
13438
|
-
return
|
|
13784
|
+
return readFileSync15(logger.getLogPath(), "utf-8");
|
|
13439
13785
|
} catch {
|
|
13440
13786
|
return "";
|
|
13441
13787
|
}
|
|
@@ -13443,7 +13789,7 @@ function defaultReadLog() {
|
|
|
13443
13789
|
function readLockFile(configDir) {
|
|
13444
13790
|
const path = lockPath(configDir);
|
|
13445
13791
|
try {
|
|
13446
|
-
const pid = Number.parseInt(
|
|
13792
|
+
const pid = Number.parseInt(readFileSync15(path, "utf-8"), 10);
|
|
13447
13793
|
return { pid: Number.isNaN(pid) ? -1 : pid, mtime: statSync6(path).mtime };
|
|
13448
13794
|
} catch {
|
|
13449
13795
|
return null;
|
|
@@ -13535,24 +13881,33 @@ async function runKnowledgeSync(options = {}) {
|
|
|
13535
13881
|
}
|
|
13536
13882
|
let ready;
|
|
13537
13883
|
let open;
|
|
13884
|
+
let branchOf;
|
|
13538
13885
|
try {
|
|
13539
13886
|
const listSessions = deps.listSessions ?? (() => options.bootstrap ? scanAgentSessions({}) : scanAgentSessions({
|
|
13540
13887
|
since: new Date(now().getTime() - GATE_WINDOW_DAYS * 24 * 60 * 60 * 1000),
|
|
13541
13888
|
limit: GATE_WINDOW
|
|
13542
13889
|
}));
|
|
13543
|
-
|
|
13544
|
-
|
|
13545
|
-
|
|
13546
|
-
|
|
13547
|
-
|
|
13548
|
-
|
|
13549
|
-
|
|
13550
|
-
|
|
13551
|
-
|
|
13552
|
-
|
|
13553
|
-
|
|
13554
|
-
|
|
13555
|
-
|
|
13890
|
+
const scanned = await listSessions();
|
|
13891
|
+
let flush;
|
|
13892
|
+
let locator = deps.locator;
|
|
13893
|
+
let resolveBranch = deps.resolveBranch;
|
|
13894
|
+
if (!locator || !resolveBranch) {
|
|
13895
|
+
const resolver = createProjectDirResolver();
|
|
13896
|
+
locator ??= resolver;
|
|
13897
|
+
resolveBranch ??= resolver.resolveBranch;
|
|
13898
|
+
flush = resolver.flush;
|
|
13899
|
+
}
|
|
13900
|
+
branchOf = resolveBranch;
|
|
13901
|
+
const repoFilter = studyRepoFilter(state, () => scanAgentSessions({}), locator);
|
|
13902
|
+
if (state.project_filter) {
|
|
13903
|
+
delete state.project_filter;
|
|
13904
|
+
if (repoFilter)
|
|
13905
|
+
state.repo_filter = repoFilter;
|
|
13906
|
+
logger.debug("sync", `folder scope converted to repos: ${repoFilter?.join(", ") || "none"}`);
|
|
13907
|
+
}
|
|
13908
|
+
const sessions = filterSessionsByRepo(scanned, repoFilter, (s) => locator.resolveRepo(s));
|
|
13909
|
+
flush?.();
|
|
13910
|
+
logger.debug("sync", `study scope ${repoFilter ? repoFilter.join(", ") || "none" : "all repos"}: ${sessions.length} of ${scanned.length} sessions in scope`);
|
|
13556
13911
|
({ ready, open } = gateSessions(sessions, state.watermark, now()));
|
|
13557
13912
|
logGateResult(ready, open.length, state.watermark);
|
|
13558
13913
|
} catch (err) {
|
|
@@ -13611,10 +13966,11 @@ async function runKnowledgeSync(options = {}) {
|
|
|
13611
13966
|
} else if (isIncognito(candidate)) {
|
|
13612
13967
|
incognito += 1;
|
|
13613
13968
|
logger.debug("sync", `skipping incognito session ${candidate.harness}/${candidate.id}`);
|
|
13614
|
-
} else if (worthStudying(candidate)) {
|
|
13615
|
-
batch.push(candidate);
|
|
13616
|
-
} else {
|
|
13969
|
+
} else if (!worthStudying(candidate)) {
|
|
13617
13970
|
trivial += 1;
|
|
13971
|
+
} else {
|
|
13972
|
+
const branch = candidate.repo ? branchOf(candidate) : null;
|
|
13973
|
+
batch.push(branch ? { ...candidate, branch } : candidate);
|
|
13618
13974
|
}
|
|
13619
13975
|
}
|
|
13620
13976
|
const skippedNote = `${trivial} trivial, ${incognito} incognito${alreadyStudied > 0 ? `, ${alreadyStudied} already studied` : ""} skipped`;
|
|
@@ -13742,7 +14098,7 @@ var init_sync = __esm(() => {
|
|
|
13742
14098
|
});
|
|
13743
14099
|
|
|
13744
14100
|
// src/learner/conflicts.ts
|
|
13745
|
-
import { existsSync as
|
|
14101
|
+
import { existsSync as existsSync14, readFileSync as readFileSync16 } from "node:fs";
|
|
13746
14102
|
function managedSettingsPaths(platform = process.platform) {
|
|
13747
14103
|
switch (platform) {
|
|
13748
14104
|
case "darwin":
|
|
@@ -13771,11 +14127,11 @@ function conflictingKeysIn(settings) {
|
|
|
13771
14127
|
function detectSettingsConflicts(paths = managedSettingsPaths()) {
|
|
13772
14128
|
const conflicts = [];
|
|
13773
14129
|
for (const file of paths) {
|
|
13774
|
-
if (!
|
|
14130
|
+
if (!existsSync14(file))
|
|
13775
14131
|
continue;
|
|
13776
14132
|
let settings;
|
|
13777
14133
|
try {
|
|
13778
|
-
settings = JSON.parse(
|
|
14134
|
+
settings = JSON.parse(readFileSync16(file, "utf8"));
|
|
13779
14135
|
} catch {
|
|
13780
14136
|
conflicts.push({ file, keys: [UNREADABLE_SETTINGS_KEY] });
|
|
13781
14137
|
continue;
|
|
@@ -13800,11 +14156,11 @@ var init_conflicts = __esm(() => {
|
|
|
13800
14156
|
});
|
|
13801
14157
|
|
|
13802
14158
|
// src/telemetry/debug-id.ts
|
|
13803
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
14159
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "3b9a1619-fdbd-ebdd-6475-6e2164756e21";
|
|
13804
14160
|
|
|
13805
14161
|
// src/telemetry/telemetry.ts
|
|
13806
14162
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
13807
|
-
import { existsSync as
|
|
14163
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
13808
14164
|
import { request as httpRequest2 } from "node:http";
|
|
13809
14165
|
import { request as httpsRequest } from "node:https";
|
|
13810
14166
|
import { isAbsolute, relative, resolve as resolve2, sep } from "node:path";
|
|
@@ -13942,7 +14298,7 @@ function parseOwnedStackLine(originalLine, packageRoot) {
|
|
|
13942
14298
|
return;
|
|
13943
14299
|
}
|
|
13944
14300
|
try {
|
|
13945
|
-
if (!
|
|
14301
|
+
if (!existsSync15(resolvedPath))
|
|
13946
14302
|
return;
|
|
13947
14303
|
} catch {
|
|
13948
14304
|
return;
|
|
@@ -14825,9 +15181,9 @@ var init_agent_select = __esm(() => {
|
|
|
14825
15181
|
});
|
|
14826
15182
|
|
|
14827
15183
|
// src/incognito/agents.ts
|
|
14828
|
-
import { existsSync as
|
|
15184
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync10, readFileSync as readFileSync17, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "node:fs";
|
|
14829
15185
|
import { homedir as homedir4 } from "node:os";
|
|
14830
|
-
import { dirname as dirname5, join as
|
|
15186
|
+
import { dirname as dirname5, join as join14 } from "node:path";
|
|
14831
15187
|
function withFrontmatter(body) {
|
|
14832
15188
|
return `---
|
|
14833
15189
|
description: ${DESCRIPTION}
|
|
@@ -14836,10 +15192,10 @@ description: ${DESCRIPTION}
|
|
|
14836
15192
|
${body}`;
|
|
14837
15193
|
}
|
|
14838
15194
|
function claudeConfigDir2() {
|
|
14839
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
15195
|
+
return process.env.CLAUDE_CONFIG_DIR || join14(homedir4(), ".claude");
|
|
14840
15196
|
}
|
|
14841
15197
|
function codexHome2() {
|
|
14842
|
-
return process.env.CODEX_HOME ||
|
|
15198
|
+
return process.env.CODEX_HOME || join14(homedir4(), ".codex");
|
|
14843
15199
|
}
|
|
14844
15200
|
function fileAgent(options) {
|
|
14845
15201
|
const { commandPath, content } = options;
|
|
@@ -14850,29 +15206,29 @@ function fileAgent(options) {
|
|
|
14850
15206
|
commandPath,
|
|
14851
15207
|
isEnabled: () => {
|
|
14852
15208
|
const path = commandPath();
|
|
14853
|
-
if (!
|
|
15209
|
+
if (!existsSync16(path))
|
|
14854
15210
|
return false;
|
|
14855
15211
|
try {
|
|
14856
|
-
return
|
|
15212
|
+
return readFileSync17(path, "utf-8").includes(INCOGNITO_MARKER);
|
|
14857
15213
|
} catch {
|
|
14858
15214
|
return false;
|
|
14859
15215
|
}
|
|
14860
15216
|
},
|
|
14861
15217
|
enable: () => {
|
|
14862
15218
|
const path = commandPath();
|
|
14863
|
-
if (
|
|
14864
|
-
if (
|
|
15219
|
+
if (existsSync16(path)) {
|
|
15220
|
+
if (readFileSync17(path, "utf-8") === content)
|
|
14865
15221
|
return "unchanged";
|
|
14866
|
-
|
|
15222
|
+
writeFileSync11(path, content, "utf-8");
|
|
14867
15223
|
return "updated";
|
|
14868
15224
|
}
|
|
14869
|
-
|
|
14870
|
-
|
|
15225
|
+
mkdirSync10(dirname5(path), { recursive: true });
|
|
15226
|
+
writeFileSync11(path, content, "utf-8");
|
|
14871
15227
|
return "created";
|
|
14872
15228
|
},
|
|
14873
15229
|
disable: () => {
|
|
14874
15230
|
const path = commandPath();
|
|
14875
|
-
if (!
|
|
15231
|
+
if (!existsSync16(path))
|
|
14876
15232
|
return "not_found";
|
|
14877
15233
|
unlinkSync2(path);
|
|
14878
15234
|
return "removed";
|
|
@@ -14885,21 +15241,21 @@ function allIncognitoAgents() {
|
|
|
14885
15241
|
id: "claude",
|
|
14886
15242
|
name: "Claude Code",
|
|
14887
15243
|
detectPath: claudeConfigDir2,
|
|
14888
|
-
commandPath: () =>
|
|
15244
|
+
commandPath: () => join14(claudeConfigDir2(), "commands", FILE_NAME),
|
|
14889
15245
|
content: withFrontmatter(INCOGNITO_COMMAND_BODY)
|
|
14890
15246
|
}),
|
|
14891
15247
|
fileAgent({
|
|
14892
15248
|
id: "cursor",
|
|
14893
15249
|
name: "Cursor",
|
|
14894
|
-
detectPath: () =>
|
|
14895
|
-
commandPath: () =>
|
|
15250
|
+
detectPath: () => join14(homedir4(), ".cursor"),
|
|
15251
|
+
commandPath: () => join14(homedir4(), ".cursor", "commands", FILE_NAME),
|
|
14896
15252
|
content: INCOGNITO_COMMAND_BODY
|
|
14897
15253
|
}),
|
|
14898
15254
|
fileAgent({
|
|
14899
15255
|
id: "codex",
|
|
14900
15256
|
name: "Codex",
|
|
14901
15257
|
detectPath: codexHome2,
|
|
14902
|
-
commandPath: () =>
|
|
15258
|
+
commandPath: () => join14(codexHome2(), "prompts", FILE_NAME),
|
|
14903
15259
|
content: withFrontmatter(INCOGNITO_COMMAND_BODY)
|
|
14904
15260
|
})
|
|
14905
15261
|
];
|
|
@@ -14983,7 +15339,7 @@ var init_knowledge_incognito = __esm(() => {
|
|
|
14983
15339
|
|
|
14984
15340
|
// src/statusline/agents.ts
|
|
14985
15341
|
import { homedir as homedir5 } from "node:os";
|
|
14986
|
-
import { join as
|
|
15342
|
+
import { join as join15 } from "node:path";
|
|
14987
15343
|
function statuslineCommand(agentId) {
|
|
14988
15344
|
if (process.env.DOSU_DEV !== "true")
|
|
14989
15345
|
return `dosu ${RENDER_ARGS} ${agentId}`;
|
|
@@ -14993,7 +15349,7 @@ function isDosuStatuslineCommand(command) {
|
|
|
14993
15349
|
return typeof command === "string" && command.includes(RENDER_ARGS);
|
|
14994
15350
|
}
|
|
14995
15351
|
function claudeConfigDir3() {
|
|
14996
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
15352
|
+
return process.env.CLAUDE_CONFIG_DIR || join15(homedir5(), ".claude");
|
|
14997
15353
|
}
|
|
14998
15354
|
function statuslineOf(config) {
|
|
14999
15355
|
const value = config.statusLine;
|
|
@@ -15034,7 +15390,7 @@ function allStatuslineAgents() {
|
|
|
15034
15390
|
id: "claude",
|
|
15035
15391
|
name: "Claude Code",
|
|
15036
15392
|
detectPath: claudeConfigDir3,
|
|
15037
|
-
configPath: () =>
|
|
15393
|
+
configPath: () => join15(claudeConfigDir3(), "settings.json")
|
|
15038
15394
|
}),
|
|
15039
15395
|
configAgent({
|
|
15040
15396
|
id: "cursor",
|
|
@@ -15299,12 +15655,12 @@ var init_backfill_run = __esm(() => {
|
|
|
15299
15655
|
});
|
|
15300
15656
|
|
|
15301
15657
|
// src/learner/config-dir.ts
|
|
15302
|
-
import { mkdtempSync, rmSync as rmSync3, writeFileSync as
|
|
15658
|
+
import { mkdtempSync, rmSync as rmSync3, writeFileSync as writeFileSync12 } from "node:fs";
|
|
15303
15659
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
15304
|
-
import { join as
|
|
15660
|
+
import { join as join16 } from "node:path";
|
|
15305
15661
|
function createRunConfigDir() {
|
|
15306
|
-
const path = mkdtempSync(
|
|
15307
|
-
|
|
15662
|
+
const path = mkdtempSync(join16(tmpdir2(), "dosu-learner-"));
|
|
15663
|
+
writeFileSync12(join16(path, ".claude.json"), JSON.stringify({ hasCompletedOnboarding: true }));
|
|
15308
15664
|
return {
|
|
15309
15665
|
path,
|
|
15310
15666
|
cleanup() {
|
|
@@ -15352,10 +15708,10 @@ var init_env = __esm(() => {
|
|
|
15352
15708
|
});
|
|
15353
15709
|
|
|
15354
15710
|
// src/learner/executable.ts
|
|
15355
|
-
import { accessSync, constants as constants2, existsSync as
|
|
15711
|
+
import { accessSync, constants as constants2, existsSync as existsSync17 } from "node:fs";
|
|
15356
15712
|
import { createRequire as createRequire3 } from "node:module";
|
|
15357
15713
|
import { homedir as homedir6 } from "node:os";
|
|
15358
|
-
import { delimiter as delimiter2, dirname as dirname6, join as
|
|
15714
|
+
import { delimiter as delimiter2, dirname as dirname6, join as join17 } from "node:path";
|
|
15359
15715
|
function binaryNames(platform = process.platform) {
|
|
15360
15716
|
return platform === "win32" ? ["claude.exe", "claude.cmd"] : ["claude"];
|
|
15361
15717
|
}
|
|
@@ -15364,7 +15720,7 @@ function sdkNativeBinaryExists() {
|
|
|
15364
15720
|
const requireRuntime = createRequire3(import.meta.url);
|
|
15365
15721
|
const pkg = `@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}`;
|
|
15366
15722
|
const pkgDir = dirname6(requireRuntime.resolve(`${pkg}/package.json`));
|
|
15367
|
-
return binaryNames().some((name) =>
|
|
15723
|
+
return binaryNames().some((name) => existsSync17(join17(pkgDir, name)));
|
|
15368
15724
|
} catch {
|
|
15369
15725
|
return false;
|
|
15370
15726
|
}
|
|
@@ -15380,10 +15736,10 @@ function isExecutable(path) {
|
|
|
15380
15736
|
function findSystemClaude(env = process.env, homeDir = homedir6()) {
|
|
15381
15737
|
const names = binaryNames();
|
|
15382
15738
|
const dirs = (env.PATH ?? "").split(delimiter2).filter(Boolean);
|
|
15383
|
-
dirs.push(
|
|
15739
|
+
dirs.push(join17(homeDir, ".local", "bin"), join17(homeDir, ".claude", "local"));
|
|
15384
15740
|
for (const dir of dirs) {
|
|
15385
15741
|
for (const name of names) {
|
|
15386
|
-
const candidate =
|
|
15742
|
+
const candidate = join17(dir, name);
|
|
15387
15743
|
if (isExecutable(candidate))
|
|
15388
15744
|
return candidate;
|
|
15389
15745
|
}
|
|
@@ -15477,9 +15833,8 @@ note cap are the volume guards.
|
|
|
15477
15833
|
5. Title is a noun-phrase topic (like "page_version UniqueViolation race"), not a sentence.
|
|
15478
15834
|
Content is a self-contained observation in plain language; include file/path pointers when
|
|
15479
15835
|
useful.
|
|
15480
|
-
6.
|
|
15481
|
-
|
|
15482
|
-
verified, omit both.
|
|
15836
|
+
6. Never pass repo or branch to write_knowledge; the client attaches each note's repo from the
|
|
15837
|
+
session it came from.
|
|
15483
15838
|
7. Never quote credentials, tokens, or secrets — even redacted placeholders — and never include
|
|
15484
15839
|
long verbatim transcript spans. Summarize in your own words.
|
|
15485
15840
|
8. A trivial session with no real user query is normal: skip it silently.`;
|
|
@@ -58494,6 +58849,8 @@ async function runLearner(options) {
|
|
|
58494
58849
|
let currentSession;
|
|
58495
58850
|
const readsSinceWrite = new Set;
|
|
58496
58851
|
const sessionKeys = new Map(options.sessions.map((s) => [s.id, `${s.harness}/${s.id}`]));
|
|
58852
|
+
const sessionRepos = new Map(options.sessions.map((s) => [s.id, s.repo]));
|
|
58853
|
+
const sessionBranches = new Map(options.sessions.map((s) => [s.id, s.branch]));
|
|
58497
58854
|
const notedSessions = new Set;
|
|
58498
58855
|
const pendingNotes = new Map;
|
|
58499
58856
|
let turns = 0;
|
|
@@ -58572,15 +58929,32 @@ async function runLearner(options) {
|
|
|
58572
58929
|
message: "Write each session's notes right after reading THAT session, before reading the next. You have read multiple sessions without writing, so a note cannot be attributed to one. Re-read only the session this note is about, then write it."
|
|
58573
58930
|
};
|
|
58574
58931
|
}
|
|
58932
|
+
const noted = currentSession && sessionKeys.get(currentSession);
|
|
58933
|
+
if (!currentSession || !noted) {
|
|
58934
|
+
return {
|
|
58935
|
+
behavior: "deny",
|
|
58936
|
+
message: "Read the session this note is about with read_session first, then write it."
|
|
58937
|
+
};
|
|
58938
|
+
}
|
|
58575
58939
|
notesWritten += 1;
|
|
58576
58940
|
readsSinceWrite.clear();
|
|
58577
|
-
|
|
58578
|
-
|
|
58579
|
-
|
|
58580
|
-
|
|
58941
|
+
pendingNotes.set(toolUseID, noted);
|
|
58942
|
+
const {
|
|
58943
|
+
transcript_id: _transcriptByModel,
|
|
58944
|
+
repo: _repoByModel,
|
|
58945
|
+
branch: _branchByModel,
|
|
58946
|
+
...clean
|
|
58947
|
+
} = input;
|
|
58948
|
+
const repo = sessionRepos.get(currentSession);
|
|
58949
|
+
const branch = repo && sessionBranches.get(currentSession);
|
|
58581
58950
|
return {
|
|
58582
58951
|
behavior: "allow",
|
|
58583
|
-
updatedInput:
|
|
58952
|
+
updatedInput: {
|
|
58953
|
+
...clean,
|
|
58954
|
+
transcript_id: currentSession,
|
|
58955
|
+
...repo ? { repo } : {},
|
|
58956
|
+
...branch ? { branch } : {}
|
|
58957
|
+
}
|
|
58584
58958
|
};
|
|
58585
58959
|
}
|
|
58586
58960
|
return { behavior: "allow", updatedInput: input };
|
|
@@ -58669,9 +59043,8 @@ var init_runner = __esm(() => {
|
|
|
58669
59043
|
});
|
|
58670
59044
|
|
|
58671
59045
|
// src/commands/knowledge.ts
|
|
58672
|
-
import { existsSync as
|
|
58673
|
-
import {
|
|
58674
|
-
import { delimiter as delimiter4, join as join21 } from "node:path";
|
|
59046
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
59047
|
+
import { delimiter as delimiter4, join as join22 } from "node:path";
|
|
58675
59048
|
function requireConfig7() {
|
|
58676
59049
|
const cfg = requireLoginConfig();
|
|
58677
59050
|
if (!cfg.active_account?.target?.org_id || !cfg.active_account?.target?.space_id) {
|
|
@@ -58791,6 +59164,7 @@ ${results.length - opts.limit} more results not shown.`));
|
|
|
58791
59164
|
return;
|
|
58792
59165
|
}
|
|
58793
59166
|
if (opts.detach) {
|
|
59167
|
+
await captureHookSession();
|
|
58794
59168
|
const spawned = spawnDetachedSelf([
|
|
58795
59169
|
"knowledge",
|
|
58796
59170
|
"sync",
|
|
@@ -58938,10 +59312,11 @@ function printSyncStatus(status, now = new Date) {
|
|
|
58938
59312
|
}
|
|
58939
59313
|
const wm = status.state.watermark;
|
|
58940
59314
|
console.log(` Studied through: ${wm ? `${wm} (${formatAge(wm, now)})` : "nothing studied yet"}`);
|
|
58941
|
-
|
|
58942
|
-
|
|
58943
|
-
|
|
58944
|
-
|
|
59315
|
+
const repoFilter = status.state.repo_filter;
|
|
59316
|
+
if (repoFilter) {
|
|
59317
|
+
console.log(` Study scope: ${repoFilter.length ? repoFilter.map(displayRepo).join(", ") : "no repos"}`);
|
|
59318
|
+
} else if (status.state.project_filter?.length) {
|
|
59319
|
+
console.log(` Study scope: ${status.state.project_filter.length} folders (converted to repos on the next sync)`);
|
|
58945
59320
|
}
|
|
58946
59321
|
if ((status.state.total_notes ?? 0) > 0) {
|
|
58947
59322
|
const tokens = status.state.total_learning_tokens ?? 0;
|
|
@@ -59094,7 +59469,7 @@ function reportHookFailure(agent, err) {
|
|
|
59094
59469
|
}
|
|
59095
59470
|
function dosuOnPath() {
|
|
59096
59471
|
const bin = process.platform === "win32" ? "dosu.cmd" : "dosu";
|
|
59097
|
-
return (process.env.PATH ?? "").split(delimiter4).some((dir) => dir !== "" &&
|
|
59472
|
+
return (process.env.PATH ?? "").split(delimiter4).some((dir) => dir !== "" && existsSync19(join22(dir, bin)));
|
|
59098
59473
|
}
|
|
59099
59474
|
var import_picocolors21;
|
|
59100
59475
|
var init_knowledge = __esm(() => {
|
|
@@ -59104,6 +59479,8 @@ var init_knowledge = __esm(() => {
|
|
|
59104
59479
|
init_agents();
|
|
59105
59480
|
init_formats();
|
|
59106
59481
|
init_generate();
|
|
59482
|
+
init_capture();
|
|
59483
|
+
init_repo();
|
|
59107
59484
|
init_backlog();
|
|
59108
59485
|
init_detach();
|
|
59109
59486
|
init_status();
|
|
@@ -59558,7 +59935,7 @@ var init_time_range = __esm(() => {
|
|
|
59558
59935
|
});
|
|
59559
59936
|
|
|
59560
59937
|
// src/commands/review.ts
|
|
59561
|
-
import { readFileSync as
|
|
59938
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
59562
59939
|
function requireConfig10() {
|
|
59563
59940
|
return requireLoginConfig();
|
|
59564
59941
|
}
|
|
@@ -59746,7 +60123,7 @@ function reviewCommand() {
|
|
|
59746
60123
|
let body = opts.body;
|
|
59747
60124
|
if (opts.bodyFile) {
|
|
59748
60125
|
try {
|
|
59749
|
-
body =
|
|
60126
|
+
body = readFileSync19(opts.bodyFile, "utf-8");
|
|
59750
60127
|
} catch (err) {
|
|
59751
60128
|
console.error(import_picocolors25.default.red(`Failed to read --body-file: ${err.message}`));
|
|
59752
60129
|
process.exit(1);
|
|
@@ -60666,16 +61043,16 @@ The coding agent performs triage; Dosu cloud generates docs and opens the PR.
|
|
|
60666
61043
|
// src/commands/skill.ts
|
|
60667
61044
|
import {
|
|
60668
61045
|
cpSync,
|
|
60669
|
-
existsSync as
|
|
61046
|
+
existsSync as existsSync20,
|
|
60670
61047
|
lstatSync as lstatSync2,
|
|
60671
|
-
mkdirSync as
|
|
60672
|
-
readFileSync as
|
|
61048
|
+
mkdirSync as mkdirSync12,
|
|
61049
|
+
readFileSync as readFileSync20,
|
|
60673
61050
|
rmSync as rmSync5,
|
|
60674
61051
|
symlinkSync,
|
|
60675
|
-
writeFileSync as
|
|
61052
|
+
writeFileSync as writeFileSync13
|
|
60676
61053
|
} from "node:fs";
|
|
60677
|
-
import { homedir as
|
|
60678
|
-
import { dirname as dirname10, join as
|
|
61054
|
+
import { homedir as homedir7 } from "node:os";
|
|
61055
|
+
import { dirname as dirname10, join as join23, relative as relative3 } from "node:path";
|
|
60679
61056
|
function skillAgentIDsForProviders(providerIDs) {
|
|
60680
61057
|
return [
|
|
60681
61058
|
...new Set(providerIDs.map((providerID) => SKILL_AGENT_BY_PROVIDER[providerID]).filter((agent) => Boolean(agent)))
|
|
@@ -60685,15 +61062,15 @@ function isSkillAgentID(agent) {
|
|
|
60685
61062
|
return SUPPORTED_SKILL_AGENTS.includes(agent);
|
|
60686
61063
|
}
|
|
60687
61064
|
function universalSkillsDir() {
|
|
60688
|
-
return
|
|
61065
|
+
return join23(homedir7(), ".agents", "skills");
|
|
60689
61066
|
}
|
|
60690
61067
|
function linkedSkillsDir(agent) {
|
|
60691
61068
|
if (agent === "claude-code") {
|
|
60692
|
-
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() ||
|
|
60693
|
-
return
|
|
61069
|
+
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join23(homedir7(), ".claude");
|
|
61070
|
+
return join23(claudeConfigDir, "skills");
|
|
60694
61071
|
}
|
|
60695
61072
|
if (agent === "windsurf")
|
|
60696
|
-
return
|
|
61073
|
+
return join23(homedir7(), ".codeium", "windsurf", "skills");
|
|
60697
61074
|
return null;
|
|
60698
61075
|
}
|
|
60699
61076
|
function skillInstallTargetForProvider(providerID) {
|
|
@@ -60702,18 +61079,18 @@ function skillInstallTargetForProvider(providerID) {
|
|
|
60702
61079
|
return null;
|
|
60703
61080
|
const linked = linkedSkillsDir(agentID);
|
|
60704
61081
|
if (linked)
|
|
60705
|
-
return { path:
|
|
60706
|
-
return { path:
|
|
61082
|
+
return { path: join23(linked, SKILL_NAME), symlink: true };
|
|
61083
|
+
return { path: join23(universalSkillsDir(), SKILL_NAME), symlink: false };
|
|
60707
61084
|
}
|
|
60708
61085
|
function installStatePath() {
|
|
60709
|
-
return
|
|
61086
|
+
return join23(getConfigDir(), INSTALL_STATE_FILENAME);
|
|
60710
61087
|
}
|
|
60711
61088
|
function readSkillInstallState() {
|
|
60712
61089
|
try {
|
|
60713
61090
|
const path = installStatePath();
|
|
60714
|
-
if (!
|
|
61091
|
+
if (!existsSync20(path))
|
|
60715
61092
|
return null;
|
|
60716
|
-
const data = JSON.parse(
|
|
61093
|
+
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
60717
61094
|
if (typeof data?.version === "string" && Array.isArray(data.agents) && data.agents.every((agent) => typeof agent === "string") && typeof data.installedAt === "number") {
|
|
60718
61095
|
return { version: data.version, agents: data.agents, installedAt: data.installedAt };
|
|
60719
61096
|
}
|
|
@@ -60725,9 +61102,9 @@ function readSkillInstallState() {
|
|
|
60725
61102
|
function writeSkillInstallState(state) {
|
|
60726
61103
|
try {
|
|
60727
61104
|
const dir = getConfigDir();
|
|
60728
|
-
if (!
|
|
60729
|
-
|
|
60730
|
-
|
|
61105
|
+
if (!existsSync20(dir))
|
|
61106
|
+
mkdirSync12(dir, { recursive: true, mode: 448 });
|
|
61107
|
+
writeFileSync13(installStatePath(), JSON.stringify(state), { mode: 384 });
|
|
60731
61108
|
} catch (err) {
|
|
60732
61109
|
logger.debug("skill", `Could not record skill install state: ${err}`);
|
|
60733
61110
|
}
|
|
@@ -60736,11 +61113,11 @@ function clearSkillInstallState() {
|
|
|
60736
61113
|
rmSync5(installStatePath(), { force: true });
|
|
60737
61114
|
}
|
|
60738
61115
|
function pruneLegacySkillLock() {
|
|
60739
|
-
const lockPath =
|
|
61116
|
+
const lockPath = join23(homedir7(), ".agents", ".skill-lock.json");
|
|
60740
61117
|
try {
|
|
60741
|
-
if (!
|
|
61118
|
+
if (!existsSync20(lockPath))
|
|
60742
61119
|
return [];
|
|
60743
|
-
const lock = JSON.parse(
|
|
61120
|
+
const lock = JSON.parse(readFileSync20(lockPath, "utf-8"));
|
|
60744
61121
|
const skills = lock?.skills;
|
|
60745
61122
|
if (!skills || typeof skills !== "object")
|
|
60746
61123
|
return [];
|
|
@@ -60749,7 +61126,7 @@ function pruneLegacySkillLock() {
|
|
|
60749
61126
|
return [];
|
|
60750
61127
|
for (const name of legacy)
|
|
60751
61128
|
delete skills[name];
|
|
60752
|
-
|
|
61129
|
+
writeFileSync13(lockPath, `${JSON.stringify(lock, null, 2)}
|
|
60753
61130
|
`);
|
|
60754
61131
|
logger.debug("skill", `Removed legacy lock entries: ${legacy.join(", ")}`);
|
|
60755
61132
|
return legacy;
|
|
@@ -60769,13 +61146,13 @@ function pathExists(path) {
|
|
|
60769
61146
|
function writeSkillDir(skill, dir) {
|
|
60770
61147
|
rmSync5(dir, { recursive: true, force: true });
|
|
60771
61148
|
for (const file of skill.files) {
|
|
60772
|
-
const target =
|
|
60773
|
-
|
|
60774
|
-
|
|
61149
|
+
const target = join23(dir, ...file.path.split("/"));
|
|
61150
|
+
mkdirSync12(dirname10(target), { recursive: true });
|
|
61151
|
+
writeFileSync13(target, file.content, { mode: file.executable ? 493 : 420 });
|
|
60775
61152
|
}
|
|
60776
61153
|
}
|
|
60777
61154
|
function linkSkillDir(linkPath, targetDir) {
|
|
60778
|
-
|
|
61155
|
+
mkdirSync12(dirname10(linkPath), { recursive: true });
|
|
60779
61156
|
rmSync5(linkPath, { recursive: true, force: true });
|
|
60780
61157
|
try {
|
|
60781
61158
|
symlinkSync(relative3(dirname10(linkPath), targetDir), linkPath, "dir");
|
|
@@ -60808,15 +61185,15 @@ function installBundledSkills(agentIDs) {
|
|
|
60808
61185
|
if (bundledNames.has(name))
|
|
60809
61186
|
continue;
|
|
60810
61187
|
for (const dir of [universalSkillsDir(), ...linkDirs])
|
|
60811
|
-
removeSkillDir(
|
|
61188
|
+
removeSkillDir(join23(dir, name));
|
|
60812
61189
|
}
|
|
60813
61190
|
const paths = [];
|
|
60814
61191
|
for (const skill of BUNDLED_SKILLS) {
|
|
60815
|
-
const universal =
|
|
61192
|
+
const universal = join23(universalSkillsDir(), skill.name);
|
|
60816
61193
|
writeSkillDir(skill, universal);
|
|
60817
61194
|
paths.push(universal);
|
|
60818
61195
|
for (const dir of linkDirs) {
|
|
60819
|
-
const linkPath =
|
|
61196
|
+
const linkPath = join23(dir, skill.name);
|
|
60820
61197
|
linkSkillDir(linkPath, universal);
|
|
60821
61198
|
paths.push(linkPath);
|
|
60822
61199
|
}
|
|
@@ -60827,7 +61204,7 @@ function installBundledSkills(agentIDs) {
|
|
|
60827
61204
|
agents: [...new Set([...previous?.agents ?? [], ...agents])],
|
|
60828
61205
|
installedAt: Date.now()
|
|
60829
61206
|
});
|
|
60830
|
-
rmSync5(
|
|
61207
|
+
rmSync5(join23(getConfigDir(), LEGACY_CACHE_FILENAME), { force: true });
|
|
60831
61208
|
logger.info("skill", `Installed bundled skills v${VERSION} for ${agents.join(", ")}`);
|
|
60832
61209
|
return { success: true, version: VERSION, paths };
|
|
60833
61210
|
} catch (err) {
|
|
@@ -60849,13 +61226,13 @@ function removeSkills() {
|
|
|
60849
61226
|
const removed = [];
|
|
60850
61227
|
for (const dir of dirs) {
|
|
60851
61228
|
for (const name of names) {
|
|
60852
|
-
const path =
|
|
61229
|
+
const path = join23(dir, name);
|
|
60853
61230
|
if (removeSkillDir(path))
|
|
60854
61231
|
removed.push(path);
|
|
60855
61232
|
}
|
|
60856
61233
|
}
|
|
60857
61234
|
clearSkillInstallState();
|
|
60858
|
-
rmSync5(
|
|
61235
|
+
rmSync5(join23(getConfigDir(), LEGACY_CACHE_FILENAME), { force: true });
|
|
60859
61236
|
return removed;
|
|
60860
61237
|
}
|
|
60861
61238
|
function printPaths(paths) {
|
|
@@ -61210,17 +61587,17 @@ var init_sources = __esm(() => {
|
|
|
61210
61587
|
// src/telemetry/settings.ts
|
|
61211
61588
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
61212
61589
|
import {
|
|
61213
|
-
existsSync as
|
|
61590
|
+
existsSync as existsSync21,
|
|
61214
61591
|
lstatSync as lstatSync3,
|
|
61215
|
-
mkdirSync as
|
|
61216
|
-
readFileSync as
|
|
61217
|
-
renameSync as
|
|
61592
|
+
mkdirSync as mkdirSync13,
|
|
61593
|
+
readFileSync as readFileSync21,
|
|
61594
|
+
renameSync as renameSync6,
|
|
61218
61595
|
unlinkSync as unlinkSync4,
|
|
61219
|
-
writeFileSync as
|
|
61596
|
+
writeFileSync as writeFileSync14
|
|
61220
61597
|
} from "node:fs";
|
|
61221
|
-
import { join as
|
|
61598
|
+
import { join as join24 } from "node:path";
|
|
61222
61599
|
function getTelemetrySettingsPath() {
|
|
61223
|
-
return
|
|
61600
|
+
return join24(getConfigDir(), TELEMETRY_SETTINGS_FILENAME);
|
|
61224
61601
|
}
|
|
61225
61602
|
function loadTelemetrySettings() {
|
|
61226
61603
|
return readTelemetrySettings().settings;
|
|
@@ -61288,7 +61665,7 @@ function readTelemetrySettings() {
|
|
|
61288
61665
|
}
|
|
61289
61666
|
let content;
|
|
61290
61667
|
try {
|
|
61291
|
-
content =
|
|
61668
|
+
content = readFileSync21(path, "utf-8");
|
|
61292
61669
|
} catch {
|
|
61293
61670
|
return { status: "error", settings: disabledTelemetrySettings() };
|
|
61294
61671
|
}
|
|
@@ -61320,14 +61697,14 @@ function writeTelemetrySettings(settings) {
|
|
|
61320
61697
|
const dir = getConfigDir();
|
|
61321
61698
|
const temporaryPath = `${path}.${process.pid}.${randomUUID4()}.tmp`;
|
|
61322
61699
|
try {
|
|
61323
|
-
if (!
|
|
61324
|
-
|
|
61325
|
-
|
|
61700
|
+
if (!existsSync21(dir))
|
|
61701
|
+
mkdirSync13(dir, { recursive: true, mode: 448 });
|
|
61702
|
+
writeFileSync14(temporaryPath, `${JSON.stringify(settings, null, 2)}
|
|
61326
61703
|
`, {
|
|
61327
61704
|
flag: "wx",
|
|
61328
61705
|
mode: 384
|
|
61329
61706
|
});
|
|
61330
|
-
|
|
61707
|
+
renameSync6(temporaryPath, path);
|
|
61331
61708
|
return true;
|
|
61332
61709
|
} catch {
|
|
61333
61710
|
try {
|
|
@@ -61708,7 +62085,7 @@ var init_antigravity = __esm(() => {
|
|
|
61708
62085
|
});
|
|
61709
62086
|
|
|
61710
62087
|
// src/mcp/providers/claude.ts
|
|
61711
|
-
import { join as
|
|
62088
|
+
import { join as join25 } from "node:path";
|
|
61712
62089
|
var ClaudeProvider = () => createJSONProvider({
|
|
61713
62090
|
providerName: "Claude Code",
|
|
61714
62091
|
providerID: "claude",
|
|
@@ -61718,24 +62095,24 @@ var ClaudeProvider = () => createJSONProvider({
|
|
|
61718
62095
|
globalPath: "~/.claude.json",
|
|
61719
62096
|
topKey: "mcpServers",
|
|
61720
62097
|
buildServer: ({ url, headers }) => ({ type: "http", url, headers, alwaysLoad: true }),
|
|
61721
|
-
localConfigPath: (cwd) =>
|
|
62098
|
+
localConfigPath: (cwd) => join25(cwd, ".mcp.json")
|
|
61722
62099
|
});
|
|
61723
62100
|
var init_claude = __esm(() => {
|
|
61724
62101
|
init_base();
|
|
61725
62102
|
});
|
|
61726
62103
|
|
|
61727
62104
|
// src/mcp/providers/claude-desktop.ts
|
|
61728
|
-
import { join as
|
|
62105
|
+
import { join as join26 } from "node:path";
|
|
61729
62106
|
function configPath() {
|
|
61730
|
-
return
|
|
62107
|
+
return join26(appSupportDir(), "Claude", "claude_desktop_config.json");
|
|
61731
62108
|
}
|
|
61732
62109
|
var ClaudeDesktopProvider = () => ({
|
|
61733
62110
|
name: () => "Claude Desktop",
|
|
61734
62111
|
id: () => "claude-desktop",
|
|
61735
62112
|
supportsLocal: () => false,
|
|
61736
62113
|
priority: () => 2,
|
|
61737
|
-
detectPaths: () => [
|
|
61738
|
-
isInstalled: () => isInstalled([
|
|
62114
|
+
detectPaths: () => [join26(appSupportDir(), "Claude")],
|
|
62115
|
+
isInstalled: () => isInstalled([join26(appSupportDir(), "Claude")]),
|
|
61739
62116
|
globalConfigPath: () => configPath(),
|
|
61740
62117
|
isConfigured: () => isJSONKeyConfigured(configPath(), "mcpServers"),
|
|
61741
62118
|
install(cfg, global2) {
|
|
@@ -61762,14 +62139,14 @@ var init_claude_desktop = __esm(() => {
|
|
|
61762
62139
|
});
|
|
61763
62140
|
|
|
61764
62141
|
// src/mcp/providers/cline.ts
|
|
61765
|
-
import { join as
|
|
61766
|
-
var extensionDir = () =>
|
|
62142
|
+
import { join as join27 } from "node:path";
|
|
62143
|
+
var extensionDir = () => join27(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
|
|
61767
62144
|
providerName: "Cline",
|
|
61768
62145
|
providerID: "cline",
|
|
61769
62146
|
local: false,
|
|
61770
62147
|
priorityValue: 11,
|
|
61771
62148
|
paths: [extensionDir()],
|
|
61772
|
-
globalPath:
|
|
62149
|
+
globalPath: join27(extensionDir(), "settings", "cline_mcp_settings.json"),
|
|
61773
62150
|
topKey: "mcpServers",
|
|
61774
62151
|
buildServer: ({ url, headers }) => ({
|
|
61775
62152
|
url,
|
|
@@ -61784,7 +62161,7 @@ var init_cline = __esm(() => {
|
|
|
61784
62161
|
});
|
|
61785
62162
|
|
|
61786
62163
|
// src/mcp/providers/cline-cli.ts
|
|
61787
|
-
import { join as
|
|
62164
|
+
import { join as join28 } from "node:path";
|
|
61788
62165
|
function clineDir() {
|
|
61789
62166
|
return process.env.CLINE_DIR ?? expandHome("~/.cline");
|
|
61790
62167
|
}
|
|
@@ -61794,7 +62171,7 @@ var ClineCliProvider = () => createJSONProvider({
|
|
|
61794
62171
|
local: false,
|
|
61795
62172
|
priorityValue: 12,
|
|
61796
62173
|
paths: [clineDir()],
|
|
61797
|
-
globalPath:
|
|
62174
|
+
globalPath: join28(clineDir(), "data", "settings", "cline_mcp_settings.json"),
|
|
61798
62175
|
topKey: "mcpServers",
|
|
61799
62176
|
buildServer: ({ url, headers }) => ({
|
|
61800
62177
|
url,
|
|
@@ -61809,20 +62186,20 @@ var init_cline_cli = __esm(() => {
|
|
|
61809
62186
|
});
|
|
61810
62187
|
|
|
61811
62188
|
// src/mcp/providers/codex.ts
|
|
61812
|
-
import { existsSync as
|
|
61813
|
-
import { dirname as dirname11, join as
|
|
62189
|
+
import { existsSync as existsSync22, readFileSync as readFileSync22 } from "node:fs";
|
|
62190
|
+
import { dirname as dirname11, join as join29 } from "node:path";
|
|
61814
62191
|
function codexHome3() {
|
|
61815
62192
|
return process.env.CODEX_HOME ?? expandHome("~/.codex");
|
|
61816
62193
|
}
|
|
61817
62194
|
function getConfigPath2(global2) {
|
|
61818
62195
|
if (global2)
|
|
61819
|
-
return
|
|
61820
|
-
return
|
|
62196
|
+
return join29(codexHome3(), "config.toml");
|
|
62197
|
+
return join29(process.cwd(), ".codex", "config.toml");
|
|
61821
62198
|
}
|
|
61822
62199
|
function readTOML(path) {
|
|
61823
|
-
if (!
|
|
62200
|
+
if (!existsSync22(path))
|
|
61824
62201
|
return "";
|
|
61825
|
-
return
|
|
62202
|
+
return readFileSync22(path, "utf-8");
|
|
61826
62203
|
}
|
|
61827
62204
|
function writeTOML(path, content) {
|
|
61828
62205
|
writeSecureFile(path, content);
|
|
@@ -61897,17 +62274,17 @@ function projectConfigPaths() {
|
|
|
61897
62274
|
const chain = [];
|
|
61898
62275
|
for (let dir = cwd;; ) {
|
|
61899
62276
|
chain.push(dir);
|
|
61900
|
-
if (
|
|
62277
|
+
if (existsSync22(join29(dir, ".git")))
|
|
61901
62278
|
break;
|
|
61902
62279
|
const parent = dirname11(dir);
|
|
61903
62280
|
if (parent === dir)
|
|
61904
|
-
return [
|
|
62281
|
+
return [join29(cwd, ".codex", "config.toml")];
|
|
61905
62282
|
dir = parent;
|
|
61906
62283
|
}
|
|
61907
|
-
return chain.reverse().map((dir) =>
|
|
62284
|
+
return chain.reverse().map((dir) => join29(dir, ".codex", "config.toml"));
|
|
61908
62285
|
}
|
|
61909
62286
|
function pruneLegacyRemoteEntry(path) {
|
|
61910
|
-
if (!
|
|
62287
|
+
if (!existsSync22(path))
|
|
61911
62288
|
return;
|
|
61912
62289
|
const content = readTOML(path);
|
|
61913
62290
|
if (!hasRemoteHTTPForm(content))
|
|
@@ -61921,9 +62298,9 @@ var REMOTE_HTTP_KEY, CodexProvider = () => ({
|
|
|
61921
62298
|
priority: () => 8,
|
|
61922
62299
|
detectPaths: () => ["~/.codex"],
|
|
61923
62300
|
isInstalled: () => isInstalled(["~/.codex"]),
|
|
61924
|
-
globalConfigPath: () =>
|
|
62301
|
+
globalConfigPath: () => join29(codexHome3(), "config.toml"),
|
|
61925
62302
|
isConfigured: () => {
|
|
61926
|
-
const content = readTOML(
|
|
62303
|
+
const content = readTOML(join29(codexHome3(), "config.toml"));
|
|
61927
62304
|
return content.includes("[mcp_servers.dosu]");
|
|
61928
62305
|
},
|
|
61929
62306
|
install(cfg, global2) {
|
|
@@ -61954,10 +62331,10 @@ var init_codex = __esm(() => {
|
|
|
61954
62331
|
});
|
|
61955
62332
|
|
|
61956
62333
|
// src/mcp/providers/copilot.ts
|
|
61957
|
-
import { join as
|
|
62334
|
+
import { join as join30 } from "node:path";
|
|
61958
62335
|
function globalPath() {
|
|
61959
62336
|
if (process.env.XDG_CONFIG_HOME) {
|
|
61960
|
-
return
|
|
62337
|
+
return join30(process.env.XDG_CONFIG_HOME, "mcp-config.json");
|
|
61961
62338
|
}
|
|
61962
62339
|
return expandHome("~/.copilot/mcp-config.json");
|
|
61963
62340
|
}
|
|
@@ -61981,7 +62358,7 @@ var CopilotProvider = () => ({
|
|
|
61981
62358
|
};
|
|
61982
62359
|
installJSONServer(globalPath(), "mcpServers", server);
|
|
61983
62360
|
} else {
|
|
61984
|
-
const configPath =
|
|
62361
|
+
const configPath = join30(process.cwd(), ".vscode", "mcp.json");
|
|
61985
62362
|
const server = {
|
|
61986
62363
|
type: "http",
|
|
61987
62364
|
url,
|
|
@@ -61994,7 +62371,7 @@ var CopilotProvider = () => ({
|
|
|
61994
62371
|
if (global2) {
|
|
61995
62372
|
removeJSONServer(globalPath(), "mcpServers");
|
|
61996
62373
|
} else {
|
|
61997
|
-
const configPath =
|
|
62374
|
+
const configPath = join30(process.cwd(), ".vscode", "mcp.json");
|
|
61998
62375
|
removeJSONServer(configPath, "servers");
|
|
61999
62376
|
}
|
|
62000
62377
|
}
|
|
@@ -62005,7 +62382,7 @@ var init_copilot = __esm(() => {
|
|
|
62005
62382
|
});
|
|
62006
62383
|
|
|
62007
62384
|
// src/mcp/providers/cursor.ts
|
|
62008
|
-
import { join as
|
|
62385
|
+
import { join as join31 } from "node:path";
|
|
62009
62386
|
var CursorProvider = () => createJSONProvider({
|
|
62010
62387
|
providerName: "Cursor",
|
|
62011
62388
|
providerID: "cursor",
|
|
@@ -62018,14 +62395,14 @@ var CursorProvider = () => createJSONProvider({
|
|
|
62018
62395
|
url,
|
|
62019
62396
|
headers
|
|
62020
62397
|
}),
|
|
62021
|
-
localConfigPath: (cwd) =>
|
|
62398
|
+
localConfigPath: (cwd) => join31(cwd, ".cursor", "mcp.json")
|
|
62022
62399
|
});
|
|
62023
62400
|
var init_cursor = __esm(() => {
|
|
62024
62401
|
init_base();
|
|
62025
62402
|
});
|
|
62026
62403
|
|
|
62027
62404
|
// src/mcp/providers/factory.ts
|
|
62028
|
-
import { join as
|
|
62405
|
+
import { join as join32 } from "node:path";
|
|
62029
62406
|
var FactoryProvider = () => createJSONProvider({
|
|
62030
62407
|
providerName: "Factory",
|
|
62031
62408
|
providerID: "factory",
|
|
@@ -62034,14 +62411,14 @@ var FactoryProvider = () => createJSONProvider({
|
|
|
62034
62411
|
paths: ["~/.factory"],
|
|
62035
62412
|
globalPath: "~/.factory/mcp.json",
|
|
62036
62413
|
topKey: "mcpServers",
|
|
62037
|
-
localConfigPath: (cwd) =>
|
|
62414
|
+
localConfigPath: (cwd) => join32(cwd, ".factory", "mcp.json")
|
|
62038
62415
|
});
|
|
62039
62416
|
var init_factory = __esm(() => {
|
|
62040
62417
|
init_base();
|
|
62041
62418
|
});
|
|
62042
62419
|
|
|
62043
62420
|
// src/mcp/providers/gemini.ts
|
|
62044
|
-
import { join as
|
|
62421
|
+
import { join as join33 } from "node:path";
|
|
62045
62422
|
var GeminiProvider = () => createJSONProvider({
|
|
62046
62423
|
providerName: "Gemini CLI",
|
|
62047
62424
|
providerID: "gemini",
|
|
@@ -62050,7 +62427,7 @@ var GeminiProvider = () => createJSONProvider({
|
|
|
62050
62427
|
paths: ["~/.gemini"],
|
|
62051
62428
|
globalPath: "~/.gemini/settings.json",
|
|
62052
62429
|
topKey: "mcpServers",
|
|
62053
|
-
localConfigPath: (cwd) =>
|
|
62430
|
+
localConfigPath: (cwd) => join33(cwd, ".gemini", "settings.json")
|
|
62054
62431
|
});
|
|
62055
62432
|
var init_gemini = __esm(() => {
|
|
62056
62433
|
init_base();
|
|
@@ -62092,14 +62469,14 @@ var init_manual = __esm(() => {
|
|
|
62092
62469
|
});
|
|
62093
62470
|
|
|
62094
62471
|
// src/mcp/providers/mcporter.ts
|
|
62095
|
-
import { existsSync as
|
|
62096
|
-
import { join as
|
|
62472
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
62473
|
+
import { join as join34 } from "node:path";
|
|
62097
62474
|
function resolveGlobalConfigPath() {
|
|
62098
62475
|
const jsonPath = expandHome("~/.mcporter/mcporter.json");
|
|
62099
|
-
if (
|
|
62476
|
+
if (existsSync23(jsonPath))
|
|
62100
62477
|
return jsonPath;
|
|
62101
62478
|
const jsoncPath = expandHome("~/.mcporter/mcporter.jsonc");
|
|
62102
|
-
if (
|
|
62479
|
+
if (existsSync23(jsoncPath))
|
|
62103
62480
|
return jsoncPath;
|
|
62104
62481
|
return jsonPath;
|
|
62105
62482
|
}
|
|
@@ -62113,7 +62490,7 @@ var MCPorterProvider = () => ({
|
|
|
62113
62490
|
globalConfigPath: () => resolveGlobalConfigPath(),
|
|
62114
62491
|
isConfigured: () => isJSONKeyConfigured(resolveGlobalConfigPath(), "mcpServers"),
|
|
62115
62492
|
install(cfg, global2) {
|
|
62116
|
-
const configPath = global2 ? resolveGlobalConfigPath() :
|
|
62493
|
+
const configPath = global2 ? resolveGlobalConfigPath() : join34(process.cwd(), "config", "mcporter.json");
|
|
62117
62494
|
const server = {
|
|
62118
62495
|
type: "http",
|
|
62119
62496
|
url: mcpEndpoint(cfg),
|
|
@@ -62122,7 +62499,7 @@ var MCPorterProvider = () => ({
|
|
|
62122
62499
|
installJSONServer(configPath, "mcpServers", server);
|
|
62123
62500
|
},
|
|
62124
62501
|
remove(global2) {
|
|
62125
|
-
const configPath = global2 ? resolveGlobalConfigPath() :
|
|
62502
|
+
const configPath = global2 ? resolveGlobalConfigPath() : join34(process.cwd(), "config", "mcporter.json");
|
|
62126
62503
|
removeJSONServer(configPath, "mcpServers");
|
|
62127
62504
|
}
|
|
62128
62505
|
});
|
|
@@ -62132,7 +62509,7 @@ var init_mcporter = __esm(() => {
|
|
|
62132
62509
|
});
|
|
62133
62510
|
|
|
62134
62511
|
// src/mcp/providers/opencode.ts
|
|
62135
|
-
import { join as
|
|
62512
|
+
import { join as join35 } from "node:path";
|
|
62136
62513
|
var OpenCodeProvider = () => createJSONProvider({
|
|
62137
62514
|
providerName: "OpenCode",
|
|
62138
62515
|
providerID: "opencode",
|
|
@@ -62147,23 +62524,23 @@ var OpenCodeProvider = () => createJSONProvider({
|
|
|
62147
62524
|
enabled: true,
|
|
62148
62525
|
headers
|
|
62149
62526
|
}),
|
|
62150
|
-
localConfigPath: (cwd) =>
|
|
62527
|
+
localConfigPath: (cwd) => join35(cwd, "opencode.json")
|
|
62151
62528
|
});
|
|
62152
62529
|
var init_opencode = __esm(() => {
|
|
62153
62530
|
init_base();
|
|
62154
62531
|
});
|
|
62155
62532
|
|
|
62156
62533
|
// src/mcp/providers/vscode.ts
|
|
62157
|
-
import { join as
|
|
62534
|
+
import { join as join36 } from "node:path";
|
|
62158
62535
|
var VSCodeProvider = () => createJSONProvider({
|
|
62159
62536
|
providerName: "VS Code",
|
|
62160
62537
|
providerID: "vscode",
|
|
62161
62538
|
local: true,
|
|
62162
62539
|
priorityValue: 6,
|
|
62163
|
-
paths: [
|
|
62164
|
-
globalPath:
|
|
62540
|
+
paths: [join36(appSupportDir(), "Code")],
|
|
62541
|
+
globalPath: join36(appSupportDir(), "Code", "User", "mcp.json"),
|
|
62165
62542
|
topKey: "servers",
|
|
62166
|
-
localConfigPath: (cwd) =>
|
|
62543
|
+
localConfigPath: (cwd) => join36(cwd, ".vscode", "mcp.json")
|
|
62167
62544
|
});
|
|
62168
62545
|
var init_vscode = __esm(() => {
|
|
62169
62546
|
init_detect();
|
|
@@ -62171,15 +62548,15 @@ var init_vscode = __esm(() => {
|
|
|
62171
62548
|
});
|
|
62172
62549
|
|
|
62173
62550
|
// src/mcp/providers/windsurf.ts
|
|
62174
|
-
import { homedir as
|
|
62175
|
-
import { join as
|
|
62551
|
+
import { homedir as homedir8 } from "node:os";
|
|
62552
|
+
import { join as join37 } from "node:path";
|
|
62176
62553
|
var WindsurfProvider = () => createJSONProvider({
|
|
62177
62554
|
providerName: "Windsurf",
|
|
62178
62555
|
providerID: "windsurf",
|
|
62179
62556
|
local: false,
|
|
62180
62557
|
priorityValue: 9,
|
|
62181
|
-
paths: [
|
|
62182
|
-
globalPath:
|
|
62558
|
+
paths: [join37(homedir8(), ".codeium", "windsurf")],
|
|
62559
|
+
globalPath: join37(homedir8(), ".codeium", "windsurf", "mcp_config.json"),
|
|
62183
62560
|
topKey: "mcpServers"
|
|
62184
62561
|
});
|
|
62185
62562
|
var init_windsurf = __esm(() => {
|
|
@@ -62188,26 +62565,26 @@ var init_windsurf = __esm(() => {
|
|
|
62188
62565
|
|
|
62189
62566
|
// src/mcp/providers/zed.ts
|
|
62190
62567
|
import { rmSync as rmSync6 } from "node:fs";
|
|
62191
|
-
import { homedir as
|
|
62192
|
-
import { join as
|
|
62568
|
+
import { homedir as homedir9, platform as platform3 } from "node:os";
|
|
62569
|
+
import { join as join38 } from "node:path";
|
|
62193
62570
|
function zedConfigDir() {
|
|
62194
62571
|
const os = platform3();
|
|
62195
62572
|
if (os === "win32")
|
|
62196
|
-
return
|
|
62573
|
+
return join38(appSupportDir(), "Zed");
|
|
62197
62574
|
if (os === "darwin")
|
|
62198
|
-
return
|
|
62199
|
-
return
|
|
62575
|
+
return join38(homedir9(), ".config", "zed");
|
|
62576
|
+
return join38(appSupportDir(), "zed");
|
|
62200
62577
|
}
|
|
62201
62578
|
function zedDataDir() {
|
|
62202
62579
|
const os = platform3();
|
|
62203
62580
|
if (os === "darwin")
|
|
62204
|
-
return
|
|
62581
|
+
return join38(appSupportDir(), "Zed");
|
|
62205
62582
|
if (os === "win32")
|
|
62206
|
-
return
|
|
62207
|
-
return
|
|
62583
|
+
return join38(process.env.LOCALAPPDATA ?? "", "Zed");
|
|
62584
|
+
return join38(process.env.XDG_DATA_HOME ?? join38(homedir9(), ".local", "share"), "zed");
|
|
62208
62585
|
}
|
|
62209
62586
|
function legacyDarwinSettingsPath() {
|
|
62210
|
-
return platform3() === "darwin" ?
|
|
62587
|
+
return platform3() === "darwin" ? join38(appSupportDir(), "Zed", "settings.json") : null;
|
|
62211
62588
|
}
|
|
62212
62589
|
function removeLegacyDosuEntry(path) {
|
|
62213
62590
|
let cfg;
|
|
@@ -62233,10 +62610,10 @@ var ZedProvider = (legacyPath = legacyDarwinSettingsPath()) => {
|
|
|
62233
62610
|
local: true,
|
|
62234
62611
|
priorityValue: 10,
|
|
62235
62612
|
paths: [zedConfigDir(), zedDataDir()],
|
|
62236
|
-
globalPath:
|
|
62613
|
+
globalPath: join38(zedConfigDir(), "settings.json"),
|
|
62237
62614
|
topKey: "context_servers",
|
|
62238
62615
|
buildServer: ({ url, headers }) => ({ url, headers }),
|
|
62239
|
-
localConfigPath: (cwd) =>
|
|
62616
|
+
localConfigPath: (cwd) => join38(cwd, ".zed", "settings.json")
|
|
62240
62617
|
});
|
|
62241
62618
|
if (!legacyPath)
|
|
62242
62619
|
return provider;
|
|
@@ -62344,29 +62721,29 @@ var init_refresh = __esm(() => {
|
|
|
62344
62721
|
import { spawn as spawn3 } from "node:child_process";
|
|
62345
62722
|
import {
|
|
62346
62723
|
closeSync as closeSync6,
|
|
62347
|
-
existsSync as
|
|
62348
|
-
mkdirSync as
|
|
62724
|
+
existsSync as existsSync24,
|
|
62725
|
+
mkdirSync as mkdirSync14,
|
|
62349
62726
|
openSync as openSync6,
|
|
62350
|
-
readFileSync as
|
|
62727
|
+
readFileSync as readFileSync23,
|
|
62351
62728
|
rmSync as rmSync7,
|
|
62352
62729
|
statSync as statSync8,
|
|
62353
|
-
writeFileSync as
|
|
62730
|
+
writeFileSync as writeFileSync15,
|
|
62354
62731
|
writeSync
|
|
62355
62732
|
} from "node:fs";
|
|
62356
|
-
import { homedir as
|
|
62357
|
-
import { join as
|
|
62733
|
+
import { homedir as homedir10 } from "node:os";
|
|
62734
|
+
import { join as join39 } from "node:path";
|
|
62358
62735
|
function statePath() {
|
|
62359
|
-
return
|
|
62736
|
+
return join39(getConfigDir(), STATE_FILENAME2);
|
|
62360
62737
|
}
|
|
62361
62738
|
function lockPath2() {
|
|
62362
|
-
return
|
|
62739
|
+
return join39(getConfigDir(), LOCK_FILENAME2);
|
|
62363
62740
|
}
|
|
62364
62741
|
function isValidVersion(value) {
|
|
62365
62742
|
return typeof value === "string" && VERSION_PATTERN.test(value);
|
|
62366
62743
|
}
|
|
62367
62744
|
function readState() {
|
|
62368
62745
|
try {
|
|
62369
|
-
const raw = JSON.parse(
|
|
62746
|
+
const raw = JSON.parse(readFileSync23(statePath(), "utf-8"));
|
|
62370
62747
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
62371
62748
|
return {};
|
|
62372
62749
|
const data = raw;
|
|
@@ -62385,9 +62762,9 @@ function readState() {
|
|
|
62385
62762
|
function writeState(state) {
|
|
62386
62763
|
try {
|
|
62387
62764
|
const dir = getConfigDir();
|
|
62388
|
-
if (!
|
|
62389
|
-
|
|
62390
|
-
|
|
62765
|
+
if (!existsSync24(dir))
|
|
62766
|
+
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
62767
|
+
writeFileSync15(statePath(), `${JSON.stringify(state, null, 2)}
|
|
62391
62768
|
`, { mode: 384 });
|
|
62392
62769
|
return true;
|
|
62393
62770
|
} catch {
|
|
@@ -62440,7 +62817,7 @@ function lockIsFresh(now) {
|
|
|
62440
62817
|
}
|
|
62441
62818
|
function claimLock(version, now) {
|
|
62442
62819
|
try {
|
|
62443
|
-
|
|
62820
|
+
mkdirSync14(getConfigDir(), { recursive: true, mode: 448 });
|
|
62444
62821
|
if (!lockIsFresh(now))
|
|
62445
62822
|
rmSync7(lockPath2(), { force: true });
|
|
62446
62823
|
const fd = openSync6(lockPath2(), "wx", 384);
|
|
@@ -62461,7 +62838,7 @@ function releaseLock() {
|
|
|
62461
62838
|
}
|
|
62462
62839
|
function readLockVersion() {
|
|
62463
62840
|
try {
|
|
62464
|
-
const version =
|
|
62841
|
+
const version = readFileSync23(lockPath2(), "utf-8").trim();
|
|
62465
62842
|
return isValidVersion(version) ? version : undefined;
|
|
62466
62843
|
} catch {
|
|
62467
62844
|
return;
|
|
@@ -62488,7 +62865,7 @@ function startAutoUpdate(version, options = {}) {
|
|
|
62488
62865
|
return claim === "held" ? "in_progress" : "unavailable";
|
|
62489
62866
|
try {
|
|
62490
62867
|
const child = spawn3(invocation.command, invocation.args, {
|
|
62491
|
-
cwd:
|
|
62868
|
+
cwd: homedir10(),
|
|
62492
62869
|
detached: true,
|
|
62493
62870
|
stdio: "ignore",
|
|
62494
62871
|
windowsHide: true,
|
|
@@ -62535,8 +62912,8 @@ var init_auto_update = __esm(() => {
|
|
|
62535
62912
|
});
|
|
62536
62913
|
|
|
62537
62914
|
// src/version/update-check.ts
|
|
62538
|
-
import { existsSync as
|
|
62539
|
-
import { join as
|
|
62915
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
|
|
62916
|
+
import { join as join40 } from "node:path";
|
|
62540
62917
|
function isValidVersion2(value) {
|
|
62541
62918
|
return typeof value === "string" && SEMVER_PATTERN.test(value);
|
|
62542
62919
|
}
|
|
@@ -62558,14 +62935,14 @@ function isNewerVersion(latest, current) {
|
|
|
62558
62935
|
return false;
|
|
62559
62936
|
}
|
|
62560
62937
|
function getCachePath2() {
|
|
62561
|
-
return
|
|
62938
|
+
return join40(getConfigDir(), CACHE_FILENAME3);
|
|
62562
62939
|
}
|
|
62563
62940
|
function readCache() {
|
|
62564
62941
|
try {
|
|
62565
62942
|
const path = getCachePath2();
|
|
62566
|
-
if (!
|
|
62943
|
+
if (!existsSync25(path))
|
|
62567
62944
|
return null;
|
|
62568
|
-
const data = JSON.parse(
|
|
62945
|
+
const data = JSON.parse(readFileSync24(path, "utf-8"));
|
|
62569
62946
|
if (typeof data.lastCheck === "number" && isValidVersion2(data.latestVersion)) {
|
|
62570
62947
|
return data;
|
|
62571
62948
|
}
|
|
@@ -62577,10 +62954,10 @@ function readCache() {
|
|
|
62577
62954
|
function writeCache(cache) {
|
|
62578
62955
|
try {
|
|
62579
62956
|
const dir = getConfigDir();
|
|
62580
|
-
if (!
|
|
62581
|
-
|
|
62957
|
+
if (!existsSync25(dir)) {
|
|
62958
|
+
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
62582
62959
|
}
|
|
62583
|
-
|
|
62960
|
+
writeFileSync16(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
62584
62961
|
} catch {}
|
|
62585
62962
|
}
|
|
62586
62963
|
async function fetchLatestVersion() {
|
|
@@ -62708,8 +63085,8 @@ var init_update_check = __esm(() => {
|
|
|
62708
63085
|
});
|
|
62709
63086
|
|
|
62710
63087
|
// src/version/mcp-refresh-check.ts
|
|
62711
|
-
import { existsSync as
|
|
62712
|
-
import { join as
|
|
63088
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
|
|
63089
|
+
import { join as join41 } from "node:path";
|
|
62713
63090
|
function needsMcpRefresh(previous, current) {
|
|
62714
63091
|
if (previous === null)
|
|
62715
63092
|
return true;
|
|
@@ -62719,14 +63096,14 @@ function needsMcpRefresh(previous, current) {
|
|
|
62719
63096
|
return MCP_FORMAT_CHANGES.some((change) => isNewerVersion(change, older) && !isNewerVersion(change, newer));
|
|
62720
63097
|
}
|
|
62721
63098
|
function getCachePath3() {
|
|
62722
|
-
return
|
|
63099
|
+
return join41(getConfigDir(), CACHE_FILENAME4);
|
|
62723
63100
|
}
|
|
62724
63101
|
function readMcpRefreshCache() {
|
|
62725
63102
|
try {
|
|
62726
63103
|
const path = getCachePath3();
|
|
62727
|
-
if (!
|
|
63104
|
+
if (!existsSync26(path))
|
|
62728
63105
|
return null;
|
|
62729
|
-
const data = JSON.parse(
|
|
63106
|
+
const data = JSON.parse(readFileSync25(path, "utf-8"));
|
|
62730
63107
|
if (typeof data?.version === "string")
|
|
62731
63108
|
return { version: data.version };
|
|
62732
63109
|
return null;
|
|
@@ -62737,10 +63114,10 @@ function readMcpRefreshCache() {
|
|
|
62737
63114
|
function writeMcpRefreshCache(cache) {
|
|
62738
63115
|
try {
|
|
62739
63116
|
const dir = getConfigDir();
|
|
62740
|
-
if (!
|
|
62741
|
-
|
|
63117
|
+
if (!existsSync26(dir)) {
|
|
63118
|
+
mkdirSync16(dir, { recursive: true, mode: 448 });
|
|
62742
63119
|
}
|
|
62743
|
-
|
|
63120
|
+
writeFileSync17(getCachePath3(), JSON.stringify(cache), { mode: 384 });
|
|
62744
63121
|
} catch {}
|
|
62745
63122
|
}
|
|
62746
63123
|
function canRefreshMcp(cfg) {
|
|
@@ -62888,15 +63265,15 @@ function createLogFollower(path, emit) {
|
|
|
62888
63265
|
var init_follow = () => {};
|
|
62889
63266
|
|
|
62890
63267
|
// src/sessions/session-title.ts
|
|
62891
|
-
import { existsSync as
|
|
62892
|
-
import { homedir as
|
|
62893
|
-
import { join as
|
|
63268
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync26, renameSync as renameSync7, statSync as statSync10, writeFileSync as writeFileSync18 } from "node:fs";
|
|
63269
|
+
import { homedir as homedir11 } from "node:os";
|
|
63270
|
+
import { join as join42 } from "node:path";
|
|
62894
63271
|
function cachePath2(configDir) {
|
|
62895
|
-
return
|
|
63272
|
+
return join42(configDir, CACHE_FILENAME5);
|
|
62896
63273
|
}
|
|
62897
63274
|
function loadCacheFile2(configDir) {
|
|
62898
63275
|
try {
|
|
62899
|
-
const raw = JSON.parse(
|
|
63276
|
+
const raw = JSON.parse(readFileSync26(cachePath2(configDir), "utf-8"));
|
|
62900
63277
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION2 || typeof raw.entries !== "object")
|
|
62901
63278
|
return {};
|
|
62902
63279
|
return raw.entries;
|
|
@@ -62906,13 +63283,13 @@ function loadCacheFile2(configDir) {
|
|
|
62906
63283
|
}
|
|
62907
63284
|
function saveCacheFile2(configDir, entries) {
|
|
62908
63285
|
try {
|
|
62909
|
-
if (!
|
|
62910
|
-
|
|
63286
|
+
if (!existsSync27(configDir))
|
|
63287
|
+
mkdirSync17(configDir, { recursive: true, mode: 448 });
|
|
62911
63288
|
const path = cachePath2(configDir);
|
|
62912
63289
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
62913
63290
|
const file = { schema_version: CACHE_SCHEMA_VERSION2, entries };
|
|
62914
|
-
|
|
62915
|
-
|
|
63291
|
+
writeFileSync18(tmp, JSON.stringify(file), { mode: 384 });
|
|
63292
|
+
renameSync7(tmp, path);
|
|
62916
63293
|
} catch {}
|
|
62917
63294
|
}
|
|
62918
63295
|
function extractUserQuery(text) {
|
|
@@ -62944,15 +63321,15 @@ function claudeSummaryFromHead(text) {
|
|
|
62944
63321
|
}
|
|
62945
63322
|
return null;
|
|
62946
63323
|
}
|
|
62947
|
-
function reconstructSession(harness, id, slug, home =
|
|
63324
|
+
function reconstructSession(harness, id, slug, home = homedir11(), exists = existsSync27) {
|
|
62948
63325
|
if (!slug)
|
|
62949
63326
|
return null;
|
|
62950
63327
|
const candidates = [];
|
|
62951
63328
|
if (harness === "claude") {
|
|
62952
|
-
candidates.push(
|
|
63329
|
+
candidates.push(join42(home, ".claude", "projects", slug, `${id}.jsonl`));
|
|
62953
63330
|
} else if (harness === "cursor") {
|
|
62954
|
-
const project =
|
|
62955
|
-
candidates.push(
|
|
63331
|
+
const project = join42(home, ".cursor", "projects", slug);
|
|
63332
|
+
candidates.push(join42(project, "agent-transcripts", id, `${id}.jsonl`), join42(project, "agent-transcripts", `${id}.jsonl`));
|
|
62956
63333
|
} else {
|
|
62957
63334
|
return null;
|
|
62958
63335
|
}
|
|
@@ -62964,7 +63341,7 @@ function reconstructSession(harness, id, slug, home = homedir12(), exists = exis
|
|
|
62964
63341
|
}
|
|
62965
63342
|
function readHead2(path) {
|
|
62966
63343
|
try {
|
|
62967
|
-
return
|
|
63344
|
+
return readFileSync26(path, "utf-8").slice(0, 128 * 1024);
|
|
62968
63345
|
} catch {
|
|
62969
63346
|
return null;
|
|
62970
63347
|
}
|
|
@@ -63044,8 +63421,8 @@ var init_alt_screen = __esm(() => {
|
|
|
63044
63421
|
});
|
|
63045
63422
|
|
|
63046
63423
|
// src/tui/activity-view.ts
|
|
63047
|
-
import { existsSync as
|
|
63048
|
-
import { basename as
|
|
63424
|
+
import { existsSync as existsSync28, readFileSync as readFileSync27 } from "node:fs";
|
|
63425
|
+
import { basename as basename6 } from "node:path";
|
|
63049
63426
|
function reduceActivityViewKey(key) {
|
|
63050
63427
|
if (key === "q" || key === ESC7 || key === CTRL_C4)
|
|
63051
63428
|
return "back";
|
|
@@ -63365,12 +63742,12 @@ function createRowNamer() {
|
|
|
63365
63742
|
names.titles[key] = t;
|
|
63366
63743
|
};
|
|
63367
63744
|
for (const s of [...backlog.queued, ...backlog.open]) {
|
|
63368
|
-
if (!
|
|
63745
|
+
if (!existsSync28(s.path))
|
|
63369
63746
|
continue;
|
|
63370
63747
|
const key = `${s.harness}/${s.id}`;
|
|
63371
63748
|
const dir = dirs.resolve(s);
|
|
63372
63749
|
if (dir)
|
|
63373
|
-
names.projects[key] =
|
|
63750
|
+
names.projects[key] = basename6(dir);
|
|
63374
63751
|
title(key, s);
|
|
63375
63752
|
resolved = true;
|
|
63376
63753
|
}
|
|
@@ -63379,7 +63756,7 @@ function createRowNamer() {
|
|
|
63379
63756
|
if (!names.projects[key]) {
|
|
63380
63757
|
const dir = dirs.cached(key) ?? (r.project ? fromSlug(r.project) : null);
|
|
63381
63758
|
if (dir)
|
|
63382
|
-
names.projects[key] =
|
|
63759
|
+
names.projects[key] = basename6(dir);
|
|
63383
63760
|
}
|
|
63384
63761
|
if (!names.titles[key]) {
|
|
63385
63762
|
const hit = titles.cached(key);
|
|
@@ -63402,7 +63779,7 @@ function createRowNamer() {
|
|
|
63402
63779
|
}
|
|
63403
63780
|
function defaultReadLog2() {
|
|
63404
63781
|
try {
|
|
63405
|
-
return
|
|
63782
|
+
return readFileSync27(logger.getLogPath(), "utf-8");
|
|
63406
63783
|
} catch {
|
|
63407
63784
|
return "";
|
|
63408
63785
|
}
|
|
@@ -63619,14 +63996,14 @@ var init_activity_view = __esm(() => {
|
|
|
63619
63996
|
});
|
|
63620
63997
|
|
|
63621
63998
|
// src/rules/installer.ts
|
|
63622
|
-
import { existsSync as
|
|
63623
|
-
import { homedir as
|
|
63624
|
-
import { dirname as dirname12, join as
|
|
63999
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync18, readFileSync as readFileSync28, unlinkSync as unlinkSync5, writeFileSync as writeFileSync19 } from "node:fs";
|
|
64000
|
+
import { homedir as homedir12 } from "node:os";
|
|
64001
|
+
import { dirname as dirname12, join as join43 } from "node:path";
|
|
63625
64002
|
function claudeConfigDir4() {
|
|
63626
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
64003
|
+
return process.env.CLAUDE_CONFIG_DIR || join43(homedir12(), ".claude");
|
|
63627
64004
|
}
|
|
63628
64005
|
function codexHome4() {
|
|
63629
|
-
return process.env.CODEX_HOME ||
|
|
64006
|
+
return process.env.CODEX_HOME || join43(homedir12(), ".codex");
|
|
63630
64007
|
}
|
|
63631
64008
|
function isRuleAgent(agent) {
|
|
63632
64009
|
return Object.hasOwn(RULE_TARGETS, agent);
|
|
@@ -63652,17 +64029,17 @@ async function fetchDosuRule(fetchImpl = globalThis.fetch) {
|
|
|
63652
64029
|
return normalizeRule(FALLBACK_DOSU_RULE);
|
|
63653
64030
|
}
|
|
63654
64031
|
function ensureParent(path) {
|
|
63655
|
-
|
|
64032
|
+
mkdirSync18(dirname12(path), { recursive: true });
|
|
63656
64033
|
}
|
|
63657
64034
|
function writeIfChanged(path, content) {
|
|
63658
|
-
if (!
|
|
64035
|
+
if (!existsSync29(path)) {
|
|
63659
64036
|
ensureParent(path);
|
|
63660
|
-
|
|
64037
|
+
writeFileSync19(path, content, "utf-8");
|
|
63661
64038
|
return "created";
|
|
63662
64039
|
}
|
|
63663
|
-
if (
|
|
64040
|
+
if (readFileSync28(path, "utf-8") === content)
|
|
63664
64041
|
return "unchanged";
|
|
63665
|
-
|
|
64042
|
+
writeFileSync19(path, content, "utf-8");
|
|
63666
64043
|
return "updated";
|
|
63667
64044
|
}
|
|
63668
64045
|
function findSection(content) {
|
|
@@ -63688,14 +64065,14 @@ function buildSection(content, lineEnding = `
|
|
|
63688
64065
|
return `${DOSU_RULE_SECTION_START}${lineEnding}${body}${lineEnding}${DOSU_RULE_SECTION_END}`;
|
|
63689
64066
|
}
|
|
63690
64067
|
function upsertSection(path, content) {
|
|
63691
|
-
if (!
|
|
64068
|
+
if (!existsSync29(path)) {
|
|
63692
64069
|
const section = buildSection(content);
|
|
63693
64070
|
ensureParent(path);
|
|
63694
|
-
|
|
64071
|
+
writeFileSync19(path, `${section}
|
|
63695
64072
|
`, "utf-8");
|
|
63696
64073
|
return "created";
|
|
63697
64074
|
}
|
|
63698
|
-
const existing =
|
|
64075
|
+
const existing = readFileSync28(path, "utf-8");
|
|
63699
64076
|
const lineEnding = lineEndingFor(existing);
|
|
63700
64077
|
const section = buildSection(content, lineEnding);
|
|
63701
64078
|
const location = findSection(existing);
|
|
@@ -63708,7 +64085,7 @@ function upsertSection(path, content) {
|
|
|
63708
64085
|
}
|
|
63709
64086
|
if (next === existing)
|
|
63710
64087
|
return "unchanged";
|
|
63711
|
-
|
|
64088
|
+
writeFileSync19(path, next, "utf-8");
|
|
63712
64089
|
return "updated";
|
|
63713
64090
|
}
|
|
63714
64091
|
function installRuleForAgent(agent, content) {
|
|
@@ -63725,13 +64102,13 @@ function removeRuleForAgent(agent) {
|
|
|
63725
64102
|
return null;
|
|
63726
64103
|
const target = RULE_TARGETS[agent];
|
|
63727
64104
|
const path = target.path();
|
|
63728
|
-
if (!
|
|
64105
|
+
if (!existsSync29(path))
|
|
63729
64106
|
return { agent, path, action: "not_found" };
|
|
63730
64107
|
if (target.kind === "file") {
|
|
63731
64108
|
unlinkSync5(path);
|
|
63732
64109
|
return { agent, path, action: "removed" };
|
|
63733
64110
|
}
|
|
63734
|
-
const existing =
|
|
64111
|
+
const existing = readFileSync28(path, "utf-8");
|
|
63735
64112
|
const lineEnding = lineEndingFor(existing);
|
|
63736
64113
|
const location = findSection(existing);
|
|
63737
64114
|
if (!location)
|
|
@@ -63740,7 +64117,7 @@ function removeRuleForAgent(agent) {
|
|
|
63740
64117
|
if (!next) {
|
|
63741
64118
|
unlinkSync5(path);
|
|
63742
64119
|
} else {
|
|
63743
|
-
|
|
64120
|
+
writeFileSync19(path, `${next}${lineEnding}`, "utf-8");
|
|
63744
64121
|
}
|
|
63745
64122
|
return { agent, path, action: "removed" };
|
|
63746
64123
|
}
|
|
@@ -63768,36 +64145,36 @@ var init_installer = __esm(() => {
|
|
|
63768
64145
|
RULE_TARGETS = {
|
|
63769
64146
|
claude: {
|
|
63770
64147
|
kind: "file",
|
|
63771
|
-
path: () =>
|
|
64148
|
+
path: () => join43(claudeConfigDir4(), "rules", "dosu.md")
|
|
63772
64149
|
},
|
|
63773
64150
|
cursor: {
|
|
63774
64151
|
kind: "file",
|
|
63775
|
-
path: () =>
|
|
64152
|
+
path: () => join43(homedir12(), ".cursor", "rules", "dosu.mdc"),
|
|
63776
64153
|
cursorFrontmatter: true
|
|
63777
64154
|
},
|
|
63778
64155
|
codex: {
|
|
63779
64156
|
kind: "section",
|
|
63780
|
-
path: () =>
|
|
64157
|
+
path: () => join43(codexHome4(), "AGENTS.md")
|
|
63781
64158
|
},
|
|
63782
64159
|
opencode: {
|
|
63783
64160
|
kind: "section",
|
|
63784
|
-
path: () =>
|
|
64161
|
+
path: () => join43(homedir12(), ".config", "opencode", "AGENTS.md")
|
|
63785
64162
|
},
|
|
63786
64163
|
gemini: {
|
|
63787
64164
|
kind: "section",
|
|
63788
|
-
path: () =>
|
|
64165
|
+
path: () => join43(homedir12(), ".gemini", "GEMINI.md")
|
|
63789
64166
|
},
|
|
63790
64167
|
antigravity: {
|
|
63791
64168
|
kind: "section",
|
|
63792
|
-
path: () =>
|
|
64169
|
+
path: () => join43(homedir12(), ".gemini", "GEMINI.md")
|
|
63793
64170
|
}
|
|
63794
64171
|
};
|
|
63795
64172
|
});
|
|
63796
64173
|
|
|
63797
64174
|
// src/setup/agents-md-step.ts
|
|
63798
64175
|
import { execSync as execSync2 } from "node:child_process";
|
|
63799
|
-
import { existsSync as
|
|
63800
|
-
import { join as
|
|
64176
|
+
import { existsSync as existsSync30, readFileSync as readFileSync29, writeFileSync as writeFileSync20 } from "node:fs";
|
|
64177
|
+
import { join as join44 } from "node:path";
|
|
63801
64178
|
function inGitWorkTree(cwd = process.cwd()) {
|
|
63802
64179
|
try {
|
|
63803
64180
|
const stdout = execSync2("git rev-parse --is-inside-work-tree", {
|
|
@@ -63811,10 +64188,10 @@ function inGitWorkTree(cwd = process.cwd()) {
|
|
|
63811
64188
|
}
|
|
63812
64189
|
function dosuAgentsSectionState(cwd = process.cwd()) {
|
|
63813
64190
|
try {
|
|
63814
|
-
const path =
|
|
63815
|
-
if (!
|
|
64191
|
+
const path = join44(cwd, "AGENTS.md");
|
|
64192
|
+
if (!existsSync30(path))
|
|
63816
64193
|
return "missing";
|
|
63817
|
-
const content =
|
|
64194
|
+
const content = readFileSync29(path, "utf-8");
|
|
63818
64195
|
const startMatch = content.match(SECTION_START_RE);
|
|
63819
64196
|
if (!startMatch || !content.includes(DOSU_SECTION_END))
|
|
63820
64197
|
return "missing";
|
|
@@ -63849,14 +64226,14 @@ function findSection2(content) {
|
|
|
63849
64226
|
return { start, end };
|
|
63850
64227
|
}
|
|
63851
64228
|
function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
|
|
63852
|
-
const path =
|
|
63853
|
-
if (!
|
|
64229
|
+
const path = join44(cwd, "AGENTS.md");
|
|
64230
|
+
if (!existsSync30(path)) {
|
|
63854
64231
|
const section = buildDosuAgentsSection(content);
|
|
63855
|
-
|
|
64232
|
+
writeFileSync20(path, `${section}
|
|
63856
64233
|
`);
|
|
63857
64234
|
return { path, action: "created" };
|
|
63858
64235
|
}
|
|
63859
|
-
const existing =
|
|
64236
|
+
const existing = readFileSync29(path, "utf-8");
|
|
63860
64237
|
const lineEnding = lineEndingFor2(existing);
|
|
63861
64238
|
const section = renderDosuAgentsSection(content, lineEnding);
|
|
63862
64239
|
const location = findSection2(existing);
|
|
@@ -63868,7 +64245,7 @@ function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RU
|
|
|
63868
64245
|
}
|
|
63869
64246
|
if (next === existing)
|
|
63870
64247
|
return { path, action: "unchanged" };
|
|
63871
|
-
|
|
64248
|
+
writeFileSync20(path, next);
|
|
63872
64249
|
return { path, action: "updated" };
|
|
63873
64250
|
}
|
|
63874
64251
|
async function stepUpdateAgentsMd(cwd = process.cwd(), content) {
|
|
@@ -64642,9 +65019,6 @@ async function runSetupFlow(opts = {}) {
|
|
|
64642
65019
|
if (cfg.mode !== MODE_OSS) {
|
|
64643
65020
|
await stepShowLibrary(cfg);
|
|
64644
65021
|
}
|
|
64645
|
-
if (cfg.mode !== MODE_OSS) {
|
|
64646
|
-
await stepOfferGithubConnect(cfg);
|
|
64647
|
-
}
|
|
64648
65022
|
const apiKey = await stepMintAPIKey(apiClient, cfg);
|
|
64649
65023
|
if (!apiKey) {
|
|
64650
65024
|
trackInBackground(trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
@@ -64968,46 +65342,6 @@ async function stepSetupHandshake(cfg, onboardingRunID) {
|
|
|
64968
65342
|
return false;
|
|
64969
65343
|
}
|
|
64970
65344
|
}
|
|
64971
|
-
async function stepOfferGithubConnect(cfg) {
|
|
64972
|
-
const target = cfg.active_account?.target;
|
|
64973
|
-
if (!target?.org_id || !target?.space_id)
|
|
64974
|
-
return;
|
|
64975
|
-
try {
|
|
64976
|
-
await Promise.resolve().then(() => init_trpc());
|
|
64977
|
-
const trpc = createTypedClient(cfg);
|
|
64978
|
-
if (await spaceHasGithubSource(trpc, target.space_id))
|
|
64979
|
-
return;
|
|
64980
|
-
} catch (err) {
|
|
64981
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
64982
|
-
logger.warn("setup", `GitHub source check failed, skipping offer: ${msg}`);
|
|
64983
|
-
return;
|
|
64984
|
-
}
|
|
64985
|
-
logger.info("setup", "Step: offer GitHub connect (no GitHub source in the MCP's Library)");
|
|
64986
|
-
log2.warn("No GitHub repos are connected to this MCP yet, so it can't answer from your code.");
|
|
64987
|
-
const connectNow = await confirm2({
|
|
64988
|
-
message: "Connect a GitHub repo now?",
|
|
64989
|
-
active: "Connect now",
|
|
64990
|
-
inactive: "Skip for now",
|
|
64991
|
-
initialValue: true
|
|
64992
|
-
});
|
|
64993
|
-
if (isCancel2(connectNow) || !connectNow) {
|
|
64994
|
-
log2.info(`Skipped. Connect later at ${info(`${getWebAppURL()}/libraries`)} or re-run ${info("dosu setup")}.`);
|
|
64995
|
-
return;
|
|
64996
|
-
}
|
|
64997
|
-
await stepConnectGitHubRepo(cfg);
|
|
64998
|
-
}
|
|
64999
|
-
async function spaceHasGithubSource(trpc, spaceID) {
|
|
65000
|
-
try {
|
|
65001
|
-
const sources = await trpc.libraries.sourcesList.query(spaceID);
|
|
65002
|
-
return (sources ?? []).some((source) => source.provider_slug === "github");
|
|
65003
|
-
} catch (err) {
|
|
65004
|
-
const missingProcedure = isTRPCClientError(err) && err.data?.code === "NOT_FOUND";
|
|
65005
|
-
if (!missingProcedure)
|
|
65006
|
-
throw err;
|
|
65007
|
-
const spaceDeployments = await trpc.workspaces.listForSpace.query(spaceID);
|
|
65008
|
-
return (spaceDeployments ?? []).some((d) => d.provider_slug === "github");
|
|
65009
|
-
}
|
|
65010
|
-
}
|
|
65011
65345
|
async function resolveCloudSetupContext(cfg) {
|
|
65012
65346
|
try {
|
|
65013
65347
|
await Promise.resolve().then(() => init_trpc());
|
|
@@ -65540,7 +65874,6 @@ ${dim(wrapLog("Run it inside a session to keep that session out of studying. Rem
|
|
|
65540
65874
|
}
|
|
65541
65875
|
var import_picocolors34, OAUTH_ANALYTICS_REASONS, SETUP_HANDSHAKE_TIMEOUT_MS = 1800000, LIBRARY_SELECT_CANCELLED;
|
|
65542
65876
|
var init_flow2 = __esm(() => {
|
|
65543
|
-
init_dist();
|
|
65544
65877
|
init_errors3();
|
|
65545
65878
|
init_client();
|
|
65546
65879
|
init_skill();
|
|
@@ -65560,7 +65893,6 @@ var init_flow2 = __esm(() => {
|
|
|
65560
65893
|
init_mcp_refresh_check();
|
|
65561
65894
|
init_agents_md_step();
|
|
65562
65895
|
init_analytics2();
|
|
65563
|
-
init_github_step();
|
|
65564
65896
|
init_rules_step();
|
|
65565
65897
|
init_styles();
|
|
65566
65898
|
import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
@@ -65580,7 +65912,7 @@ var init_flow2 = __esm(() => {
|
|
|
65580
65912
|
// src/commands/upgrade.ts
|
|
65581
65913
|
import { spawnSync } from "node:child_process";
|
|
65582
65914
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
65583
|
-
import { homedir as
|
|
65915
|
+
import { homedir as homedir13 } from "node:os";
|
|
65584
65916
|
import { posix, win32 as win322 } from "node:path";
|
|
65585
65917
|
function isAbsoluteCommandProcessor(value) {
|
|
65586
65918
|
return Boolean(value && win322.isAbsolute(value) && win322.basename(value).toLowerCase() === "cmd.exe");
|
|
@@ -65634,7 +65966,7 @@ function packageRoots(manager, platform, comSpec, env, cwd) {
|
|
|
65634
65966
|
manager === "npm" ? path.join(lines[0], "@dosu", "cli") : path.join(lines[0], "node_modules", "@dosu", "cli")
|
|
65635
65967
|
];
|
|
65636
65968
|
}
|
|
65637
|
-
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd =
|
|
65969
|
+
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd = homedir13()) {
|
|
65638
65970
|
const path = platform === "win32" ? win322 : posix;
|
|
65639
65971
|
if (!entrypoint || !path.isAbsolute(entrypoint))
|
|
65640
65972
|
return null;
|
|
@@ -65687,7 +66019,7 @@ Or install Dosu globally with your package manager:`);
|
|
|
65687
66019
|
function runUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
65688
66020
|
const platform = options.platform ?? process.platform;
|
|
65689
66021
|
const env = options.env ?? process.env;
|
|
65690
|
-
const cwd = options.cwd ??
|
|
66022
|
+
const cwd = options.cwd ?? homedir13();
|
|
65691
66023
|
let manager = null;
|
|
65692
66024
|
if (channel === "npm") {
|
|
65693
66025
|
if (isNpxInvocation(channel, env)) {
|
|
@@ -65754,7 +66086,7 @@ function finishWithNewBinary(channel, options) {
|
|
|
65754
66086
|
return;
|
|
65755
66087
|
}
|
|
65756
66088
|
const result = spawnSync(invocation.command, invocation.args, {
|
|
65757
|
-
cwd: options.cwd ??
|
|
66089
|
+
cwd: options.cwd ?? homedir13(),
|
|
65758
66090
|
shell: false,
|
|
65759
66091
|
stdio: "inherit"
|
|
65760
66092
|
});
|
|
@@ -66552,8 +66884,7 @@ var init_pages_view = __esm(() => {
|
|
|
66552
66884
|
});
|
|
66553
66885
|
|
|
66554
66886
|
// src/tui/tui.ts
|
|
66555
|
-
import {
|
|
66556
|
-
import { basename as basename6 } from "node:path";
|
|
66887
|
+
import { basename as basename7 } from "node:path";
|
|
66557
66888
|
async function probeSession(cfg) {
|
|
66558
66889
|
if (!isAuthenticated(cfg) || !isTokenExpired(cfg))
|
|
66559
66890
|
return { expired: false };
|
|
@@ -66580,7 +66911,7 @@ function bannerContext(cfg, session) {
|
|
|
66580
66911
|
return {
|
|
66581
66912
|
version: getVersionString(),
|
|
66582
66913
|
webAppHost,
|
|
66583
|
-
directory:
|
|
66914
|
+
directory: basename7(process.cwd()),
|
|
66584
66915
|
signedIn: isAuthenticated(cfg),
|
|
66585
66916
|
sessionExpired: session.expired,
|
|
66586
66917
|
deploymentName: cfg.active_account?.target?.deployment_name,
|
|
@@ -66781,8 +67112,9 @@ async function runSettings(cfg) {
|
|
|
66781
67112
|
while (true) {
|
|
66782
67113
|
const target = cfg.active_account?.target;
|
|
66783
67114
|
const library = target?.library_name ?? target?.deployment_name ?? "not configured";
|
|
66784
|
-
const
|
|
66785
|
-
const
|
|
67115
|
+
const sync = loadSyncState();
|
|
67116
|
+
const filter = sync.repo_filter;
|
|
67117
|
+
const scope = !filter ? sync.project_filter?.length ? `${sync.project_filter.length} folders (legacy)` : "all repos" : filter.length === 0 ? "no repos" : filter.length <= 2 ? filter.map(displayRepo).join(", ") : `${filter.length} repos`;
|
|
66786
67118
|
const action = await menuSelect("settings", [
|
|
66787
67119
|
{ label: "switch organization", hint: target?.org_name, value: "switch-org" },
|
|
66788
67120
|
{ label: "switch library", hint: library, value: "switch-library" },
|
|
@@ -66816,45 +67148,43 @@ async function runSettings(cfg) {
|
|
|
66816
67148
|
}
|
|
66817
67149
|
}
|
|
66818
67150
|
}
|
|
66819
|
-
function
|
|
66820
|
-
const home = homedir15();
|
|
66821
|
-
return dir === home ? "~" : dir.startsWith(`${home}/`) ? `~${dir.slice(home.length)}` : dir;
|
|
66822
|
-
}
|
|
66823
|
-
function discoverProjectDirs() {
|
|
67151
|
+
function discoverSessionRepos(current) {
|
|
66824
67152
|
const counts = new Map;
|
|
66825
67153
|
try {
|
|
66826
67154
|
const resolver = createProjectDirResolver();
|
|
66827
67155
|
for (const session of scanAgentSessions({})) {
|
|
66828
|
-
const
|
|
66829
|
-
|
|
67156
|
+
const repo = resolver.resolveRepo(session);
|
|
67157
|
+
if (repo)
|
|
67158
|
+
counts.set(repo, (counts.get(repo) ?? 0) + 1);
|
|
66830
67159
|
}
|
|
66831
67160
|
resolver.flush();
|
|
66832
67161
|
} catch {}
|
|
66833
|
-
|
|
67162
|
+
for (const repo of current ?? [])
|
|
67163
|
+
if (!counts.has(repo))
|
|
67164
|
+
counts.set(repo, 0);
|
|
67165
|
+
return [...counts.entries()].sort((a, b) => b[1] - a[1]).map(([repo]) => repo);
|
|
66834
67166
|
}
|
|
66835
67167
|
async function runStudyingProjectsSetting() {
|
|
66836
|
-
const
|
|
66837
|
-
|
|
66838
|
-
|
|
67168
|
+
const state = loadSyncState();
|
|
67169
|
+
const current = studyRepoFilter(state, () => scanAgentSessions({}), createProjectDirResolver());
|
|
67170
|
+
const repos = discoverSessionRepos(current);
|
|
67171
|
+
if (repos.length === 0) {
|
|
67172
|
+
log2.info("No agent sessions inside a git repo found yet; nothing to scope.");
|
|
66839
67173
|
return;
|
|
66840
67174
|
}
|
|
66841
|
-
const current = loadSyncState().project_filter;
|
|
66842
67175
|
const selected = await multiselect2({
|
|
66843
|
-
message: "Study sessions from which
|
|
66844
|
-
options:
|
|
66845
|
-
|
|
66846
|
-
|
|
66847
|
-
|
|
66848
|
-
initialValues: current?.length ? current : dirs,
|
|
66849
|
-
summary: (picked) => picked.length === dirs.length ? "all folders · new ones included automatically" : `${picked.length} of ${dirs.length} folders · subfolders included`,
|
|
66850
|
-
validate: (picked) => picked.length === 0 ? "Select at least one folder." : undefined
|
|
67176
|
+
message: "Study sessions from which repos?",
|
|
67177
|
+
options: repos.map((repo) => ({ label: displayRepo(repo), hint: repo, value: repo })),
|
|
67178
|
+
initialValues: current ?? repos,
|
|
67179
|
+
summary: (picked) => picked.length === repos.length ? "all repos · new ones included automatically" : `${picked.length} of ${repos.length} repos`,
|
|
67180
|
+
validate: (picked) => picked.length === 0 ? "Select at least one repo." : undefined
|
|
66851
67181
|
});
|
|
66852
67182
|
if (isCancel2(selected))
|
|
66853
67183
|
return;
|
|
66854
|
-
const { project_filter:
|
|
66855
|
-
const all = selected.length ===
|
|
66856
|
-
saveSyncState(all ?
|
|
66857
|
-
const scope = all ? "all
|
|
67184
|
+
const { repo_filter: _repos, project_filter: _folders, ...fresh } = loadSyncState();
|
|
67185
|
+
const all = selected.length === repos.length;
|
|
67186
|
+
saveSyncState(all ? fresh : { ...fresh, repo_filter: [...selected] });
|
|
67187
|
+
const scope = all ? "all repos" : selected.map(displayRepo).join(", ");
|
|
66858
67188
|
log2.success(`Study scope ${dim(`· ${scope}`)}`);
|
|
66859
67189
|
}
|
|
66860
67190
|
async function handleAuthenticate(cfg) {
|
|
@@ -66907,6 +67237,7 @@ var init_tui = __esm(() => {
|
|
|
66907
67237
|
init_providers();
|
|
66908
67238
|
init_generate();
|
|
66909
67239
|
init_project_dir();
|
|
67240
|
+
init_repo();
|
|
66910
67241
|
init_scan();
|
|
66911
67242
|
init_agents_md_step();
|
|
66912
67243
|
init_flow2();
|
|
@@ -67527,7 +67858,7 @@ var init_flow3 = __esm(() => {
|
|
|
67527
67858
|
});
|
|
67528
67859
|
|
|
67529
67860
|
// src/cli/cli.ts
|
|
67530
|
-
import { readFileSync as
|
|
67861
|
+
import { readFileSync as readFileSync30, unlinkSync as unlinkSync6 } from "node:fs";
|
|
67531
67862
|
function shouldRunBackgroundChecks(actionName) {
|
|
67532
67863
|
return actionName !== "upgrade";
|
|
67533
67864
|
}
|
|
@@ -67973,7 +68304,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
67973
68304
|
}
|
|
67974
68305
|
if (opts.follow) {
|
|
67975
68306
|
try {
|
|
67976
|
-
const lines =
|
|
68307
|
+
const lines = readFileSync30(logPath, "utf-8").split(`
|
|
67977
68308
|
`);
|
|
67978
68309
|
if (lines.at(-1) === "")
|
|
67979
68310
|
lines.pop();
|
|
@@ -67989,7 +68320,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
67989
68320
|
if (opts.tail !== undefined) {
|
|
67990
68321
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
67991
68322
|
try {
|
|
67992
|
-
const content =
|
|
68323
|
+
const content = readFileSync30(logPath, "utf-8");
|
|
67993
68324
|
const lines = content.split(`
|
|
67994
68325
|
`);
|
|
67995
68326
|
console.log(lines.slice(-n).join(`
|
|
@@ -68115,4 +68446,4 @@ main().catch((err) => {
|
|
|
68115
68446
|
process.exit(1);
|
|
68116
68447
|
});
|
|
68117
68448
|
|
|
68118
|
-
//# debugId=
|
|
68449
|
+
//# debugId=3b9a1619-fdbd-ebdd-6475-6e2164756e21
|