@dosu/cli 0.67.0-beta.1 → 0.67.0-beta.10
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 +40 -73
- package/bin/dosu.js +596 -634
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -450,7 +450,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
450
450
|
function getVersionString() {
|
|
451
451
|
return `v${VERSION}`;
|
|
452
452
|
}
|
|
453
|
-
var VERSION = "0.67.0-beta.
|
|
453
|
+
var VERSION = "0.67.0-beta.10", INSTALL_CHANNEL = "npm";
|
|
454
454
|
|
|
455
455
|
// src/debug/logger.ts
|
|
456
456
|
import {
|
|
@@ -602,22 +602,6 @@ function expandHome(path) {
|
|
|
602
602
|
return path;
|
|
603
603
|
return join3(homedir2(), path.slice(1));
|
|
604
604
|
}
|
|
605
|
-
function appSupportDir() {
|
|
606
|
-
switch (platform()) {
|
|
607
|
-
case "darwin": {
|
|
608
|
-
return join3(homedir2(), "Library", "Application Support");
|
|
609
|
-
}
|
|
610
|
-
case "win32": {
|
|
611
|
-
return process.env.APPDATA ?? "";
|
|
612
|
-
}
|
|
613
|
-
default: {
|
|
614
|
-
const xdg = process.env.XDG_CONFIG_HOME;
|
|
615
|
-
if (xdg)
|
|
616
|
-
return xdg;
|
|
617
|
-
return join3(homedir2(), ".config");
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
605
|
function allOnPath(name) {
|
|
622
606
|
return (process.env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) => join3(dir, name)).filter((candidate) => existsSync3(candidate));
|
|
623
607
|
}
|
|
@@ -1087,7 +1071,7 @@ function getSupabaseURL() {
|
|
|
1087
1071
|
return process.env.SUPABASE_URL_OVERRIDE ?? "https://wldmetsoicvieidlsqrb.supabase.co" ?? "";
|
|
1088
1072
|
}
|
|
1089
1073
|
function getSupabaseAnonKey() {
|
|
1090
|
-
return process.env.SUPABASE_ANON_KEY_OVERRIDE ?? "
|
|
1074
|
+
return process.env.SUPABASE_ANON_KEY_OVERRIDE ?? "sb_publishable_zbUf8qAI35-w42udlAJ6LQ_01-ZZtln" ?? "";
|
|
1091
1075
|
}
|
|
1092
1076
|
function isAbsoluteHttpUrl(value) {
|
|
1093
1077
|
try {
|
|
@@ -3486,6 +3470,7 @@ function redactSecrets2(text) {
|
|
|
3486
3470
|
if (kvAssignmentNearby(lower)) {
|
|
3487
3471
|
const kvRepl = (m) => `${m[1]}${m[2]}${m[3]}[redacted:credential]${closingQuote(m[3], m[5])}`;
|
|
3488
3472
|
s = replaceSubmatch(s, genericKVRE, "credential", counts, kvRepl);
|
|
3473
|
+
s = replaceSubmatch(s, authTokenKVRE, "credential", counts, kvRepl);
|
|
3489
3474
|
s = replaceSubmatch(s, envKeyRE, "credential", counts, kvRepl);
|
|
3490
3475
|
s = replaceSubmatch(s, genericKVIntlRE, "credential", counts, kvRepl);
|
|
3491
3476
|
}
|
|
@@ -3626,18 +3611,19 @@ function redactEntropy(s, counts) {
|
|
|
3626
3611
|
return s;
|
|
3627
3612
|
return out + s.slice(last);
|
|
3628
3613
|
}
|
|
3629
|
-
var REDACTION_MARKER = "[redacted:", awsAccessKeyRE, awsSecretRE, genericKVRE, envKeyRE, genericKVIntlRE, bearerRE, quotedSecretRE, pemPrivateRE, providerRE, jwtRE, connURLRE, kvHints, providerHints, entropyMinBits = 4.5, entropyMinAssign = 20, entropyMinStandalone = 28, stopWords;
|
|
3614
|
+
var REDACTION_MARKER = "[redacted:", awsAccessKeyRE, awsSecretRE, genericKVRE, authTokenKVRE, envKeyRE, genericKVIntlRE, bearerRE, quotedSecretRE, pemPrivateRE, providerRE, jwtRE, connURLRE, kvHints, providerHints, entropyMinBits = 4.5, entropyMinAssign = 20, entropyMinStandalone = 28, stopWords;
|
|
3630
3615
|
var init_redact = __esm(() => {
|
|
3631
3616
|
awsAccessKeyRE = /A(?:KIA|SIA)[0-9A-Z]{16}/g;
|
|
3632
3617
|
awsSecretRE = /\b(aws[_-]?secret[_-]?access[_-]?key)(\\*['"]?\s*[:=]\s*)(\\*['"]?)([A-Za-z0-9/+=_-]{32,})(\\*['"]?)/gi;
|
|
3633
3618
|
genericKVRE = /\b([\w.-]{0,64}?(?:api[_-]?key|secret|token|passwd|password|authorization))(\\*['"]?\s*[:=]\s*)(\\*['"]?)([A-Za-z0-9/+=._-]{16,})(\\*['"]?)/gi;
|
|
3619
|
+
authTokenKVRE = /\b([\w.-]{0,64}?(?:access|refresh|id)[_-]?token)(\\*['"]?\s*[:=]\s*)(\\*['"]?)([A-Za-z0-9/+=._-]{8,})(\\*['"]?)/gi;
|
|
3634
3620
|
envKeyRE = /\b([A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*_KEY)(\\*['"]?\s*[:=]\s*)(\\*['"]?)([A-Za-z0-9/+=._-]{16,})(\\*['"]?)/g;
|
|
3635
3621
|
genericKVIntlRE = /(парол[ьяею]|токен[ауы]?|секрет[ауы]?|ключ[аеиуом]?|contraseña|senha|passwort|密码|密碼|パスワード|비밀번호)(\\*['"]?\s*[:=]\s*)(\\*['"]?)([A-Za-z0-9/+=._-]{16,})(\\*['"]?)/gi;
|
|
3636
3622
|
bearerRE = /\b(Bearer|Basic)(\s+)([A-Za-z0-9._~+/=-]{16,})/gi;
|
|
3637
3623
|
quotedSecretRE = /\b(password|passwd|pwd|secret|token|api[_-]?key)(\s+(?:is\s+|was\s+|for\s+)?)(\\*["'`])([^"'`\n]{6,80})(\\*["'`])/gi;
|
|
3638
3624
|
pemPrivateRE = /-----BEGIN [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY[A-Z0-9 ]*-----/g;
|
|
3639
|
-
providerRE = /\b(gh[opsur]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}|sk_user_[A-Za-z0-
|
|
3640
|
-
jwtRE = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\b/g;
|
|
3625
|
+
providerRE = /\b(gh[opsur]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}|sk_user_[A-Za-z0-9_-]{8,}|sk-[A-Za-z0-9_-]*[A-Za-z0-9]{20,}|gsk_[A-Za-z0-9]{20,}|xai-[A-Za-z0-9]{20,}|hf_[A-Za-z0-9]{20,}|npm_[A-Za-z0-9]{30,}|xox[bpcs]-[A-Za-z0-9-]{10,}|AIza[0-9A-Za-z_-]{30,})\b/g;
|
|
3626
|
+
jwtRE = /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\b|(?<=(?:^|[^A-Za-z0-9_-])[A-Za-z0-9_-]{1,8})eyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}/g;
|
|
3641
3627
|
connURLRE = /\b([A-Za-z][A-Za-z0-9+.-]*:\/\/)([^\s/@:]*):([^\s]+)@([^\s]+)/g;
|
|
3642
3628
|
kvHints = [
|
|
3643
3629
|
"key",
|
|
@@ -7688,6 +7674,10 @@ function saveSyncState(state, configDir = getConfigDir()) {
|
|
|
7688
7674
|
writeFileSync3(tmp, JSON.stringify(state, null, 2), { mode: 384 });
|
|
7689
7675
|
renameSync2(tmp, path);
|
|
7690
7676
|
}
|
|
7677
|
+
function saveRepoFilter(repos, configDir = getConfigDir()) {
|
|
7678
|
+
const { repo_filter: _repos, project_filter: _folders, ...rest } = loadSyncState(configDir);
|
|
7679
|
+
saveSyncState(repos ? { ...rest, repo_filter: [...repos] } : rest, configDir);
|
|
7680
|
+
}
|
|
7691
7681
|
function setSyncPaused(paused, configDir = getConfigDir()) {
|
|
7692
7682
|
const state = loadSyncState(configDir);
|
|
7693
7683
|
if (paused)
|
|
@@ -9411,18 +9401,26 @@ function groupedAgent(options) {
|
|
|
9411
9401
|
}
|
|
9412
9402
|
function cursorAgent() {
|
|
9413
9403
|
const configPath = () => expandHome("~/.cursor/hooks.json");
|
|
9404
|
+
const has = (event) => hasCursorHook(readHookConfig(configPath()), event);
|
|
9414
9405
|
return {
|
|
9415
9406
|
id: () => "cursor",
|
|
9416
9407
|
name: () => "Cursor",
|
|
9417
9408
|
isInstalled: () => isInstalled(["~/.cursor"]),
|
|
9418
9409
|
configPath,
|
|
9419
|
-
isEnabled: () =>
|
|
9410
|
+
isEnabled: () => has(CURSOR_EVENT),
|
|
9420
9411
|
enable: () => {
|
|
9421
|
-
|
|
9412
|
+
let config = readHookConfig(configPath());
|
|
9413
|
+
config = addCursorHook(config, CURSOR_EVENT);
|
|
9414
|
+
config = addCursorHook(config, CURSOR_END_EVENT);
|
|
9415
|
+
writeHookConfig(configPath(), config);
|
|
9422
9416
|
},
|
|
9423
9417
|
disable: () => {
|
|
9424
|
-
|
|
9425
|
-
|
|
9418
|
+
let config = readHookConfig(configPath());
|
|
9419
|
+
config = removeCursorHook(config, CURSOR_EVENT);
|
|
9420
|
+
config = removeCursorHook(config, CURSOR_END_EVENT);
|
|
9421
|
+
writeHookConfig(configPath(), config);
|
|
9422
|
+
},
|
|
9423
|
+
statusNote: () => has(CURSOR_END_EVENT) ? "" : "The sessionEnd hook is missing, so sessions ship only once quiet; 'dosu knowledge hooks enable cursor' adds it."
|
|
9426
9424
|
};
|
|
9427
9425
|
}
|
|
9428
9426
|
function claudeAgent() {
|
|
@@ -9499,7 +9497,7 @@ function refreshEnabledHooks() {
|
|
|
9499
9497
|
}
|
|
9500
9498
|
return refreshed;
|
|
9501
9499
|
}
|
|
9502
|
-
var CURSOR_EVENT = "stop";
|
|
9500
|
+
var CURSOR_EVENT = "stop", CURSOR_END_EVENT = "sessionEnd";
|
|
9503
9501
|
var init_agents2 = __esm(() => {
|
|
9504
9502
|
init_logger();
|
|
9505
9503
|
init_agents();
|
|
@@ -9582,14 +9580,18 @@ function headReflogOfDir(dir, timeout = 5000) {
|
|
|
9582
9580
|
function displayRepo(repo) {
|
|
9583
9581
|
return repo.split("/").slice(1).join("/") || repo;
|
|
9584
9582
|
}
|
|
9585
|
-
|
|
9583
|
+
function githubSlugOfRepo(repo) {
|
|
9584
|
+
return repo === null ? null : GITHUB_SLUG.exec(repo)?.[1] ?? null;
|
|
9585
|
+
}
|
|
9586
|
+
var GIT_LOCATION_ENV, GIT_TIMED_OUT, GITHUB_SLUG;
|
|
9586
9587
|
var init_repo = __esm(() => {
|
|
9587
9588
|
GIT_LOCATION_ENV = ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE"];
|
|
9588
9589
|
GIT_TIMED_OUT = Symbol("git timed out");
|
|
9590
|
+
GITHUB_SLUG = /^github\.com\/([a-z0-9-]+\/[a-z0-9._-]+)$/;
|
|
9589
9591
|
});
|
|
9590
9592
|
|
|
9591
9593
|
// src/sync/lock.ts
|
|
9592
|
-
import { existsSync as existsSync12, readFileSync as readFileSync15, rmSync as rmSync2, statSync as statSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
9594
|
+
import { existsSync as existsSync12, readFileSync as readFileSync15, rmSync as rmSync2, statSync as statSync5, utimesSync, writeFileSync as writeFileSync6 } from "node:fs";
|
|
9593
9595
|
import { join as join15 } from "node:path";
|
|
9594
9596
|
function processAlive(pid) {
|
|
9595
9597
|
try {
|
|
@@ -9652,6 +9654,16 @@ function fileLock(configDir = getConfigDir(), now = () => new Date) {
|
|
|
9652
9654
|
} catch {}
|
|
9653
9655
|
return false;
|
|
9654
9656
|
},
|
|
9657
|
+
refresh() {
|
|
9658
|
+
if (!held)
|
|
9659
|
+
return;
|
|
9660
|
+
try {
|
|
9661
|
+
if (readFileSync15(path, "utf8") === String(process.pid)) {
|
|
9662
|
+
const at = now();
|
|
9663
|
+
utimesSync(path, at, at);
|
|
9664
|
+
}
|
|
9665
|
+
} catch {}
|
|
9666
|
+
},
|
|
9655
9667
|
release() {
|
|
9656
9668
|
if (!held)
|
|
9657
9669
|
return;
|
|
@@ -16186,77 +16198,10 @@ var init_ask = __esm(() => {
|
|
|
16186
16198
|
import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
16187
16199
|
});
|
|
16188
16200
|
|
|
16189
|
-
// src/setup/styles.ts
|
|
16190
|
-
import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
|
|
16191
|
-
function hasTruecolor() {
|
|
16192
|
-
return /truecolor|24bit/i.test(process.env.COLORTERM ?? "");
|
|
16193
|
-
}
|
|
16194
|
-
function brand(msg) {
|
|
16195
|
-
if (!import_picocolors8.default.isColorSupported)
|
|
16196
|
-
return msg;
|
|
16197
|
-
return hasTruecolor() ? `${BRAND_FG}${msg}${RESET_FG}` : import_picocolors8.default.green(msg);
|
|
16198
|
-
}
|
|
16199
|
-
function brandBadge(msg) {
|
|
16200
|
-
if (!import_picocolors8.default.isColorSupported)
|
|
16201
|
-
return `[ ${msg} ]`;
|
|
16202
|
-
const label = import_picocolors8.default.bold(` ${msg} `);
|
|
16203
|
-
return hasTruecolor() ? `${BRAND_BG}${INK_FG}${label}${RESET_FG}${RESET_BG}` : import_picocolors8.default.bgGreen(import_picocolors8.default.black(label));
|
|
16204
|
-
}
|
|
16205
|
-
function dim(msg) {
|
|
16206
|
-
return import_picocolors8.default.dim(msg);
|
|
16207
|
-
}
|
|
16208
|
-
function formatSetupSummary(title, items, marker = IconAdd) {
|
|
16209
|
-
const styled = marker === IconRemove ? import_picocolors8.default.red(marker) : brand(marker);
|
|
16210
|
-
const lines = items.map((item) => {
|
|
16211
|
-
const path = `${item.path}${item.status ? ` (${item.status})` : ""}`;
|
|
16212
|
-
return item.label ? `${styled} ${item.label}
|
|
16213
|
-
${dim(path)}` : `${styled} ${dim(path)}`;
|
|
16214
|
-
});
|
|
16215
|
-
return `${title}
|
|
16216
|
-
${lines.join(`
|
|
16217
|
-
`)}`;
|
|
16218
|
-
}
|
|
16219
|
-
function browserFallbackHint(url) {
|
|
16220
|
-
return dim(`If your browser doesn't open automatically, visit:
|
|
16221
|
-
${url}`);
|
|
16222
|
-
}
|
|
16223
|
-
function info(msg) {
|
|
16224
|
-
return import_picocolors8.default.cyan(msg);
|
|
16225
|
-
}
|
|
16226
|
-
function visibleWidth(text) {
|
|
16227
|
-
return stripVTControlCharacters4(text).length;
|
|
16228
|
-
}
|
|
16229
|
-
function wrapLog(text, columns = process.stdout.columns || 80) {
|
|
16230
|
-
const width = Math.max(20, columns - LOG_GUTTER);
|
|
16231
|
-
const out = [];
|
|
16232
|
-
for (const paragraph of text.split(`
|
|
16233
|
-
`)) {
|
|
16234
|
-
if (visibleWidth(paragraph) <= width) {
|
|
16235
|
-
out.push(paragraph);
|
|
16236
|
-
continue;
|
|
16237
|
-
}
|
|
16238
|
-
let line = "";
|
|
16239
|
-
for (const word of paragraph.split(" ")) {
|
|
16240
|
-
if (line === "") {
|
|
16241
|
-
line = word;
|
|
16242
|
-
} else if (visibleWidth(line) + 1 + visibleWidth(word) <= width) {
|
|
16243
|
-
line = `${line} ${word}`;
|
|
16244
|
-
} else {
|
|
16245
|
-
out.push(line);
|
|
16246
|
-
line = word;
|
|
16247
|
-
}
|
|
16248
|
-
}
|
|
16249
|
-
out.push(line);
|
|
16250
|
-
}
|
|
16251
|
-
return out.join(`
|
|
16252
|
-
`);
|
|
16253
|
-
}
|
|
16254
|
-
var import_picocolors8, IconAdd = "✔", IconRemove = "-", BRAND_FG = "\x1B[38;2;82;164;15m", BRAND_BG = "\x1B[48;2;82;164;15m", INK_FG = "\x1B[38;2;14;14;14m", RESET_FG = "\x1B[39m", RESET_BG = "\x1B[49m", LOG_GUTTER = 4;
|
|
16255
|
-
var init_styles = __esm(() => {
|
|
16256
|
-
import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
16257
|
-
});
|
|
16258
|
-
|
|
16259
16201
|
// src/tui/layout.ts
|
|
16202
|
+
function activeLayoutMargin() {
|
|
16203
|
+
return activeMargin;
|
|
16204
|
+
}
|
|
16260
16205
|
function contentWidth(columns = process.stdout.columns ?? 80) {
|
|
16261
16206
|
return Math.min(columns, CONTENT_WIDTH);
|
|
16262
16207
|
}
|
|
@@ -16275,9 +16220,9 @@ function breadcrumb(segments, width = contentWidth()) {
|
|
|
16275
16220
|
const trailWidth = head.reduce((total, segment) => total + segment.length + 3, 0);
|
|
16276
16221
|
const room = Math.max(8, width - trailWidth);
|
|
16277
16222
|
const clipped = leaf.length <= room ? leaf : `${leaf.slice(0, room - 1)}…`;
|
|
16278
|
-
return head.map((segment) =>
|
|
16223
|
+
return head.map((segment) => import_picocolors8.default.dim(`${segment} › `)).join("") + import_picocolors8.default.bold(clipped);
|
|
16279
16224
|
}
|
|
16280
|
-
function
|
|
16225
|
+
function visibleWidth(text) {
|
|
16281
16226
|
return text.replace(ANSI_PATTERN2, "").length;
|
|
16282
16227
|
}
|
|
16283
16228
|
function tabStrip(labels, active, width, { spread = true } = {}) {
|
|
@@ -16288,8 +16233,8 @@ function tabStrip(labels, active, width, { spread = true } = {}) {
|
|
|
16288
16233
|
for (const [id, label] of labels) {
|
|
16289
16234
|
const left = Math.floor((cellW - label.length) / 2);
|
|
16290
16235
|
const cell = " ".repeat(left) + label + " ".repeat(cellW - label.length - left);
|
|
16291
|
-
row += id === active ? brand(
|
|
16292
|
-
rule += id === active ? brand("━".repeat(cellW)) :
|
|
16236
|
+
row += id === active ? brand(import_picocolors8.default.bold(cell)) : import_picocolors8.default.dim(cell);
|
|
16237
|
+
rule += id === active ? brand("━".repeat(cellW)) : import_picocolors8.default.dim("─".repeat(cellW));
|
|
16293
16238
|
}
|
|
16294
16239
|
return [row, rule];
|
|
16295
16240
|
}
|
|
@@ -16312,18 +16257,18 @@ function tabStrip(labels, active, width, { spread = true } = {}) {
|
|
|
16312
16257
|
if (id === active) {
|
|
16313
16258
|
activeStart = col;
|
|
16314
16259
|
activeLen = label.length;
|
|
16315
|
-
row += brand(
|
|
16260
|
+
row += brand(import_picocolors8.default.bold(label));
|
|
16316
16261
|
} else {
|
|
16317
|
-
row +=
|
|
16262
|
+
row += import_picocolors8.default.dim(label);
|
|
16318
16263
|
}
|
|
16319
16264
|
col += label.length;
|
|
16320
16265
|
});
|
|
16321
16266
|
const tail = Math.max(0, width - activeStart - activeLen);
|
|
16322
|
-
const rule =
|
|
16267
|
+
const rule = import_picocolors8.default.dim("─".repeat(activeStart)) + brand("━".repeat(activeLen)) + import_picocolors8.default.dim("─".repeat(tail));
|
|
16323
16268
|
return [row, rule];
|
|
16324
16269
|
}
|
|
16325
16270
|
function centerBlock(lines, width) {
|
|
16326
|
-
const blockWidth = Math.max(...lines.map(
|
|
16271
|
+
const blockWidth = Math.max(...lines.map(visibleWidth));
|
|
16327
16272
|
const pad = " ".repeat(Math.max(0, Math.floor((width - blockWidth) / 2)));
|
|
16328
16273
|
return lines.map((line) => pad + line);
|
|
16329
16274
|
}
|
|
@@ -16364,6 +16309,7 @@ function installCenteredLayout(stream = process.stdout) {
|
|
|
16364
16309
|
if (margin === 0)
|
|
16365
16310
|
return () => {};
|
|
16366
16311
|
active = true;
|
|
16312
|
+
activeMargin = margin;
|
|
16367
16313
|
const pad = " ".repeat(margin);
|
|
16368
16314
|
const original = stream.write;
|
|
16369
16315
|
const state = { atLineStart: true };
|
|
@@ -16376,12 +16322,13 @@ function installCenteredLayout(stream = process.stdout) {
|
|
|
16376
16322
|
return () => {
|
|
16377
16323
|
stream.write = original;
|
|
16378
16324
|
active = false;
|
|
16325
|
+
activeMargin = 0;
|
|
16379
16326
|
};
|
|
16380
16327
|
}
|
|
16381
|
-
var
|
|
16328
|
+
var import_picocolors8, ESC2, CONTENT_WIDTH = 64, TOKEN_PATTERN, COLUMN_RESET_FINALS, active = false, activeMargin = 0, ANSI_PATTERN2, TAB_CELL_PAD = 2;
|
|
16382
16329
|
var init_layout = __esm(() => {
|
|
16383
16330
|
init_styles();
|
|
16384
|
-
|
|
16331
|
+
import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
16385
16332
|
ESC2 = String.fromCharCode(27);
|
|
16386
16333
|
TOKEN_PATTERN = new RegExp(`(\r
|
|
16387
16334
|
|\r|
|
|
@@ -16390,6 +16337,73 @@ var init_layout = __esm(() => {
|
|
|
16390
16337
|
ANSI_PATTERN2 = new RegExp(`${ESC2}\\[[0-9;?]*[A-Za-z]`, "g");
|
|
16391
16338
|
});
|
|
16392
16339
|
|
|
16340
|
+
// src/setup/styles.ts
|
|
16341
|
+
function hasTruecolor() {
|
|
16342
|
+
return /truecolor|24bit/i.test(process.env.COLORTERM ?? "");
|
|
16343
|
+
}
|
|
16344
|
+
function brand(msg) {
|
|
16345
|
+
if (!import_picocolors9.default.isColorSupported)
|
|
16346
|
+
return msg;
|
|
16347
|
+
return hasTruecolor() ? `${BRAND_FG}${msg}${RESET_FG}` : import_picocolors9.default.green(msg);
|
|
16348
|
+
}
|
|
16349
|
+
function brandBadge(msg) {
|
|
16350
|
+
if (!import_picocolors9.default.isColorSupported)
|
|
16351
|
+
return `[ ${msg} ]`;
|
|
16352
|
+
const label = import_picocolors9.default.bold(` ${msg} `);
|
|
16353
|
+
return hasTruecolor() ? `${BRAND_BG}${INK_FG}${label}${RESET_FG}${RESET_BG}` : import_picocolors9.default.bgGreen(import_picocolors9.default.black(label));
|
|
16354
|
+
}
|
|
16355
|
+
function dim(msg) {
|
|
16356
|
+
return import_picocolors9.default.dim(msg);
|
|
16357
|
+
}
|
|
16358
|
+
function formatSetupSummary(title, items, marker = IconAdd) {
|
|
16359
|
+
const styled = marker === IconRemove ? import_picocolors9.default.red(marker) : brand(marker);
|
|
16360
|
+
const lines = items.map((item) => {
|
|
16361
|
+
const path = `${item.path}${item.status ? ` (${item.status})` : ""}`;
|
|
16362
|
+
return item.label ? `${styled} ${item.label}
|
|
16363
|
+
${dim(path)}` : `${styled} ${dim(path)}`;
|
|
16364
|
+
});
|
|
16365
|
+
return `${title}
|
|
16366
|
+
${lines.join(`
|
|
16367
|
+
`)}`;
|
|
16368
|
+
}
|
|
16369
|
+
function browserFallbackHint(url) {
|
|
16370
|
+
return dim(`If your browser doesn't open automatically, visit:
|
|
16371
|
+
${url}`);
|
|
16372
|
+
}
|
|
16373
|
+
function info(msg) {
|
|
16374
|
+
return import_picocolors9.default.cyan(msg);
|
|
16375
|
+
}
|
|
16376
|
+
function wrapLog(text, columns = process.stdout.columns || 80) {
|
|
16377
|
+
const width = Math.max(20, contentWidth(columns) - LOG_GUTTER);
|
|
16378
|
+
const out = [];
|
|
16379
|
+
for (const paragraph of text.split(`
|
|
16380
|
+
`)) {
|
|
16381
|
+
if (visibleWidth(paragraph) <= width) {
|
|
16382
|
+
out.push(paragraph);
|
|
16383
|
+
continue;
|
|
16384
|
+
}
|
|
16385
|
+
let line = "";
|
|
16386
|
+
for (const word of paragraph.split(" ")) {
|
|
16387
|
+
if (line === "") {
|
|
16388
|
+
line = word;
|
|
16389
|
+
} else if (visibleWidth(line) + 1 + visibleWidth(word) <= width) {
|
|
16390
|
+
line = `${line} ${word}`;
|
|
16391
|
+
} else {
|
|
16392
|
+
out.push(line);
|
|
16393
|
+
line = word;
|
|
16394
|
+
}
|
|
16395
|
+
}
|
|
16396
|
+
out.push(line);
|
|
16397
|
+
}
|
|
16398
|
+
return out.join(`
|
|
16399
|
+
`);
|
|
16400
|
+
}
|
|
16401
|
+
var import_picocolors9, IconAdd = "✔", IconRemove = "-", BRAND_FG = "\x1B[38;2;82;164;15m", BRAND_BG = "\x1B[48;2;82;164;15m", INK_FG = "\x1B[38;2;14;14;14m", RESET_FG = "\x1B[39m", RESET_BG = "\x1B[49m", LOG_GUTTER = 4;
|
|
16402
|
+
var init_styles = __esm(() => {
|
|
16403
|
+
init_layout();
|
|
16404
|
+
import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
16405
|
+
});
|
|
16406
|
+
|
|
16393
16407
|
// src/tui/menu.ts
|
|
16394
16408
|
function parseKeys(chunk) {
|
|
16395
16409
|
const keys = [];
|
|
@@ -16427,9 +16441,9 @@ function reduceMenuKey(key, selected, count) {
|
|
|
16427
16441
|
return { type: "none" };
|
|
16428
16442
|
}
|
|
16429
16443
|
function renderMenuFrame(message, options, selected) {
|
|
16430
|
-
const labelWidth = Math.max(...options.map((option) =>
|
|
16444
|
+
const labelWidth = Math.max(...options.map((option) => visibleWidth(option.label)));
|
|
16431
16445
|
const rows = options.map((option, index) => {
|
|
16432
|
-
const label = option.label + " ".repeat(labelWidth -
|
|
16446
|
+
const label = option.label + " ".repeat(labelWidth - visibleWidth(option.label));
|
|
16433
16447
|
const hint = option.hint ? ` ${import_picocolors10.default.dim(option.hint)}` : "";
|
|
16434
16448
|
return index === selected ? `${brand(POINTER)} ${import_picocolors10.default.bold(label)}${hint}` : ` ${import_picocolors10.default.dim(label)}${hint}`;
|
|
16435
16449
|
});
|
|
@@ -16603,15 +16617,18 @@ function runInteractive(controller, io = {}) {
|
|
|
16603
16617
|
output.write(`${ESC4}[${frameLines}A${ESC4}[0J`);
|
|
16604
16618
|
frameLines = 0;
|
|
16605
16619
|
};
|
|
16620
|
+
const rowsFor = (line) => {
|
|
16621
|
+
const columns = output.columns || 80;
|
|
16622
|
+
return Math.max(1, Math.ceil((activeLayoutMargin() + visibleWidth(line)) / columns));
|
|
16623
|
+
};
|
|
16606
16624
|
const draw = () => {
|
|
16607
|
-
const
|
|
16608
|
-
`)).map((line) => `${brand(BAR)} ${line}`)
|
|
16609
|
-
`);
|
|
16625
|
+
const lines = controller.render().flatMap((line) => line.split(`
|
|
16626
|
+
`)).map((line) => `${brand(BAR)} ${line}`);
|
|
16610
16627
|
erase();
|
|
16611
|
-
output.write(`${
|
|
16628
|
+
output.write(`${lines.join(`
|
|
16629
|
+
`)}
|
|
16612
16630
|
`);
|
|
16613
|
-
frameLines =
|
|
16614
|
-
`).length;
|
|
16631
|
+
frameLines = lines.reduce((total, line) => total + rowsFor(line), 0);
|
|
16615
16632
|
};
|
|
16616
16633
|
output.write(HIDE_CURSOR2);
|
|
16617
16634
|
draw();
|
|
@@ -16721,7 +16738,11 @@ function multiselect2(opts, io = {}) {
|
|
|
16721
16738
|
let top = 0;
|
|
16722
16739
|
let error;
|
|
16723
16740
|
const picked = new Set(opts.initialValues ?? []);
|
|
16724
|
-
const
|
|
16741
|
+
const suffixWidth = Math.max(0, ...opts.options.map((option) => {
|
|
16742
|
+
const texts = opts.statusFor ? [opts.statusFor(option.value, true), opts.statusFor(option.value, false)] : [option.hint];
|
|
16743
|
+
return Math.max(0, ...texts.map((text) => text ? visibleWidth(text) + 3 : 0));
|
|
16744
|
+
}));
|
|
16745
|
+
const maxLabel = Math.max(16, contentWidth(output.columns || 80) - 8 - suffixWidth);
|
|
16725
16746
|
const clipLabel = (text) => text.length <= maxLabel ? text : `…${text.slice(text.length - maxLabel + 1)}`;
|
|
16726
16747
|
const labelWidth = Math.max(...opts.options.map((o) => clipLabel(optionLabel(o)).length));
|
|
16727
16748
|
const pickedValues = () => opts.options.filter((option) => picked.has(option.value)).map((option) => option.value);
|
|
@@ -18346,7 +18367,7 @@ async function stepConnectGitHubRepo(cfg, detected = detectGitRepo(), opts = {})
|
|
|
18346
18367
|
}
|
|
18347
18368
|
repos = refresh.repos;
|
|
18348
18369
|
if (!refresh.foundNew) {
|
|
18349
|
-
log2.warn("GitHub may still be syncing. Pick 'Refresh list' in a moment to re-check; sync usually completes within a minute.");
|
|
18370
|
+
log2.warn(wrapLog("GitHub may still be syncing. Pick 'Refresh list' in a moment to re-check; sync usually completes within a minute."));
|
|
18350
18371
|
}
|
|
18351
18372
|
continue;
|
|
18352
18373
|
}
|
|
@@ -19806,14 +19827,18 @@ function recordCapturedSession(key, update, configDir = getConfigDir(), now = ne
|
|
|
19806
19827
|
return false;
|
|
19807
19828
|
}
|
|
19808
19829
|
}
|
|
19830
|
+
function cursorSessionId(hook) {
|
|
19831
|
+
const id = typeof hook.transcript_path === "string" && hook.transcript_path.endsWith(".jsonl") ? basename7(hook.transcript_path, ".jsonl") : hook.conversation_id;
|
|
19832
|
+
return typeof id === "string" ? id : null;
|
|
19833
|
+
}
|
|
19809
19834
|
function captureCursorStop(payload, deps = {}) {
|
|
19810
19835
|
if (typeof payload !== "object" || payload === null)
|
|
19811
19836
|
return false;
|
|
19812
19837
|
const hook = payload;
|
|
19813
19838
|
if (hook.cursor_version === undefined)
|
|
19814
19839
|
return false;
|
|
19815
|
-
const id =
|
|
19816
|
-
if (
|
|
19840
|
+
const id = cursorSessionId(hook);
|
|
19841
|
+
if (id === null)
|
|
19817
19842
|
return false;
|
|
19818
19843
|
const roots = hook.workspace_roots;
|
|
19819
19844
|
const dir = Array.isArray(roots) && typeof roots[0] === "string" ? roots[0] : undefined;
|
|
@@ -19894,6 +19919,17 @@ function piSessionShutdown(hook) {
|
|
|
19894
19919
|
return null;
|
|
19895
19920
|
return { harness: "pi", id, path };
|
|
19896
19921
|
}
|
|
19922
|
+
function cursorSessionEnd(hook) {
|
|
19923
|
+
if (hook.hook_event_name !== "sessionEnd" || hook.cursor_version === undefined)
|
|
19924
|
+
return null;
|
|
19925
|
+
const path = hook.transcript_path;
|
|
19926
|
+
if (typeof path !== "string" || !path.startsWith("/") || !path.endsWith(".jsonl"))
|
|
19927
|
+
return null;
|
|
19928
|
+
const id = basename7(path, ".jsonl");
|
|
19929
|
+
if (!SAFE_SEGMENT.test(id))
|
|
19930
|
+
return null;
|
|
19931
|
+
return { harness: "cursor", id, path };
|
|
19932
|
+
}
|
|
19897
19933
|
function endedSessionOf(payload) {
|
|
19898
19934
|
if (typeof payload !== "object" || payload === null)
|
|
19899
19935
|
return null;
|
|
@@ -19947,6 +19983,7 @@ var init_capture = __esm(() => {
|
|
|
19947
19983
|
END_EVENT_READERS = [
|
|
19948
19984
|
claudeSessionEnd,
|
|
19949
19985
|
codexSessionEnd,
|
|
19986
|
+
cursorSessionEnd,
|
|
19950
19987
|
piSessionShutdown
|
|
19951
19988
|
];
|
|
19952
19989
|
ENDED_VALUE = /^([a-z]+):([A-Za-z0-9._-]+)(?:=(\/.*))?$/s;
|
|
@@ -21945,7 +21982,8 @@ async function runKnowledgeSync(options = {}) {
|
|
|
21945
21982
|
offRecord = gate.ready.filter((s) => agentOff(s) && isUnanswered(s, state.sessions[sessionKey(s)]));
|
|
21946
21983
|
const gatedReady = gate.ready.filter((s) => !agentOff(s));
|
|
21947
21984
|
const gatedOpen = gate.open.filter((s) => !agentOff(s));
|
|
21948
|
-
const
|
|
21985
|
+
const scope = options.everyRepo && !deps.ship ? null : repoFilter;
|
|
21986
|
+
const inScope = (sessions) => filterSessionsByRepo(sessions, scope, (s) => locator.resolveRepo(s));
|
|
21949
21987
|
ready = inScope(holdBack === "backoff" ? gatedReady.filter(isEnded) : gatedReady);
|
|
21950
21988
|
open = inScope(gatedOpen);
|
|
21951
21989
|
if (holdBack === "backoff")
|
|
@@ -22019,22 +22057,47 @@ async function runKnowledgeSync(options = {}) {
|
|
|
22019
22057
|
failed: 0
|
|
22020
22058
|
};
|
|
22021
22059
|
const rank = (s) => ended.some((e) => namesSession(e, s)) ? 0 : isEnded(s) ? 1 : 2;
|
|
22022
|
-
const
|
|
22023
|
-
|
|
22024
|
-
logger.debug("sync", `shipping ${batch.length} of ${todo.length} ready sessions`);
|
|
22060
|
+
const batch = [...todo].sort((a, b) => rank(a) - rank(b) || Date.parse(a.updated) - Date.parse(b.updated));
|
|
22061
|
+
logger.debug("sync", `shipping ${batch.length} ready sessions`);
|
|
22025
22062
|
const hold = (s) => {
|
|
22026
22063
|
const current = loadState();
|
|
22027
22064
|
if (!isShippingEnabled(current))
|
|
22028
22065
|
return "stop";
|
|
22029
22066
|
return isAgentIncognito(current, s, lineage) ? "agent" : null;
|
|
22030
22067
|
};
|
|
22068
|
+
const saved = new Map;
|
|
22069
|
+
const reported = [];
|
|
22070
|
+
let savedShipped = 0;
|
|
22071
|
+
const settle = (result) => {
|
|
22072
|
+
reported.push(result);
|
|
22073
|
+
lock.refresh?.();
|
|
22074
|
+
const key = sessionKey(result.session);
|
|
22075
|
+
const entry = ledgerEntry(result, locked.sessions[key], now().toISOString(), cliVersion);
|
|
22076
|
+
if (!entry)
|
|
22077
|
+
return;
|
|
22078
|
+
saved.set(key, entry);
|
|
22079
|
+
try {
|
|
22080
|
+
const counted = result.outcome === "shipped" && !result.session.parentId ? 1 : 0;
|
|
22081
|
+
const next = loadState();
|
|
22082
|
+
next.sessions[key] = entry;
|
|
22083
|
+
next.total_shipped = (next.total_shipped ?? 0) + counted;
|
|
22084
|
+
next.run = run;
|
|
22085
|
+
saveState(next);
|
|
22086
|
+
savedShipped += counted;
|
|
22087
|
+
} catch {}
|
|
22088
|
+
};
|
|
22031
22089
|
let results = [];
|
|
22032
22090
|
if (batch.length > 0) {
|
|
22033
22091
|
try {
|
|
22034
|
-
results = await deps.ship(batch, (s) => shippedPrefix(locked.sessions[sessionKey(s)]), hold);
|
|
22092
|
+
results = await deps.ship(batch, (s) => shippedPrefix(locked.sessions[sessionKey(s)]), hold, settle);
|
|
22035
22093
|
} catch (err) {
|
|
22036
22094
|
const message = err instanceof Error ? err.message : String(err);
|
|
22037
|
-
|
|
22095
|
+
const answered = new Set(reported.map((r) => sessionKey(r.session)));
|
|
22096
|
+
const next = batch.find((s) => !answered.has(sessionKey(s)));
|
|
22097
|
+
results = [
|
|
22098
|
+
...reported,
|
|
22099
|
+
...next ? [{ session: next, outcome: "failed", message }] : []
|
|
22100
|
+
];
|
|
22038
22101
|
}
|
|
22039
22102
|
}
|
|
22040
22103
|
const resultOf = new Map(results.map((r) => [sessionKey(r.session), r]));
|
|
@@ -22050,7 +22113,7 @@ async function runKnowledgeSync(options = {}) {
|
|
|
22050
22113
|
counts[result.outcome] += 1;
|
|
22051
22114
|
else
|
|
22052
22115
|
counts.subagents[result.outcome] += 1;
|
|
22053
|
-
const entry = ledgerEntry(result, locked.sessions[key], at, cliVersion);
|
|
22116
|
+
const entry = saved.get(key) ?? ledgerEntry(result, locked.sessions[key], at, cliVersion);
|
|
22054
22117
|
if (!entry) {
|
|
22055
22118
|
error = result.message ?? "unknown error";
|
|
22056
22119
|
logger.debug("sync", `shipping failed at ${key}: ${error}`);
|
|
@@ -22077,7 +22140,7 @@ async function runKnowledgeSync(options = {}) {
|
|
|
22077
22140
|
if (batch.length > 0) {
|
|
22078
22141
|
next.last_attempt_at = at;
|
|
22079
22142
|
next.consecutive_failures = counts.failed > 0 ? next.consecutive_failures + 1 : 0;
|
|
22080
|
-
next.total_shipped = (next.total_shipped ?? 0) + counts.shipped;
|
|
22143
|
+
next.total_shipped = (next.total_shipped ?? 0) + counts.shipped - savedShipped;
|
|
22081
22144
|
next.run = run;
|
|
22082
22145
|
}
|
|
22083
22146
|
if (resumes)
|
|
@@ -22097,7 +22160,7 @@ async function runKnowledgeSync(options = {}) {
|
|
|
22097
22160
|
lock.release();
|
|
22098
22161
|
}
|
|
22099
22162
|
}
|
|
22100
|
-
var SCAN_WINDOW_DAYS = 30, LEDGER_GRACE_DAYS = 7,
|
|
22163
|
+
var SCAN_WINDOW_DAYS = 30, LEDGER_GRACE_DAYS = 7, DAY_MS, ENDED_LOCK_WAIT_MS, LOCK_POLL_MS = 2000, LOG_PREVIEW_LIMIT = 10;
|
|
22101
22164
|
var init_sync = __esm(() => {
|
|
22102
22165
|
init_logger();
|
|
22103
22166
|
init_lineage();
|
|
@@ -22178,7 +22241,7 @@ var init_backlog = __esm(() => {
|
|
|
22178
22241
|
});
|
|
22179
22242
|
|
|
22180
22243
|
// src/telemetry/debug-id.ts
|
|
22181
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
22244
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "38c8fa6e-6a2c-1ace-6475-6e2164756e21";
|
|
22182
22245
|
|
|
22183
22246
|
// src/telemetry/telemetry.ts
|
|
22184
22247
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -23147,10 +23210,6 @@ function isDirectory(path) {
|
|
|
23147
23210
|
return false;
|
|
23148
23211
|
}
|
|
23149
23212
|
}
|
|
23150
|
-
function saveScope(repos) {
|
|
23151
|
-
const { repo_filter: _repos, project_filter: _folders, ...rest } = loadSyncState();
|
|
23152
|
-
saveSyncState(repos ? { ...rest, repo_filter: repos } : rest);
|
|
23153
|
-
}
|
|
23154
23213
|
function scopeCommand() {
|
|
23155
23214
|
const cmd = new Command("scope").description("Show or set which repos' sessions ship to Dosu memory (the TUI's sync scope)");
|
|
23156
23215
|
cmd.command("show").description("Show the repos whose sessions ship").option("--json", "Output as JSON").action((opts) => {
|
|
@@ -23180,11 +23239,11 @@ function scopeCommand() {
|
|
|
23180
23239
|
repos.add(repo);
|
|
23181
23240
|
}
|
|
23182
23241
|
const sorted = [...repos].sort();
|
|
23183
|
-
|
|
23242
|
+
saveRepoFilter(sorted);
|
|
23184
23243
|
console.log(`✓ Sessions ship only from ${sorted.join(", ")}.`);
|
|
23185
23244
|
});
|
|
23186
23245
|
cmd.command("clear").description("Ship sessions from every repo, and sessions outside any repo").action(() => {
|
|
23187
|
-
|
|
23246
|
+
saveRepoFilter(null);
|
|
23188
23247
|
console.log("✓ Sessions from every repo ship, and sessions outside any repo.");
|
|
23189
23248
|
});
|
|
23190
23249
|
return cmd;
|
|
@@ -23484,6 +23543,152 @@ var init_session_start = __esm(() => {
|
|
|
23484
23543
|
init_normalize();
|
|
23485
23544
|
});
|
|
23486
23545
|
|
|
23546
|
+
// src/shipper/usage.ts
|
|
23547
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
23548
|
+
function isObject7(value) {
|
|
23549
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23550
|
+
}
|
|
23551
|
+
function str2(value) {
|
|
23552
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
23553
|
+
}
|
|
23554
|
+
function int(value) {
|
|
23555
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.trunc(value) : 0;
|
|
23556
|
+
}
|
|
23557
|
+
function parseLines(transcript) {
|
|
23558
|
+
const lines = [];
|
|
23559
|
+
for (const line of transcript.split(`
|
|
23560
|
+
`)) {
|
|
23561
|
+
if (line.trim() === "")
|
|
23562
|
+
continue;
|
|
23563
|
+
try {
|
|
23564
|
+
const value = JSON.parse(line);
|
|
23565
|
+
if (isObject7(value))
|
|
23566
|
+
lines.push(value);
|
|
23567
|
+
} catch {}
|
|
23568
|
+
}
|
|
23569
|
+
return lines;
|
|
23570
|
+
}
|
|
23571
|
+
function billed(request) {
|
|
23572
|
+
return request.input + request.output + request.cache_read + request.cache_write > 0 || request.tool_call_ids.length > 0;
|
|
23573
|
+
}
|
|
23574
|
+
function claudeUsage(transcript) {
|
|
23575
|
+
const requests = new Map;
|
|
23576
|
+
for (const line of parseLines(transcript)) {
|
|
23577
|
+
if (line.type !== "assistant" || !isObject7(line.message))
|
|
23578
|
+
continue;
|
|
23579
|
+
const message = line.message;
|
|
23580
|
+
const usage = message.usage;
|
|
23581
|
+
const id = str2(line.requestId) ?? str2(message.id) ?? str2(line.uuid);
|
|
23582
|
+
if (!isObject7(usage) || id === null)
|
|
23583
|
+
continue;
|
|
23584
|
+
const toolCallIds = Array.isArray(message.content) ? message.content.filter((block) => isObject7(block) && block.type === "tool_use").map((block) => str2(block.id)).filter((toolId) => toolId !== null) : [];
|
|
23585
|
+
const cacheCreation = isObject7(usage.cache_creation) ? usage.cache_creation : {};
|
|
23586
|
+
const entry = {
|
|
23587
|
+
id,
|
|
23588
|
+
model: str2(message.model),
|
|
23589
|
+
timestamp: str2(line.timestamp),
|
|
23590
|
+
input: int(usage.input_tokens),
|
|
23591
|
+
output: int(usage.output_tokens),
|
|
23592
|
+
cache_read: int(usage.cache_read_input_tokens),
|
|
23593
|
+
cache_write: int(usage.cache_creation_input_tokens),
|
|
23594
|
+
cache_write_1h: int(cacheCreation.ephemeral_1h_input_tokens),
|
|
23595
|
+
speed: str2(usage.speed),
|
|
23596
|
+
tool_call_ids: toolCallIds
|
|
23597
|
+
};
|
|
23598
|
+
const previous = requests.get(id);
|
|
23599
|
+
if (previous === undefined) {
|
|
23600
|
+
requests.set(id, entry);
|
|
23601
|
+
continue;
|
|
23602
|
+
}
|
|
23603
|
+
const latest = entry.output >= previous.output ? entry : previous;
|
|
23604
|
+
requests.set(id, {
|
|
23605
|
+
...latest,
|
|
23606
|
+
timestamp: entry.timestamp ?? previous.timestamp,
|
|
23607
|
+
tool_call_ids: [...new Set([...previous.tool_call_ids, ...entry.tool_call_ids])]
|
|
23608
|
+
});
|
|
23609
|
+
}
|
|
23610
|
+
return [...requests.values()].filter(billed);
|
|
23611
|
+
}
|
|
23612
|
+
function codexUsage(transcript) {
|
|
23613
|
+
const requests = [];
|
|
23614
|
+
let model = null;
|
|
23615
|
+
let ownSessionId = null;
|
|
23616
|
+
let historyStart = null;
|
|
23617
|
+
let lastTotal = null;
|
|
23618
|
+
let toolCallIds = [];
|
|
23619
|
+
for (const line of parseLines(transcript)) {
|
|
23620
|
+
const payload = isObject7(line.payload) ? line.payload : {};
|
|
23621
|
+
const ordinal = typeof line.ordinal === "number" ? line.ordinal : null;
|
|
23622
|
+
if (historyStart !== null && ordinal !== null && ordinal < historyStart)
|
|
23623
|
+
continue;
|
|
23624
|
+
if (line.type === "session_meta") {
|
|
23625
|
+
const metaId = str2(payload.id);
|
|
23626
|
+
if (ownSessionId === null) {
|
|
23627
|
+
ownSessionId = metaId;
|
|
23628
|
+
if (str2(payload.forked_from_id) !== null) {
|
|
23629
|
+
const start = payload.subagent_history_start_ordinal;
|
|
23630
|
+
historyStart = typeof start === "number" ? start : null;
|
|
23631
|
+
}
|
|
23632
|
+
}
|
|
23633
|
+
} else if (line.type === "turn_context") {
|
|
23634
|
+
model = str2(payload.model) ?? model;
|
|
23635
|
+
} else if (line.type === "response_item") {
|
|
23636
|
+
const callId = str2(payload.call_id);
|
|
23637
|
+
if (callId !== null && typeof payload.type === "string" && payload.type.endsWith("_call")) {
|
|
23638
|
+
toolCallIds.push(callId);
|
|
23639
|
+
}
|
|
23640
|
+
} else if (line.type === "event_msg" && payload.type === "token_count") {
|
|
23641
|
+
const info = isObject7(payload.info) ? payload.info : null;
|
|
23642
|
+
const last = info && isObject7(info.last_token_usage) ? info.last_token_usage : null;
|
|
23643
|
+
const total = info && isObject7(info.total_token_usage) ? info.total_token_usage : null;
|
|
23644
|
+
if (last === null || total === null)
|
|
23645
|
+
continue;
|
|
23646
|
+
const runningTotal = int(total.total_tokens);
|
|
23647
|
+
if (runningTotal === lastTotal)
|
|
23648
|
+
continue;
|
|
23649
|
+
lastTotal = runningTotal;
|
|
23650
|
+
const input = int(last.input_tokens);
|
|
23651
|
+
const cached = int(last.cached_input_tokens);
|
|
23652
|
+
const cacheWrite = int(last.cache_write_input_tokens);
|
|
23653
|
+
const disjoint = cached + cacheWrite <= input;
|
|
23654
|
+
const request = {
|
|
23655
|
+
id: `codex:${runningTotal}`,
|
|
23656
|
+
model,
|
|
23657
|
+
timestamp: str2(line.timestamp),
|
|
23658
|
+
input: Math.max(0, input - cached - (disjoint ? cacheWrite : 0)),
|
|
23659
|
+
output: int(last.output_tokens),
|
|
23660
|
+
cache_read: cached,
|
|
23661
|
+
cache_write: disjoint ? cacheWrite : 0,
|
|
23662
|
+
cache_write_1h: 0,
|
|
23663
|
+
speed: null,
|
|
23664
|
+
tool_call_ids: toolCallIds
|
|
23665
|
+
};
|
|
23666
|
+
toolCallIds = [];
|
|
23667
|
+
if (billed(request))
|
|
23668
|
+
requests.push(request);
|
|
23669
|
+
}
|
|
23670
|
+
}
|
|
23671
|
+
return requests;
|
|
23672
|
+
}
|
|
23673
|
+
function readSessionUsage(session) {
|
|
23674
|
+
const reader = READERS[session.harness];
|
|
23675
|
+
if (!reader)
|
|
23676
|
+
return null;
|
|
23677
|
+
try {
|
|
23678
|
+
const requests = reader(readFileSync25(session.path, "utf8"));
|
|
23679
|
+
return requests.length > 0 ? { requests } : null;
|
|
23680
|
+
} catch {
|
|
23681
|
+
return null;
|
|
23682
|
+
}
|
|
23683
|
+
}
|
|
23684
|
+
var READERS;
|
|
23685
|
+
var init_usage = __esm(() => {
|
|
23686
|
+
READERS = {
|
|
23687
|
+
claude: claudeUsage,
|
|
23688
|
+
codex: codexUsage
|
|
23689
|
+
};
|
|
23690
|
+
});
|
|
23691
|
+
|
|
23487
23692
|
// src/shipper/worthiness.ts
|
|
23488
23693
|
function isTrivialTrajectory(records) {
|
|
23489
23694
|
let asked = false;
|
|
@@ -23513,6 +23718,7 @@ function createShipStep(options) {
|
|
|
23513
23718
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
23514
23719
|
const isIncognito = options.isIncognito ?? isIncognitoSession;
|
|
23515
23720
|
const normalize = options.normalize ?? normalizeSessionRecords;
|
|
23721
|
+
const readUsage = options.readUsage ?? readSessionUsage;
|
|
23516
23722
|
async function shipOne(session, shipped, resolve, hold) {
|
|
23517
23723
|
const held = hold(session);
|
|
23518
23724
|
if (held === "stop")
|
|
@@ -23542,18 +23748,21 @@ function createShipStep(options) {
|
|
|
23542
23748
|
const start = sessionStartOf(records, copied);
|
|
23543
23749
|
const branch = start.recorded ?? resolve.resolveBranch(session, start.firstPromptAt);
|
|
23544
23750
|
const parentSessionId = session.parentId ?? session.forkOf?.id;
|
|
23751
|
+
const repo = githubSlugOfRepo(resolve.resolveRepo(session));
|
|
23752
|
+
const usage = readUsage(session);
|
|
23545
23753
|
const body = JSON.stringify({
|
|
23546
23754
|
records: plan.records,
|
|
23547
23755
|
metadata: {
|
|
23548
23756
|
deployment_id: options.deploymentId,
|
|
23549
23757
|
project,
|
|
23550
|
-
repo:
|
|
23758
|
+
...repo ? { repo } : {},
|
|
23551
23759
|
agent: trajectorySourceOf(session.harness) ?? session.harness,
|
|
23552
23760
|
session_id: session.id,
|
|
23553
23761
|
...branch ? { branch } : {},
|
|
23554
23762
|
...parentSessionId ? { parent_session_id: parentSessionId } : {},
|
|
23555
23763
|
...plan.continuation ? { continuation: plan.continuation } : {}
|
|
23556
|
-
}
|
|
23764
|
+
},
|
|
23765
|
+
...usage ? { usage } : {}
|
|
23557
23766
|
});
|
|
23558
23767
|
const late = hold(session);
|
|
23559
23768
|
if (late === "stop")
|
|
@@ -23598,11 +23807,12 @@ function createShipStep(options) {
|
|
|
23598
23807
|
}
|
|
23599
23808
|
return async (sessions, shippedOf = () => {
|
|
23600
23809
|
return;
|
|
23601
|
-
}, hold = () => null) => {
|
|
23602
|
-
const resolver = options.resolveProject && options.resolveBranch ? undefined : createProjectDirResolver();
|
|
23810
|
+
}, hold = () => null, settled = () => {}) => {
|
|
23811
|
+
const resolver = options.resolveProject && options.resolveBranch && options.resolveRepo ? undefined : createProjectDirResolver();
|
|
23603
23812
|
const resolve = {
|
|
23604
23813
|
resolveProject: options.resolveProject ?? ((session) => resolver?.resolveProject(session) ?? null),
|
|
23605
|
-
resolveBranch: options.resolveBranch ?? ((session, at) => resolver?.resolveBranch(session, at) ?? null)
|
|
23814
|
+
resolveBranch: options.resolveBranch ?? ((session, at) => resolver?.resolveBranch(session, at) ?? null),
|
|
23815
|
+
resolveRepo: options.resolveRepo ?? ((session) => resolver?.resolveRepo(session) ?? null)
|
|
23606
23816
|
};
|
|
23607
23817
|
const results = [];
|
|
23608
23818
|
for (const session of sessions) {
|
|
@@ -23610,6 +23820,7 @@ function createShipStep(options) {
|
|
|
23610
23820
|
if (!result)
|
|
23611
23821
|
break;
|
|
23612
23822
|
results.push(result);
|
|
23823
|
+
settled(result);
|
|
23613
23824
|
if (result.outcome === "failed")
|
|
23614
23825
|
break;
|
|
23615
23826
|
}
|
|
@@ -23620,16 +23831,18 @@ function createShipStep(options) {
|
|
|
23620
23831
|
var REJECTED_STATUSES, REQUEST_TIMEOUT_MS2 = 60000;
|
|
23621
23832
|
var init_runner = __esm(() => {
|
|
23622
23833
|
init_project_dir();
|
|
23834
|
+
init_repo();
|
|
23623
23835
|
init_incognito();
|
|
23624
23836
|
init_continuation();
|
|
23625
23837
|
init_normalize();
|
|
23626
23838
|
init_session_start();
|
|
23839
|
+
init_usage();
|
|
23627
23840
|
REJECTED_STATUSES = new Set([400, 413, 422]);
|
|
23628
23841
|
});
|
|
23629
23842
|
|
|
23630
23843
|
// src/memory/context-hook.ts
|
|
23631
23844
|
import { basename as basename10 } from "node:path";
|
|
23632
|
-
function
|
|
23845
|
+
function str3(value) {
|
|
23633
23846
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
23634
23847
|
}
|
|
23635
23848
|
function harnessOf(agent) {
|
|
@@ -23667,10 +23880,10 @@ function incognitoCheckOf(agent) {
|
|
|
23667
23880
|
return transcriptHasIncognitoMarker;
|
|
23668
23881
|
}
|
|
23669
23882
|
function sessionIdOf(payload, format) {
|
|
23670
|
-
const transcript =
|
|
23883
|
+
const transcript = str3(payload.transcript_path);
|
|
23671
23884
|
if (format === "codex" && transcript?.endsWith(".jsonl"))
|
|
23672
23885
|
return basename10(transcript, ".jsonl");
|
|
23673
|
-
return
|
|
23886
|
+
return str3(payload.session_id);
|
|
23674
23887
|
}
|
|
23675
23888
|
function claudeCaller(id, transcript, agentId) {
|
|
23676
23889
|
if (!agentId)
|
|
@@ -23689,7 +23902,7 @@ function outsideIncognitoSession(stdin, options) {
|
|
|
23689
23902
|
const id = sessionIdOf(payload, options.format ?? "claude");
|
|
23690
23903
|
if (!id)
|
|
23691
23904
|
return null;
|
|
23692
|
-
const stored = storedSession2({ harness, id, transcript:
|
|
23905
|
+
const stored = storedSession2({ harness, id, transcript: str3(payload.transcript_path) });
|
|
23693
23906
|
if (!stored || scannedEverywhere(harness, stored.path))
|
|
23694
23907
|
return null;
|
|
23695
23908
|
return options.incognito.sessions[`${harness}/${id}`]?.by_agent ? null : stored;
|
|
@@ -23709,16 +23922,16 @@ function denial(reason) {
|
|
|
23709
23922
|
function memoryToolHookOutput(payload, isIncognito, incognito) {
|
|
23710
23923
|
if (typeof payload.tool_name !== "string" || !MEMORY_TOOL.test(payload.tool_name))
|
|
23711
23924
|
return "";
|
|
23712
|
-
const transcript =
|
|
23713
|
-
const id =
|
|
23925
|
+
const transcript = str3(payload.transcript_path);
|
|
23926
|
+
const id = str3(payload.session_id);
|
|
23714
23927
|
const how = incognito ? agentSwitchOf(incognito, { harness: "claude", id }, () => id && transcript ? sessionAtPath("claude", id, transcript) : null) : null;
|
|
23715
23928
|
if (how)
|
|
23716
23929
|
return denial(agentSwitchMessage(how, "claude", TOOLS_UNAVAILABLE));
|
|
23717
23930
|
if (transcript && isIncognito(transcript))
|
|
23718
23931
|
return denial(INCOGNITO_DENIAL);
|
|
23719
|
-
const toolUseId =
|
|
23932
|
+
const toolUseId = str3(payload.tool_use_id);
|
|
23720
23933
|
if (toolUseId && id) {
|
|
23721
|
-
recordClaudeToolCall(toolUseId, claudeCaller(id, transcript,
|
|
23934
|
+
recordClaudeToolCall(toolUseId, claudeCaller(id, transcript, str3(payload.agent_id)));
|
|
23722
23935
|
}
|
|
23723
23936
|
return "";
|
|
23724
23937
|
}
|
|
@@ -23736,7 +23949,7 @@ async function contextHookOutput(stdin, options) {
|
|
|
23736
23949
|
}
|
|
23737
23950
|
if (format !== "plain" && payload.hook_event_name !== "UserPromptSubmit")
|
|
23738
23951
|
return "";
|
|
23739
|
-
const prompt =
|
|
23952
|
+
const prompt = str3(payload.prompt);
|
|
23740
23953
|
if (!prompt || NOTIFICATION_PROMPT.test(prompt))
|
|
23741
23954
|
return "";
|
|
23742
23955
|
if (textHasIncognitoMarker(prompt) || promptRunsIncognito(prompt))
|
|
@@ -23744,14 +23957,14 @@ async function contextHookOutput(stdin, options) {
|
|
|
23744
23957
|
const agent = options.agent ?? CLAUDE_CODE_AGENT;
|
|
23745
23958
|
const harness = harnessOf(agent);
|
|
23746
23959
|
const sessionId = sessionIdOf(payload, format);
|
|
23747
|
-
const transcript =
|
|
23960
|
+
const transcript = str3(payload.transcript_path);
|
|
23748
23961
|
const switchedOff = harness && options.incognito ? agentSwitchOf(options.incognito, { harness, id: sessionId }, () => sessionId ? storedSession2({ harness, id: sessionId, transcript }) : null) : null;
|
|
23749
23962
|
if (switchedOff)
|
|
23750
23963
|
return "";
|
|
23751
23964
|
const isIncognito = options.isIncognito ?? incognitoCheckOf(agent);
|
|
23752
23965
|
if (transcript && isIncognito(transcript))
|
|
23753
23966
|
return "";
|
|
23754
|
-
const cwd =
|
|
23967
|
+
const cwd = str3(payload.cwd);
|
|
23755
23968
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
23756
23969
|
const budgetMs = options.timeoutMs ?? CONTEXT_TIMEOUT_MS;
|
|
23757
23970
|
const startedAt = Date.now();
|
|
@@ -23779,9 +23992,9 @@ async function contextHookOutput(stdin, options) {
|
|
|
23779
23992
|
return "";
|
|
23780
23993
|
}
|
|
23781
23994
|
const body = await response.json();
|
|
23782
|
-
const digest =
|
|
23995
|
+
const digest = str3(body.digest);
|
|
23783
23996
|
if (!digest) {
|
|
23784
|
-
note(`no digest, ${
|
|
23997
|
+
note(`no digest, ${str3(body.reason) ?? "none"}`);
|
|
23785
23998
|
return "";
|
|
23786
23999
|
}
|
|
23787
24000
|
const count = Array.isArray(body.memory_ids) ? body.memory_ids.length : 0;
|
|
@@ -23813,7 +24026,7 @@ var init_context_hook = __esm(() => {
|
|
|
23813
24026
|
});
|
|
23814
24027
|
|
|
23815
24028
|
// src/commands/knowledge.ts
|
|
23816
|
-
import { readFileSync as
|
|
24029
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
23817
24030
|
function collectValues(value, previous = []) {
|
|
23818
24031
|
return [...previous, value];
|
|
23819
24032
|
}
|
|
@@ -23999,21 +24212,11 @@ ${results.length - opts.limit} more results not shown.`));
|
|
|
23999
24212
|
...opts.retryRejected ? { retryRejectedBefore: new Date } : {},
|
|
24000
24213
|
deps
|
|
24001
24214
|
};
|
|
24002
|
-
|
|
24003
|
-
let sessionsShipped = outcome.counts?.shipped ?? 0;
|
|
24004
|
-
if ((opts.bootstrap || opts.flush) && deps.ship) {
|
|
24005
|
-
const maxRounds = Math.ceil(outcome.readySessions / SHIP_BATCH_LIMIT) + 2;
|
|
24006
|
-
for (let round = 1;outcome.status === "shipped" && (outcome.settledSessions ?? 0) > 0 && (outcome.settledSessions ?? 0) < outcome.readySessions && round < maxRounds; round++) {
|
|
24007
|
-
if (!opts.quiet && !opts.json)
|
|
24008
|
-
printSyncOutcome(outcome);
|
|
24009
|
-
outcome = await runKnowledgeSync(syncOptions);
|
|
24010
|
-
sessionsShipped += outcome.counts?.shipped ?? 0;
|
|
24011
|
-
}
|
|
24012
|
-
}
|
|
24215
|
+
const outcome = await runKnowledgeSync(syncOptions);
|
|
24013
24216
|
recordCommandFacets({
|
|
24014
24217
|
sync_trigger: trigger,
|
|
24015
24218
|
sync_status: outcome.status,
|
|
24016
|
-
sessions_shipped:
|
|
24219
|
+
sessions_shipped: outcome.counts?.shipped ?? 0
|
|
24017
24220
|
});
|
|
24018
24221
|
if (opts.quiet)
|
|
24019
24222
|
return;
|
|
@@ -24080,7 +24283,7 @@ function buildShipper() {
|
|
|
24080
24283
|
};
|
|
24081
24284
|
}
|
|
24082
24285
|
function readStdin3() {
|
|
24083
|
-
return
|
|
24286
|
+
return readFileSync26(0, "utf-8");
|
|
24084
24287
|
}
|
|
24085
24288
|
function contextCommand2() {
|
|
24086
24289
|
return new Command("context").description("Prompt-submit hook: add task memory to the agent's context").option("--agent <source>", "Trajectory source the session ships as", "claude-code").option("--format <format>", "Output: claude or codex hook JSON, or plain digest text", "claude").action(async (opts) => {
|
|
@@ -24345,9 +24548,9 @@ function printSyncOutcome(outcome) {
|
|
|
24345
24548
|
process.exitCode = 1;
|
|
24346
24549
|
break;
|
|
24347
24550
|
}
|
|
24348
|
-
|
|
24349
|
-
|
|
24350
|
-
console.log(import_picocolors23.default.dim(`${
|
|
24551
|
+
if (outcome.inFlightSessions > 0) {
|
|
24552
|
+
const n = outcome.inFlightSessions;
|
|
24553
|
+
console.log(import_picocolors23.default.dim(`${n} session${plural(n)} still in progress will ship once ${n === 1 ? "it ends" : "they end"}.`));
|
|
24351
24554
|
}
|
|
24352
24555
|
break;
|
|
24353
24556
|
}
|
|
@@ -24804,17 +25007,17 @@ var init_members = __esm(() => {
|
|
|
24804
25007
|
});
|
|
24805
25008
|
|
|
24806
25009
|
// src/mcp/relay.ts
|
|
24807
|
-
function
|
|
25010
|
+
function isObject8(value) {
|
|
24808
25011
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24809
25012
|
}
|
|
24810
25013
|
function messagesOf(value) {
|
|
24811
25014
|
return Array.isArray(value) ? value : [value];
|
|
24812
25015
|
}
|
|
24813
25016
|
function requestIds(message) {
|
|
24814
|
-
return messagesOf(message).flatMap((m) =>
|
|
25017
|
+
return messagesOf(message).flatMap((m) => isObject8(m) && typeof m.method === "string" && (typeof m.id === "string" || typeof m.id === "number") ? [m.id] : []);
|
|
24815
25018
|
}
|
|
24816
25019
|
function responseIds(message) {
|
|
24817
|
-
return messagesOf(message).flatMap((m) =>
|
|
25020
|
+
return messagesOf(message).flatMap((m) => isObject8(m) && (typeof m.id === "string" || typeof m.id === "number") && (("result" in m) || ("error" in m)) ? [m.id] : []);
|
|
24818
25021
|
}
|
|
24819
25022
|
function transportError(id, message) {
|
|
24820
25023
|
return { jsonrpc: "2.0", id, error: { code: TRANSPORT_ERROR, message } };
|
|
@@ -24822,9 +25025,9 @@ function transportError(id, message) {
|
|
|
24822
25025
|
function errorDetail(body) {
|
|
24823
25026
|
try {
|
|
24824
25027
|
const parsed = JSON.parse(body);
|
|
24825
|
-
if (
|
|
25028
|
+
if (isObject8(parsed)) {
|
|
24826
25029
|
const { error, error_description, detail } = parsed;
|
|
24827
|
-
if (
|
|
25030
|
+
if (isObject8(error) && typeof error.message === "string")
|
|
24828
25031
|
return error.message;
|
|
24829
25032
|
if (typeof error_description === "string")
|
|
24830
25033
|
return error_description;
|
|
@@ -24839,7 +25042,7 @@ function errorDetail(body) {
|
|
|
24839
25042
|
function jsonRpcErrorBody(body, ids) {
|
|
24840
25043
|
try {
|
|
24841
25044
|
const parsed = JSON.parse(body);
|
|
24842
|
-
if (
|
|
25045
|
+
if (isObject8(parsed) && isObject8(parsed.error) && ids.includes(parsed.id)) {
|
|
24843
25046
|
return parsed;
|
|
24844
25047
|
}
|
|
24845
25048
|
} catch {}
|
|
@@ -24933,9 +25136,9 @@ function createMcpRelay(options) {
|
|
|
24933
25136
|
return out;
|
|
24934
25137
|
}
|
|
24935
25138
|
function noteInitialized(sent, reply) {
|
|
24936
|
-
const initializeIds = messagesOf(sent).flatMap((m) =>
|
|
25139
|
+
const initializeIds = messagesOf(sent).flatMap((m) => isObject8(m) && m.method === "initialize" ? [m.id] : []);
|
|
24937
25140
|
for (const m of messagesOf(reply)) {
|
|
24938
|
-
if (!
|
|
25141
|
+
if (!isObject8(m) || !initializeIds.includes(m.id) || !isObject8(m.result))
|
|
24939
25142
|
continue;
|
|
24940
25143
|
if (typeof m.result.protocolVersion === "string")
|
|
24941
25144
|
protocolVersion = m.result.protocolVersion;
|
|
@@ -25060,13 +25263,13 @@ function openSession(options) {
|
|
|
25060
25263
|
function proxyRelay(options = {}) {
|
|
25061
25264
|
return openSession(options).relay;
|
|
25062
25265
|
}
|
|
25063
|
-
function
|
|
25266
|
+
function isObject9(value) {
|
|
25064
25267
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25065
25268
|
}
|
|
25066
25269
|
function firstRootDir(answer) {
|
|
25067
|
-
const roots =
|
|
25270
|
+
const roots = isObject9(answer.result) ? answer.result.roots : undefined;
|
|
25068
25271
|
for (const root of Array.isArray(roots) ? roots : []) {
|
|
25069
|
-
if (!
|
|
25272
|
+
if (!isObject9(root) || typeof root.uri !== "string" || !root.uri.startsWith("file:"))
|
|
25070
25273
|
continue;
|
|
25071
25274
|
try {
|
|
25072
25275
|
return fileURLToPath3(root.uri);
|
|
@@ -25100,10 +25303,10 @@ async function serveStdio(session, input, write) {
|
|
|
25100
25303
|
emit({ jsonrpc: "2.0", id: ROOTS_REQUEST_ID, method: "roots/list" });
|
|
25101
25304
|
};
|
|
25102
25305
|
const screen = (message) => {
|
|
25103
|
-
const call =
|
|
25306
|
+
const call = isObject9(message) && message.method === "tools/call" ? message : null;
|
|
25104
25307
|
if (!call)
|
|
25105
25308
|
return { callSession: null, refusal: null };
|
|
25106
|
-
const callSession =
|
|
25309
|
+
const callSession = isObject9(call.params) ? takeCallSession(call.params, session.client) : null;
|
|
25107
25310
|
const text = callRefusal(session.client, callSession ? [callSession] : []);
|
|
25108
25311
|
if (!text)
|
|
25109
25312
|
return { callSession, refusal: null };
|
|
@@ -25128,14 +25331,14 @@ async function serveStdio(session, input, write) {
|
|
|
25128
25331
|
emit(PARSE_ERROR);
|
|
25129
25332
|
return;
|
|
25130
25333
|
}
|
|
25131
|
-
const method =
|
|
25132
|
-
if (takeRoots &&
|
|
25334
|
+
const method = isObject9(message) ? message.method : undefined;
|
|
25335
|
+
if (takeRoots && isObject9(message) && message.id === ROOTS_REQUEST_ID && !method) {
|
|
25133
25336
|
takeRoots(message);
|
|
25134
25337
|
return;
|
|
25135
25338
|
}
|
|
25136
|
-
if (method === "initialize" &&
|
|
25137
|
-
const params =
|
|
25138
|
-
agentOffersRoots =
|
|
25339
|
+
if (method === "initialize" && isObject9(message)) {
|
|
25340
|
+
const params = isObject9(message.params) ? message.params : {};
|
|
25341
|
+
agentOffersRoots = isObject9(params.capabilities) && isObject9(params.capabilities.roots);
|
|
25139
25342
|
}
|
|
25140
25343
|
let outgoing = message;
|
|
25141
25344
|
let named = null;
|
|
@@ -25375,12 +25578,12 @@ var init_org = __esm(() => {
|
|
|
25375
25578
|
});
|
|
25376
25579
|
|
|
25377
25580
|
// src/sessions/project-links.ts
|
|
25378
|
-
import { existsSync as existsSync19, readFileSync as
|
|
25581
|
+
import { existsSync as existsSync19, readFileSync as readFileSync27 } from "node:fs";
|
|
25379
25582
|
function readLinksFile(configDir) {
|
|
25380
25583
|
const path = projectLinksPath(configDir);
|
|
25381
25584
|
if (!existsSync19(path))
|
|
25382
25585
|
return { links: [] };
|
|
25383
|
-
const raw =
|
|
25586
|
+
const raw = readFileSync27(path, "utf-8").trim();
|
|
25384
25587
|
if (!raw)
|
|
25385
25588
|
return { links: [] };
|
|
25386
25589
|
let parsed;
|
|
@@ -25829,7 +26032,7 @@ var init_time_range = __esm(() => {
|
|
|
25829
26032
|
});
|
|
25830
26033
|
|
|
25831
26034
|
// src/commands/review.ts
|
|
25832
|
-
import { readFileSync as
|
|
26035
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
25833
26036
|
function requireConfig10() {
|
|
25834
26037
|
return requireLoginConfig();
|
|
25835
26038
|
}
|
|
@@ -26067,7 +26270,7 @@ function reviewCommand() {
|
|
|
26067
26270
|
let body = opts.body;
|
|
26068
26271
|
if (opts.bodyFile) {
|
|
26069
26272
|
try {
|
|
26070
|
-
body =
|
|
26273
|
+
body = readFileSync28(opts.bodyFile, "utf-8");
|
|
26071
26274
|
} catch (err) {
|
|
26072
26275
|
throw invalidArgument(`Failed to read --body-file: ${err.message}`);
|
|
26073
26276
|
}
|
|
@@ -27011,7 +27214,7 @@ import {
|
|
|
27011
27214
|
existsSync as existsSync20,
|
|
27012
27215
|
lstatSync,
|
|
27013
27216
|
mkdirSync as mkdirSync12,
|
|
27014
|
-
readFileSync as
|
|
27217
|
+
readFileSync as readFileSync29,
|
|
27015
27218
|
rmSync as rmSync4,
|
|
27016
27219
|
symlinkSync,
|
|
27017
27220
|
writeFileSync as writeFileSync13
|
|
@@ -27034,8 +27237,6 @@ function linkedSkillsDir(agent) {
|
|
|
27034
27237
|
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR?.trim() || join24(homedir9(), ".claude");
|
|
27035
27238
|
return join24(claudeConfigDir, "skills");
|
|
27036
27239
|
}
|
|
27037
|
-
if (agent === "windsurf")
|
|
27038
|
-
return join24(homedir9(), ".codeium", "windsurf", "skills");
|
|
27039
27240
|
return null;
|
|
27040
27241
|
}
|
|
27041
27242
|
function skillInstallTargetForProvider(providerID) {
|
|
@@ -27055,7 +27256,7 @@ function readSkillInstallState() {
|
|
|
27055
27256
|
const path = installStatePath();
|
|
27056
27257
|
if (!existsSync20(path))
|
|
27057
27258
|
return null;
|
|
27058
|
-
const data = JSON.parse(
|
|
27259
|
+
const data = JSON.parse(readFileSync29(path, "utf-8"));
|
|
27059
27260
|
if (typeof data?.version === "string" && Array.isArray(data.agents) && data.agents.every((agent) => typeof agent === "string") && typeof data.installedAt === "number") {
|
|
27060
27261
|
return { version: data.version, agents: data.agents, installedAt: data.installedAt };
|
|
27061
27262
|
}
|
|
@@ -27082,7 +27283,7 @@ function pruneLegacySkillLock() {
|
|
|
27082
27283
|
try {
|
|
27083
27284
|
if (!existsSync20(lockPath))
|
|
27084
27285
|
return [];
|
|
27085
|
-
const lock = JSON.parse(
|
|
27286
|
+
const lock = JSON.parse(readFileSync29(lockPath, "utf-8"));
|
|
27086
27287
|
const skills = lock?.skills;
|
|
27087
27288
|
if (!skills || typeof skills !== "object")
|
|
27088
27289
|
return [];
|
|
@@ -27186,7 +27387,10 @@ function removeSkills() {
|
|
|
27186
27387
|
const names = new Set([...BUNDLED_SKILLS.map((skill) => skill.name), ...legacy]);
|
|
27187
27388
|
const dirs = [
|
|
27188
27389
|
universalSkillsDir(),
|
|
27189
|
-
...new Set(
|
|
27390
|
+
...new Set([
|
|
27391
|
+
...SUPPORTED_SKILL_AGENTS.map(linkedSkillsDir).filter((dir) => !!dir),
|
|
27392
|
+
...LEGACY_LINKED_SKILLS_DIRS.map((dir) => dir())
|
|
27393
|
+
])
|
|
27190
27394
|
];
|
|
27191
27395
|
const removed = [];
|
|
27192
27396
|
for (const dir of dirs) {
|
|
@@ -27252,7 +27456,7 @@ Failed to update skill.`));
|
|
|
27252
27456
|
});
|
|
27253
27457
|
return cmd;
|
|
27254
27458
|
}
|
|
27255
|
-
var import_picocolors31, SKILL_NAME = "dosu", LEGACY_SKILL_SOURCE = "dosu-ai/dosu-skill", INSTALL_STATE_FILENAME = "skill-install.json", LEGACY_CACHE_FILENAME = "skill-update-check.json", SUPPORTED_SKILL_AGENTS, SKILL_AGENT_BY_PROVIDER;
|
|
27459
|
+
var import_picocolors31, SKILL_NAME = "dosu", LEGACY_SKILL_SOURCE = "dosu-ai/dosu-skill", INSTALL_STATE_FILENAME = "skill-install.json", LEGACY_CACHE_FILENAME = "skill-update-check.json", SUPPORTED_SKILL_AGENTS, SKILL_AGENT_BY_PROVIDER, LEGACY_LINKED_SKILLS_DIRS;
|
|
27256
27460
|
var init_skill = __esm(() => {
|
|
27257
27461
|
init_commander();
|
|
27258
27462
|
init_config();
|
|
@@ -27264,27 +27468,20 @@ var init_skill = __esm(() => {
|
|
|
27264
27468
|
"cursor",
|
|
27265
27469
|
"gemini-cli",
|
|
27266
27470
|
"codex",
|
|
27267
|
-
"windsurf",
|
|
27268
|
-
"zed",
|
|
27269
|
-
"cline",
|
|
27270
27471
|
"github-copilot",
|
|
27271
|
-
"opencode"
|
|
27272
|
-
"antigravity"
|
|
27472
|
+
"opencode"
|
|
27273
27473
|
];
|
|
27274
27474
|
SKILL_AGENT_BY_PROVIDER = {
|
|
27275
27475
|
claude: "claude-code",
|
|
27276
27476
|
cursor: "cursor",
|
|
27277
|
-
vscode: "github-copilot",
|
|
27278
27477
|
gemini: "gemini-cli",
|
|
27279
27478
|
codex: "codex",
|
|
27280
|
-
windsurf: "windsurf",
|
|
27281
|
-
zed: "zed",
|
|
27282
|
-
cline: "cline",
|
|
27283
|
-
"cline-cli": "cline",
|
|
27284
27479
|
copilot: "github-copilot",
|
|
27285
|
-
opencode: "opencode"
|
|
27286
|
-
antigravity: "antigravity"
|
|
27480
|
+
opencode: "opencode"
|
|
27287
27481
|
};
|
|
27482
|
+
LEGACY_LINKED_SKILLS_DIRS = [
|
|
27483
|
+
() => join24(homedir9(), ".codeium", "windsurf", "skills")
|
|
27484
|
+
];
|
|
27288
27485
|
});
|
|
27289
27486
|
|
|
27290
27487
|
// src/commands/sources.ts
|
|
@@ -27555,7 +27752,7 @@ import {
|
|
|
27555
27752
|
existsSync as existsSync21,
|
|
27556
27753
|
lstatSync as lstatSync2,
|
|
27557
27754
|
mkdirSync as mkdirSync13,
|
|
27558
|
-
readFileSync as
|
|
27755
|
+
readFileSync as readFileSync30,
|
|
27559
27756
|
renameSync as renameSync5,
|
|
27560
27757
|
unlinkSync as unlinkSync6,
|
|
27561
27758
|
writeFileSync as writeFileSync14
|
|
@@ -27630,7 +27827,7 @@ function readTelemetrySettings() {
|
|
|
27630
27827
|
}
|
|
27631
27828
|
let content;
|
|
27632
27829
|
try {
|
|
27633
|
-
content =
|
|
27830
|
+
content = readFileSync30(path, "utf-8");
|
|
27634
27831
|
} catch {
|
|
27635
27832
|
return { status: "error", settings: disabledTelemetrySettings() };
|
|
27636
27833
|
}
|
|
@@ -28114,24 +28311,6 @@ var init_base = __esm(() => {
|
|
|
28114
28311
|
init_shape();
|
|
28115
28312
|
});
|
|
28116
28313
|
|
|
28117
|
-
// src/mcp/providers/antigravity.ts
|
|
28118
|
-
var AntigravityProvider = () => createJSONProvider({
|
|
28119
|
-
providerName: "Antigravity",
|
|
28120
|
-
providerID: "antigravity",
|
|
28121
|
-
local: false,
|
|
28122
|
-
priorityValue: 15,
|
|
28123
|
-
paths: ["~/.gemini"],
|
|
28124
|
-
globalPath: "~/.gemini/antigravity/mcp_config.json",
|
|
28125
|
-
topKey: "mcpServers",
|
|
28126
|
-
buildServer: ({ url, headers }) => ({
|
|
28127
|
-
serverUrl: url,
|
|
28128
|
-
headers
|
|
28129
|
-
})
|
|
28130
|
-
});
|
|
28131
|
-
var init_antigravity = __esm(() => {
|
|
28132
|
-
init_base();
|
|
28133
|
-
});
|
|
28134
|
-
|
|
28135
28314
|
// src/mcp/providers/claude.ts
|
|
28136
28315
|
import { join as join26 } from "node:path";
|
|
28137
28316
|
var ClaudeProvider = () => ({
|
|
@@ -28155,116 +28334,21 @@ var init_claude = __esm(() => {
|
|
|
28155
28334
|
init_base();
|
|
28156
28335
|
});
|
|
28157
28336
|
|
|
28158
|
-
// src/mcp/providers/claude-desktop.ts
|
|
28159
|
-
import { join as join27 } from "node:path";
|
|
28160
|
-
function configPath2() {
|
|
28161
|
-
return join27(appSupportDir(), "Claude", "claude_desktop_config.json");
|
|
28162
|
-
}
|
|
28163
|
-
var ClaudeDesktopProvider = () => ({
|
|
28164
|
-
name: () => "Claude Desktop",
|
|
28165
|
-
id: () => "claude-desktop",
|
|
28166
|
-
supportsLocal: () => false,
|
|
28167
|
-
priority: () => 2,
|
|
28168
|
-
detectPaths: () => [join27(appSupportDir(), "Claude")],
|
|
28169
|
-
isInstalled: () => isInstalled([join27(appSupportDir(), "Claude")]),
|
|
28170
|
-
globalConfigPath: () => configPath2(),
|
|
28171
|
-
isConfigured: () => isJSONKeyConfigured(configPath2(), "mcpServers"),
|
|
28172
|
-
isCurrent: (cfg) => {
|
|
28173
|
-
const proxy = proxyCommandShape("claude-desktop");
|
|
28174
|
-
return entryHasShape(proxy ? stdioServer(proxy) : npxRemoteEntry(shapeEndpoint(cfg), ANY, ANY, ANY), readJSONServer(configPath2(), "mcpServers"));
|
|
28175
|
-
},
|
|
28176
|
-
install(cfg, global) {
|
|
28177
|
-
if (!global)
|
|
28178
|
-
throw new Error("Claude Desktop does not support local installation");
|
|
28179
|
-
const url = mcpEndpoint(cfg);
|
|
28180
|
-
const proxy = proxyCommand("claude-desktop");
|
|
28181
|
-
if (proxy) {
|
|
28182
|
-
mcpHeaders(cfg.active_account?.target?.api_key);
|
|
28183
|
-
installJSONServer(configPath2(), "mcpServers", stdioServer(proxy));
|
|
28184
|
-
return;
|
|
28185
|
-
}
|
|
28186
|
-
const npx = findNpx();
|
|
28187
|
-
installJSONServer(configPath2(), "mcpServers", npxRemoteEntry(url, cfg.active_account?.target?.api_key, npx, launcherPathEnv(npx)));
|
|
28188
|
-
},
|
|
28189
|
-
remove(global) {
|
|
28190
|
-
if (!global)
|
|
28191
|
-
throw new Error("Claude Desktop does not support local removal");
|
|
28192
|
-
removeJSONServer(configPath2(), "mcpServers");
|
|
28193
|
-
}
|
|
28194
|
-
});
|
|
28195
|
-
var init_claude_desktop = __esm(() => {
|
|
28196
|
-
init_config_helpers();
|
|
28197
|
-
init_detect();
|
|
28198
|
-
init_proxy_entry();
|
|
28199
|
-
init_shape();
|
|
28200
|
-
});
|
|
28201
|
-
|
|
28202
|
-
// src/mcp/providers/cline.ts
|
|
28203
|
-
import { join as join28 } from "node:path";
|
|
28204
|
-
var extensionDir = () => join28(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
|
|
28205
|
-
providerName: "Cline",
|
|
28206
|
-
providerID: "cline",
|
|
28207
|
-
local: false,
|
|
28208
|
-
priorityValue: 11,
|
|
28209
|
-
paths: [extensionDir()],
|
|
28210
|
-
globalPath: join28(extensionDir(), "settings", "cline_mcp_settings.json"),
|
|
28211
|
-
topKey: "mcpServers",
|
|
28212
|
-
buildStdioServer: (proxy) => ({ type: "stdio", ...stdioServer(proxy), disabled: false }),
|
|
28213
|
-
buildServer: ({ url, headers }) => ({
|
|
28214
|
-
url,
|
|
28215
|
-
type: "streamableHttp",
|
|
28216
|
-
disabled: false,
|
|
28217
|
-
headers
|
|
28218
|
-
})
|
|
28219
|
-
});
|
|
28220
|
-
var init_cline = __esm(() => {
|
|
28221
|
-
init_detect();
|
|
28222
|
-
init_proxy_entry();
|
|
28223
|
-
init_base();
|
|
28224
|
-
});
|
|
28225
|
-
|
|
28226
|
-
// src/mcp/providers/cline-cli.ts
|
|
28227
|
-
import { join as join29 } from "node:path";
|
|
28228
|
-
function clineDir() {
|
|
28229
|
-
return process.env.CLINE_DIR ?? expandHome("~/.cline");
|
|
28230
|
-
}
|
|
28231
|
-
var ClineCliProvider = () => createJSONProvider({
|
|
28232
|
-
providerName: "Cline CLI",
|
|
28233
|
-
providerID: "cline-cli",
|
|
28234
|
-
local: false,
|
|
28235
|
-
priorityValue: 12,
|
|
28236
|
-
paths: [clineDir()],
|
|
28237
|
-
globalPath: join29(clineDir(), "data", "settings", "cline_mcp_settings.json"),
|
|
28238
|
-
topKey: "mcpServers",
|
|
28239
|
-
buildStdioServer: (proxy) => ({ type: "stdio", ...stdioServer(proxy), disabled: false }),
|
|
28240
|
-
buildServer: ({ url, headers }) => ({
|
|
28241
|
-
url,
|
|
28242
|
-
type: "streamableHttp",
|
|
28243
|
-
disabled: false,
|
|
28244
|
-
headers
|
|
28245
|
-
})
|
|
28246
|
-
});
|
|
28247
|
-
var init_cline_cli = __esm(() => {
|
|
28248
|
-
init_detect();
|
|
28249
|
-
init_proxy_entry();
|
|
28250
|
-
init_base();
|
|
28251
|
-
});
|
|
28252
|
-
|
|
28253
28337
|
// src/mcp/providers/codex.ts
|
|
28254
|
-
import { existsSync as existsSync22, readFileSync as
|
|
28255
|
-
import { dirname as dirname9, join as
|
|
28338
|
+
import { existsSync as existsSync22, readFileSync as readFileSync31 } from "node:fs";
|
|
28339
|
+
import { dirname as dirname9, join as join27 } from "node:path";
|
|
28256
28340
|
function codexHome4() {
|
|
28257
28341
|
return process.env.CODEX_HOME || expandHome("~/.codex");
|
|
28258
28342
|
}
|
|
28259
28343
|
function getConfigPath2(global) {
|
|
28260
28344
|
if (global)
|
|
28261
|
-
return
|
|
28262
|
-
return
|
|
28345
|
+
return join27(codexHome4(), "config.toml");
|
|
28346
|
+
return join27(process.cwd(), ".codex", "config.toml");
|
|
28263
28347
|
}
|
|
28264
28348
|
function readTOML(path) {
|
|
28265
28349
|
if (!existsSync22(path))
|
|
28266
28350
|
return "";
|
|
28267
|
-
return
|
|
28351
|
+
return readFileSync31(path, "utf-8");
|
|
28268
28352
|
}
|
|
28269
28353
|
function writeTOML(path, content) {
|
|
28270
28354
|
writeSecureFile(path, content);
|
|
@@ -28459,14 +28543,14 @@ function projectConfigPaths() {
|
|
|
28459
28543
|
const chain = [];
|
|
28460
28544
|
for (let dir = cwd;; ) {
|
|
28461
28545
|
chain.push(dir);
|
|
28462
|
-
if (existsSync22(
|
|
28546
|
+
if (existsSync22(join27(dir, ".git")))
|
|
28463
28547
|
break;
|
|
28464
28548
|
const parent = dirname9(dir);
|
|
28465
28549
|
if (parent === dir)
|
|
28466
|
-
return [
|
|
28550
|
+
return [join27(cwd, ".codex", "config.toml")];
|
|
28467
28551
|
dir = parent;
|
|
28468
28552
|
}
|
|
28469
|
-
return chain.reverse().map((dir) =>
|
|
28553
|
+
return chain.reverse().map((dir) => join27(dir, ".codex", "config.toml"));
|
|
28470
28554
|
}
|
|
28471
28555
|
function pruneLegacyRemoteEntry(path) {
|
|
28472
28556
|
if (!existsSync22(path))
|
|
@@ -28483,12 +28567,12 @@ var FORWARDED_ENV, DOSU_TABLE = "mcp_servers.dosu", REMOTE_HTTP_KEY, CodexProvid
|
|
|
28483
28567
|
priority: () => 8,
|
|
28484
28568
|
detectPaths: () => ["~/.codex"],
|
|
28485
28569
|
isInstalled: codexInstalled,
|
|
28486
|
-
globalConfigPath: () =>
|
|
28570
|
+
globalConfigPath: () => join27(codexHome4(), "config.toml"),
|
|
28487
28571
|
isConfigured: () => {
|
|
28488
|
-
const content = readTOML(
|
|
28572
|
+
const content = readTOML(join27(codexHome4(), "config.toml"));
|
|
28489
28573
|
return content.includes("[mcp_servers.dosu]");
|
|
28490
28574
|
},
|
|
28491
|
-
isCurrent: (cfg) => entryHasShape(codexServer(cfg, true), readDosuEntry(readTOML(
|
|
28575
|
+
isCurrent: (cfg) => entryHasShape(codexServer(cfg, true), readDosuEntry(readTOML(join27(codexHome4(), "config.toml")))),
|
|
28492
28576
|
install(cfg, global) {
|
|
28493
28577
|
if (cfg.mode !== MODE_OSS && !cfg.active_account?.target?.deployment_id)
|
|
28494
28578
|
throw new Error("deployment ID is required");
|
|
@@ -28521,7 +28605,7 @@ var init_codex3 = __esm(() => {
|
|
|
28521
28605
|
});
|
|
28522
28606
|
|
|
28523
28607
|
// src/mcp/providers/copilot.ts
|
|
28524
|
-
import { join as
|
|
28608
|
+
import { join as join28 } from "node:path";
|
|
28525
28609
|
function globalServer(url, apiKey, proxy) {
|
|
28526
28610
|
if (proxy)
|
|
28527
28611
|
return { type: "local", ...stdioServer(proxy), tools: ["*"] };
|
|
@@ -28529,7 +28613,7 @@ function globalServer(url, apiKey, proxy) {
|
|
|
28529
28613
|
}
|
|
28530
28614
|
function globalPath() {
|
|
28531
28615
|
if (process.env.XDG_CONFIG_HOME) {
|
|
28532
|
-
return
|
|
28616
|
+
return join28(process.env.XDG_CONFIG_HOME, "mcp-config.json");
|
|
28533
28617
|
}
|
|
28534
28618
|
return expandHome("~/.copilot/mcp-config.json");
|
|
28535
28619
|
}
|
|
@@ -28550,7 +28634,7 @@ var CopilotProvider = () => ({
|
|
|
28550
28634
|
if (global) {
|
|
28551
28635
|
installJSONServer(globalPath(), "mcpServers", globalServer(url, cfg.active_account?.target?.api_key, proxy));
|
|
28552
28636
|
} else {
|
|
28553
|
-
const configPath =
|
|
28637
|
+
const configPath = join28(process.cwd(), ".vscode", "mcp.json");
|
|
28554
28638
|
const server = proxy ? { type: "stdio", ...stdioServer(proxy) } : { type: "http", url, headers };
|
|
28555
28639
|
installJSONServer(configPath, "servers", server);
|
|
28556
28640
|
}
|
|
@@ -28559,7 +28643,7 @@ var CopilotProvider = () => ({
|
|
|
28559
28643
|
if (global) {
|
|
28560
28644
|
removeJSONServer(globalPath(), "mcpServers");
|
|
28561
28645
|
} else {
|
|
28562
|
-
const configPath =
|
|
28646
|
+
const configPath = join28(process.cwd(), ".vscode", "mcp.json");
|
|
28563
28647
|
removeJSONServer(configPath, "servers");
|
|
28564
28648
|
}
|
|
28565
28649
|
}
|
|
@@ -28572,7 +28656,7 @@ var init_copilot = __esm(() => {
|
|
|
28572
28656
|
});
|
|
28573
28657
|
|
|
28574
28658
|
// src/mcp/providers/cursor.ts
|
|
28575
|
-
import { join as
|
|
28659
|
+
import { join as join29 } from "node:path";
|
|
28576
28660
|
var CursorProvider = () => createJSONProvider({
|
|
28577
28661
|
providerName: "Cursor",
|
|
28578
28662
|
providerID: "cursor",
|
|
@@ -28585,14 +28669,14 @@ var CursorProvider = () => createJSONProvider({
|
|
|
28585
28669
|
url,
|
|
28586
28670
|
headers
|
|
28587
28671
|
}),
|
|
28588
|
-
localConfigPath: (cwd) =>
|
|
28672
|
+
localConfigPath: (cwd) => join29(cwd, ".cursor", "mcp.json")
|
|
28589
28673
|
});
|
|
28590
28674
|
var init_cursor2 = __esm(() => {
|
|
28591
28675
|
init_base();
|
|
28592
28676
|
});
|
|
28593
28677
|
|
|
28594
28678
|
// src/mcp/providers/factory.ts
|
|
28595
|
-
import { join as
|
|
28679
|
+
import { join as join30 } from "node:path";
|
|
28596
28680
|
var FactoryProvider = () => createJSONProvider({
|
|
28597
28681
|
providerName: "Factory",
|
|
28598
28682
|
providerID: "factory",
|
|
@@ -28602,7 +28686,7 @@ var FactoryProvider = () => createJSONProvider({
|
|
|
28602
28686
|
globalPath: "~/.factory/mcp.json",
|
|
28603
28687
|
topKey: "mcpServers",
|
|
28604
28688
|
buildStdioServer: (proxy) => ({ type: "stdio", ...stdioServer(proxy) }),
|
|
28605
|
-
localConfigPath: (cwd) =>
|
|
28689
|
+
localConfigPath: (cwd) => join30(cwd, ".factory", "mcp.json")
|
|
28606
28690
|
});
|
|
28607
28691
|
var init_factory = __esm(() => {
|
|
28608
28692
|
init_proxy_entry();
|
|
@@ -28610,7 +28694,7 @@ var init_factory = __esm(() => {
|
|
|
28610
28694
|
});
|
|
28611
28695
|
|
|
28612
28696
|
// src/mcp/providers/gemini.ts
|
|
28613
|
-
import { join as
|
|
28697
|
+
import { join as join31 } from "node:path";
|
|
28614
28698
|
var GeminiProvider = () => createJSONProvider({
|
|
28615
28699
|
providerName: "Gemini CLI",
|
|
28616
28700
|
providerID: "gemini",
|
|
@@ -28619,7 +28703,7 @@ var GeminiProvider = () => createJSONProvider({
|
|
|
28619
28703
|
paths: ["~/.gemini"],
|
|
28620
28704
|
globalPath: "~/.gemini/settings.json",
|
|
28621
28705
|
topKey: "mcpServers",
|
|
28622
|
-
localConfigPath: (cwd) =>
|
|
28706
|
+
localConfigPath: (cwd) => join31(cwd, ".gemini", "settings.json")
|
|
28623
28707
|
});
|
|
28624
28708
|
var init_gemini = __esm(() => {
|
|
28625
28709
|
init_base();
|
|
@@ -28664,53 +28748,8 @@ var init_manual = __esm(() => {
|
|
|
28664
28748
|
init_config_helpers();
|
|
28665
28749
|
});
|
|
28666
28750
|
|
|
28667
|
-
// src/mcp/providers/mcporter.ts
|
|
28668
|
-
import { existsSync as existsSync23 } from "node:fs";
|
|
28669
|
-
import { join as join35 } from "node:path";
|
|
28670
|
-
function server(url, apiKey, proxy) {
|
|
28671
|
-
if (proxy)
|
|
28672
|
-
return stdioServer(proxy);
|
|
28673
|
-
return { type: "http", url, headers: mcpHeaders(apiKey) };
|
|
28674
|
-
}
|
|
28675
|
-
function resolveGlobalConfigPath() {
|
|
28676
|
-
const jsonPath = expandHome("~/.mcporter/mcporter.json");
|
|
28677
|
-
if (existsSync23(jsonPath))
|
|
28678
|
-
return jsonPath;
|
|
28679
|
-
const jsoncPath = expandHome("~/.mcporter/mcporter.jsonc");
|
|
28680
|
-
if (existsSync23(jsoncPath))
|
|
28681
|
-
return jsoncPath;
|
|
28682
|
-
return jsonPath;
|
|
28683
|
-
}
|
|
28684
|
-
var MCPorterProvider = () => ({
|
|
28685
|
-
name: () => "MCPorter",
|
|
28686
|
-
id: () => "mcporter",
|
|
28687
|
-
supportsLocal: () => true,
|
|
28688
|
-
priority: () => 16,
|
|
28689
|
-
detectPaths: () => ["~/.mcporter"],
|
|
28690
|
-
isInstalled: () => isInstalled(["~/.mcporter"]),
|
|
28691
|
-
globalConfigPath: () => resolveGlobalConfigPath(),
|
|
28692
|
-
isConfigured: () => isJSONKeyConfigured(resolveGlobalConfigPath(), "mcpServers"),
|
|
28693
|
-
isCurrent: (cfg) => entryHasShape(server(shapeEndpoint(cfg), ANY, proxyCommandShape("mcporter")), readJSONServer(resolveGlobalConfigPath(), "mcpServers")),
|
|
28694
|
-
install(cfg, global) {
|
|
28695
|
-
const configPath = global ? resolveGlobalConfigPath() : join35(process.cwd(), "config", "mcporter.json");
|
|
28696
|
-
const url = mcpEndpoint(cfg);
|
|
28697
|
-
const proxy = proxyCommand("mcporter");
|
|
28698
|
-
installJSONServer(configPath, "mcpServers", server(url, cfg.active_account?.target?.api_key, proxy));
|
|
28699
|
-
},
|
|
28700
|
-
remove(global) {
|
|
28701
|
-
const configPath = global ? resolveGlobalConfigPath() : join35(process.cwd(), "config", "mcporter.json");
|
|
28702
|
-
removeJSONServer(configPath, "mcpServers");
|
|
28703
|
-
}
|
|
28704
|
-
});
|
|
28705
|
-
var init_mcporter = __esm(() => {
|
|
28706
|
-
init_config_helpers();
|
|
28707
|
-
init_detect();
|
|
28708
|
-
init_proxy_entry();
|
|
28709
|
-
init_shape();
|
|
28710
|
-
});
|
|
28711
|
-
|
|
28712
28751
|
// src/mcp/providers/opencode.ts
|
|
28713
|
-
import { join as
|
|
28752
|
+
import { join as join32 } from "node:path";
|
|
28714
28753
|
var jsonProvider = () => createJSONProvider({
|
|
28715
28754
|
providerName: "OpenCode",
|
|
28716
28755
|
providerID: "opencode",
|
|
@@ -28731,7 +28770,7 @@ var jsonProvider = () => createJSONProvider({
|
|
|
28731
28770
|
enabled: true,
|
|
28732
28771
|
headers
|
|
28733
28772
|
}),
|
|
28734
|
-
localConfigPath: (cwd) =>
|
|
28773
|
+
localConfigPath: (cwd) => join32(cwd, "opencode.json")
|
|
28735
28774
|
}), OpenCodeProvider = () => {
|
|
28736
28775
|
const provider = jsonProvider();
|
|
28737
28776
|
return { ...provider, isInstalled: () => provider.isInstalled() || isOnPath("opencode") };
|
|
@@ -28765,133 +28804,15 @@ var init_pi4 = __esm(() => {
|
|
|
28765
28804
|
init_pi3();
|
|
28766
28805
|
});
|
|
28767
28806
|
|
|
28768
|
-
// src/mcp/providers/vscode.ts
|
|
28769
|
-
import { join as join37 } from "node:path";
|
|
28770
|
-
var VSCodeProvider = () => createJSONProvider({
|
|
28771
|
-
providerName: "VS Code",
|
|
28772
|
-
providerID: "vscode",
|
|
28773
|
-
local: true,
|
|
28774
|
-
priorityValue: 6,
|
|
28775
|
-
paths: [join37(appSupportDir(), "Code")],
|
|
28776
|
-
globalPath: join37(appSupportDir(), "Code", "User", "mcp.json"),
|
|
28777
|
-
topKey: "servers",
|
|
28778
|
-
buildStdioServer: (proxy) => ({ type: "stdio", ...stdioServer(proxy) }),
|
|
28779
|
-
localConfigPath: (cwd) => join37(cwd, ".vscode", "mcp.json")
|
|
28780
|
-
});
|
|
28781
|
-
var init_vscode = __esm(() => {
|
|
28782
|
-
init_detect();
|
|
28783
|
-
init_proxy_entry();
|
|
28784
|
-
init_base();
|
|
28785
|
-
});
|
|
28786
|
-
|
|
28787
|
-
// src/mcp/providers/windsurf.ts
|
|
28788
|
-
import { homedir as homedir10 } from "node:os";
|
|
28789
|
-
import { join as join38 } from "node:path";
|
|
28790
|
-
var WindsurfProvider = () => createJSONProvider({
|
|
28791
|
-
providerName: "Windsurf",
|
|
28792
|
-
providerID: "windsurf",
|
|
28793
|
-
local: false,
|
|
28794
|
-
priorityValue: 9,
|
|
28795
|
-
paths: [join38(homedir10(), ".codeium", "windsurf")],
|
|
28796
|
-
globalPath: join38(homedir10(), ".codeium", "windsurf", "mcp_config.json"),
|
|
28797
|
-
topKey: "mcpServers"
|
|
28798
|
-
});
|
|
28799
|
-
var init_windsurf = __esm(() => {
|
|
28800
|
-
init_base();
|
|
28801
|
-
});
|
|
28802
|
-
|
|
28803
|
-
// src/mcp/providers/zed.ts
|
|
28804
|
-
import { rmSync as rmSync5 } from "node:fs";
|
|
28805
|
-
import { homedir as homedir11, platform as platform4 } from "node:os";
|
|
28806
|
-
import { join as join39 } from "node:path";
|
|
28807
|
-
function zedConfigDir() {
|
|
28808
|
-
const os = platform4();
|
|
28809
|
-
if (os === "win32")
|
|
28810
|
-
return join39(appSupportDir(), "Zed");
|
|
28811
|
-
if (os === "darwin")
|
|
28812
|
-
return join39(homedir11(), ".config", "zed");
|
|
28813
|
-
return join39(appSupportDir(), "zed");
|
|
28814
|
-
}
|
|
28815
|
-
function zedDataDir() {
|
|
28816
|
-
const os = platform4();
|
|
28817
|
-
if (os === "darwin")
|
|
28818
|
-
return join39(appSupportDir(), "Zed");
|
|
28819
|
-
if (os === "win32")
|
|
28820
|
-
return join39(process.env.LOCALAPPDATA ?? "", "Zed");
|
|
28821
|
-
return join39(process.env.XDG_DATA_HOME ?? join39(homedir11(), ".local", "share"), "zed");
|
|
28822
|
-
}
|
|
28823
|
-
function legacyDarwinSettingsPath() {
|
|
28824
|
-
return platform4() === "darwin" ? join39(appSupportDir(), "Zed", "settings.json") : null;
|
|
28825
|
-
}
|
|
28826
|
-
function removeLegacyDosuEntry(path) {
|
|
28827
|
-
let cfg;
|
|
28828
|
-
try {
|
|
28829
|
-
cfg = readJSONConfig(path);
|
|
28830
|
-
} catch {
|
|
28831
|
-
return;
|
|
28832
|
-
}
|
|
28833
|
-
const servers = cfg.context_servers;
|
|
28834
|
-
if (typeof servers !== "object" || servers === null || !("dosu" in servers))
|
|
28835
|
-
return;
|
|
28836
|
-
delete servers.dosu;
|
|
28837
|
-
const nothingElse = Object.keys(cfg).length === 1 && Object.keys(servers).length === 0;
|
|
28838
|
-
if (nothingElse)
|
|
28839
|
-
rmSync5(path, { force: true });
|
|
28840
|
-
else
|
|
28841
|
-
saveJSONConfig(path, cfg);
|
|
28842
|
-
}
|
|
28843
|
-
var ZedProvider = (legacyPath = legacyDarwinSettingsPath()) => {
|
|
28844
|
-
const provider = createJSONProvider({
|
|
28845
|
-
providerName: "Zed",
|
|
28846
|
-
providerID: "zed",
|
|
28847
|
-
local: true,
|
|
28848
|
-
priorityValue: 10,
|
|
28849
|
-
paths: [zedConfigDir(), zedDataDir()],
|
|
28850
|
-
globalPath: join39(zedConfigDir(), "settings.json"),
|
|
28851
|
-
topKey: "context_servers",
|
|
28852
|
-
buildServer: ({ url, headers }) => ({ url, headers }),
|
|
28853
|
-
localConfigPath: (cwd) => join39(cwd, ".zed", "settings.json")
|
|
28854
|
-
});
|
|
28855
|
-
if (!legacyPath)
|
|
28856
|
-
return provider;
|
|
28857
|
-
return {
|
|
28858
|
-
...provider,
|
|
28859
|
-
isCurrent: (cfg) => provider.isCurrent(cfg) && readJSONServer(legacyPath, "context_servers") === undefined,
|
|
28860
|
-
install(cfg, global) {
|
|
28861
|
-
provider.install(cfg, global);
|
|
28862
|
-
if (global)
|
|
28863
|
-
removeLegacyDosuEntry(legacyPath);
|
|
28864
|
-
},
|
|
28865
|
-
remove(global) {
|
|
28866
|
-
provider.remove(global);
|
|
28867
|
-
if (global)
|
|
28868
|
-
removeLegacyDosuEntry(legacyPath);
|
|
28869
|
-
}
|
|
28870
|
-
};
|
|
28871
|
-
};
|
|
28872
|
-
var init_zed = __esm(() => {
|
|
28873
|
-
init_config_helpers();
|
|
28874
|
-
init_detect();
|
|
28875
|
-
init_base();
|
|
28876
|
-
});
|
|
28877
|
-
|
|
28878
28807
|
// src/mcp/providers.ts
|
|
28879
28808
|
function allProviders() {
|
|
28880
28809
|
return [
|
|
28881
28810
|
ClaudeProvider(),
|
|
28882
|
-
ClaudeDesktopProvider(),
|
|
28883
28811
|
CursorProvider(),
|
|
28884
|
-
VSCodeProvider(),
|
|
28885
28812
|
GeminiProvider(),
|
|
28886
28813
|
CodexProvider(),
|
|
28887
|
-
WindsurfProvider(),
|
|
28888
|
-
ZedProvider(),
|
|
28889
|
-
ClineProvider(),
|
|
28890
|
-
ClineCliProvider(),
|
|
28891
28814
|
CopilotProvider(),
|
|
28892
28815
|
OpenCodeProvider(),
|
|
28893
|
-
AntigravityProvider(),
|
|
28894
|
-
MCPorterProvider(),
|
|
28895
28816
|
FactoryProvider(),
|
|
28896
28817
|
PiProvider(),
|
|
28897
28818
|
ManualProvider()
|
|
@@ -28908,23 +28829,15 @@ function getProvider(toolID) {
|
|
|
28908
28829
|
return provider;
|
|
28909
28830
|
}
|
|
28910
28831
|
var init_providers = __esm(() => {
|
|
28911
|
-
init_antigravity();
|
|
28912
28832
|
init_claude();
|
|
28913
|
-
init_claude_desktop();
|
|
28914
|
-
init_cline();
|
|
28915
|
-
init_cline_cli();
|
|
28916
28833
|
init_codex3();
|
|
28917
28834
|
init_copilot();
|
|
28918
28835
|
init_cursor2();
|
|
28919
28836
|
init_factory();
|
|
28920
28837
|
init_gemini();
|
|
28921
28838
|
init_manual();
|
|
28922
|
-
init_mcporter();
|
|
28923
28839
|
init_opencode4();
|
|
28924
28840
|
init_pi4();
|
|
28925
|
-
init_vscode();
|
|
28926
|
-
init_windsurf();
|
|
28927
|
-
init_zed();
|
|
28928
28841
|
});
|
|
28929
28842
|
|
|
28930
28843
|
// src/mcp/refresh.ts
|
|
@@ -28973,29 +28886,29 @@ var init_refresh = __esm(() => {
|
|
|
28973
28886
|
import { spawn as spawn2 } from "node:child_process";
|
|
28974
28887
|
import {
|
|
28975
28888
|
closeSync as closeSync8,
|
|
28976
|
-
existsSync as
|
|
28889
|
+
existsSync as existsSync23,
|
|
28977
28890
|
mkdirSync as mkdirSync14,
|
|
28978
28891
|
openSync as openSync8,
|
|
28979
|
-
readFileSync as
|
|
28980
|
-
rmSync as
|
|
28892
|
+
readFileSync as readFileSync32,
|
|
28893
|
+
rmSync as rmSync5,
|
|
28981
28894
|
statSync as statSync11,
|
|
28982
28895
|
writeFileSync as writeFileSync15,
|
|
28983
28896
|
writeSync
|
|
28984
28897
|
} from "node:fs";
|
|
28985
|
-
import { homedir as
|
|
28986
|
-
import { join as
|
|
28898
|
+
import { homedir as homedir10 } from "node:os";
|
|
28899
|
+
import { join as join33 } from "node:path";
|
|
28987
28900
|
function statePath() {
|
|
28988
|
-
return
|
|
28901
|
+
return join33(getConfigDir(), STATE_FILENAME2);
|
|
28989
28902
|
}
|
|
28990
28903
|
function lockPath2() {
|
|
28991
|
-
return
|
|
28904
|
+
return join33(getConfigDir(), LOCK_FILENAME2);
|
|
28992
28905
|
}
|
|
28993
28906
|
function isValidVersion(value) {
|
|
28994
28907
|
return typeof value === "string" && VERSION_PATTERN.test(value);
|
|
28995
28908
|
}
|
|
28996
28909
|
function readState() {
|
|
28997
28910
|
try {
|
|
28998
|
-
const raw = JSON.parse(
|
|
28911
|
+
const raw = JSON.parse(readFileSync32(statePath(), "utf-8"));
|
|
28999
28912
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
29000
28913
|
return {};
|
|
29001
28914
|
const data = raw;
|
|
@@ -29014,7 +28927,7 @@ function readState() {
|
|
|
29014
28927
|
function writeState(state) {
|
|
29015
28928
|
try {
|
|
29016
28929
|
const dir = getConfigDir();
|
|
29017
|
-
if (!
|
|
28930
|
+
if (!existsSync23(dir))
|
|
29018
28931
|
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
29019
28932
|
writeFileSync15(statePath(), `${JSON.stringify(state, null, 2)}
|
|
29020
28933
|
`, { mode: 384 });
|
|
@@ -29071,7 +28984,7 @@ function claimLock(version, now) {
|
|
|
29071
28984
|
try {
|
|
29072
28985
|
mkdirSync14(getConfigDir(), { recursive: true, mode: 448 });
|
|
29073
28986
|
if (!lockIsFresh(now))
|
|
29074
|
-
|
|
28987
|
+
rmSync5(lockPath2(), { force: true });
|
|
29075
28988
|
const fd = openSync8(lockPath2(), "wx", 384);
|
|
29076
28989
|
try {
|
|
29077
28990
|
writeSync(fd, version);
|
|
@@ -29085,12 +28998,12 @@ function claimLock(version, now) {
|
|
|
29085
28998
|
}
|
|
29086
28999
|
function releaseLock() {
|
|
29087
29000
|
try {
|
|
29088
|
-
|
|
29001
|
+
rmSync5(lockPath2(), { force: true });
|
|
29089
29002
|
} catch {}
|
|
29090
29003
|
}
|
|
29091
29004
|
function readLockVersion() {
|
|
29092
29005
|
try {
|
|
29093
|
-
const version =
|
|
29006
|
+
const version = readFileSync32(lockPath2(), "utf-8").trim();
|
|
29094
29007
|
return isValidVersion(version) ? version : undefined;
|
|
29095
29008
|
} catch {
|
|
29096
29009
|
return;
|
|
@@ -29117,7 +29030,7 @@ function startAutoUpdate(version, options = {}) {
|
|
|
29117
29030
|
return claim === "held" ? "in_progress" : "unavailable";
|
|
29118
29031
|
try {
|
|
29119
29032
|
const child = spawn2(invocation.command, invocation.args, {
|
|
29120
|
-
cwd:
|
|
29033
|
+
cwd: homedir10(),
|
|
29121
29034
|
detached: true,
|
|
29122
29035
|
stdio: "ignore",
|
|
29123
29036
|
windowsHide: true,
|
|
@@ -29164,17 +29077,17 @@ var init_auto_update = __esm(() => {
|
|
|
29164
29077
|
});
|
|
29165
29078
|
|
|
29166
29079
|
// src/version/mcp-refresh-check.ts
|
|
29167
|
-
import { existsSync as
|
|
29168
|
-
import { join as
|
|
29080
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync33, writeFileSync as writeFileSync16 } from "node:fs";
|
|
29081
|
+
import { join as join34 } from "node:path";
|
|
29169
29082
|
function getCachePath2() {
|
|
29170
|
-
return
|
|
29083
|
+
return join34(getConfigDir(), CACHE_FILENAME3);
|
|
29171
29084
|
}
|
|
29172
29085
|
function readMcpRefreshCache() {
|
|
29173
29086
|
try {
|
|
29174
29087
|
const path = getCachePath2();
|
|
29175
|
-
if (!
|
|
29088
|
+
if (!existsSync24(path))
|
|
29176
29089
|
return null;
|
|
29177
|
-
const data = JSON.parse(
|
|
29090
|
+
const data = JSON.parse(readFileSync33(path, "utf-8"));
|
|
29178
29091
|
if (typeof data?.version === "string")
|
|
29179
29092
|
return { version: data.version };
|
|
29180
29093
|
return null;
|
|
@@ -29185,7 +29098,7 @@ function readMcpRefreshCache() {
|
|
|
29185
29098
|
function writeMcpRefreshCache(cache) {
|
|
29186
29099
|
try {
|
|
29187
29100
|
const dir = getConfigDir();
|
|
29188
|
-
if (!
|
|
29101
|
+
if (!existsSync24(dir)) {
|
|
29189
29102
|
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
29190
29103
|
}
|
|
29191
29104
|
writeFileSync16(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
@@ -29328,15 +29241,15 @@ function createLogFollower(path, emit) {
|
|
|
29328
29241
|
var init_follow = () => {};
|
|
29329
29242
|
|
|
29330
29243
|
// src/sessions/session-title.ts
|
|
29331
|
-
import { existsSync as
|
|
29332
|
-
import { homedir as
|
|
29333
|
-
import { join as
|
|
29244
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync16, readFileSync as readFileSync34, renameSync as renameSync6, statSync as statSync13, writeFileSync as writeFileSync17 } from "node:fs";
|
|
29245
|
+
import { homedir as homedir11 } from "node:os";
|
|
29246
|
+
import { join as join35 } from "node:path";
|
|
29334
29247
|
function cachePath2(configDir) {
|
|
29335
|
-
return
|
|
29248
|
+
return join35(configDir, CACHE_FILENAME4);
|
|
29336
29249
|
}
|
|
29337
29250
|
function loadCacheFile2(configDir) {
|
|
29338
29251
|
try {
|
|
29339
|
-
const raw = JSON.parse(
|
|
29252
|
+
const raw = JSON.parse(readFileSync34(cachePath2(configDir), "utf-8"));
|
|
29340
29253
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION2 || typeof raw.entries !== "object")
|
|
29341
29254
|
return {};
|
|
29342
29255
|
return raw.entries;
|
|
@@ -29346,7 +29259,7 @@ function loadCacheFile2(configDir) {
|
|
|
29346
29259
|
}
|
|
29347
29260
|
function saveCacheFile2(configDir, entries) {
|
|
29348
29261
|
try {
|
|
29349
|
-
if (!
|
|
29262
|
+
if (!existsSync25(configDir))
|
|
29350
29263
|
mkdirSync16(configDir, { recursive: true, mode: 448 });
|
|
29351
29264
|
const path = cachePath2(configDir);
|
|
29352
29265
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
@@ -29384,15 +29297,15 @@ function claudeSummaryFromHead(text) {
|
|
|
29384
29297
|
}
|
|
29385
29298
|
return null;
|
|
29386
29299
|
}
|
|
29387
|
-
function reconstructSession(harness, id, slug, home =
|
|
29300
|
+
function reconstructSession(harness, id, slug, home = homedir11(), exists = existsSync25) {
|
|
29388
29301
|
if (!slug)
|
|
29389
29302
|
return null;
|
|
29390
29303
|
const candidates = [];
|
|
29391
29304
|
if (harness === "claude") {
|
|
29392
|
-
candidates.push(
|
|
29305
|
+
candidates.push(join35(home, ".claude", "projects", slug, `${id}.jsonl`));
|
|
29393
29306
|
} else if (harness === "cursor") {
|
|
29394
|
-
const project =
|
|
29395
|
-
candidates.push(
|
|
29307
|
+
const project = join35(home, ".cursor", "projects", slug);
|
|
29308
|
+
candidates.push(join35(project, "agent-transcripts", id, `${id}.jsonl`), join35(project, "agent-transcripts", `${id}.jsonl`));
|
|
29396
29309
|
} else {
|
|
29397
29310
|
return null;
|
|
29398
29311
|
}
|
|
@@ -29404,7 +29317,7 @@ function reconstructSession(harness, id, slug, home = homedir13(), exists = exis
|
|
|
29404
29317
|
}
|
|
29405
29318
|
function readHead3(path) {
|
|
29406
29319
|
try {
|
|
29407
|
-
return
|
|
29320
|
+
return readFileSync34(path, "utf-8").slice(0, 128 * 1024);
|
|
29408
29321
|
} catch {
|
|
29409
29322
|
return null;
|
|
29410
29323
|
}
|
|
@@ -29484,7 +29397,7 @@ var init_alt_screen = __esm(() => {
|
|
|
29484
29397
|
});
|
|
29485
29398
|
|
|
29486
29399
|
// src/tui/activity-view.ts
|
|
29487
|
-
import { existsSync as
|
|
29400
|
+
import { existsSync as existsSync26, readFileSync as readFileSync35 } from "node:fs";
|
|
29488
29401
|
import { basename as basename11 } from "node:path";
|
|
29489
29402
|
function reduceActivityViewKey(key) {
|
|
29490
29403
|
if (key === "q" || key === ESC7 || key === CTRL_C4)
|
|
@@ -29659,8 +29572,8 @@ function confirmBox(queuedCount, backlog, width, mode = "start") {
|
|
|
29659
29572
|
"",
|
|
29660
29573
|
`${import_picocolors37.default.bold("enter")} ${verb} · ${import_picocolors37.default.bold("esc")} cancel`
|
|
29661
29574
|
];
|
|
29662
|
-
const inner = Math.min(maxInner, Math.max(...rows.map(
|
|
29663
|
-
const pad = (row) => row + " ".repeat(Math.max(0, inner -
|
|
29575
|
+
const inner = Math.min(maxInner, Math.max(...rows.map(visibleWidth)));
|
|
29576
|
+
const pad = (row) => row + " ".repeat(Math.max(0, inner - visibleWidth(row)));
|
|
29664
29577
|
return [
|
|
29665
29578
|
import_picocolors37.default.dim(`╭${"─".repeat(inner + 2)}╮`),
|
|
29666
29579
|
...rows.map((row) => `${import_picocolors37.default.dim("│")} ${pad(row)} ${import_picocolors37.default.dim("│")}`),
|
|
@@ -29771,7 +29684,7 @@ function createRowNamer() {
|
|
|
29771
29684
|
names.titles[key] = t;
|
|
29772
29685
|
};
|
|
29773
29686
|
for (const s of [...backlog.queued, ...backlog.open]) {
|
|
29774
|
-
if (!
|
|
29687
|
+
if (!existsSync26(s.path))
|
|
29775
29688
|
continue;
|
|
29776
29689
|
const key = `${s.harness}/${s.id}`;
|
|
29777
29690
|
const dir = dirs.resolve(s);
|
|
@@ -29808,7 +29721,7 @@ function createRowNamer() {
|
|
|
29808
29721
|
}
|
|
29809
29722
|
function defaultReadLog2() {
|
|
29810
29723
|
try {
|
|
29811
|
-
return
|
|
29724
|
+
return readFileSync35(logger.getLogPath(), "utf-8");
|
|
29812
29725
|
} catch {
|
|
29813
29726
|
return "";
|
|
29814
29727
|
}
|
|
@@ -30028,14 +29941,14 @@ var init_activity_view = __esm(() => {
|
|
|
30028
29941
|
});
|
|
30029
29942
|
|
|
30030
29943
|
// src/rules/installer.ts
|
|
30031
|
-
import { existsSync as
|
|
30032
|
-
import { homedir as
|
|
30033
|
-
import { dirname as dirname10, join as
|
|
29944
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync17, readFileSync as readFileSync36, unlinkSync as unlinkSync7, writeFileSync as writeFileSync18 } from "node:fs";
|
|
29945
|
+
import { homedir as homedir12 } from "node:os";
|
|
29946
|
+
import { dirname as dirname10, join as join36 } from "node:path";
|
|
30034
29947
|
function claudeConfigDir4() {
|
|
30035
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
29948
|
+
return process.env.CLAUDE_CONFIG_DIR || join36(homedir12(), ".claude");
|
|
30036
29949
|
}
|
|
30037
29950
|
function codexHome5() {
|
|
30038
|
-
return process.env.CODEX_HOME ||
|
|
29951
|
+
return process.env.CODEX_HOME || join36(homedir12(), ".codex");
|
|
30039
29952
|
}
|
|
30040
29953
|
function isRuleAgent(agent) {
|
|
30041
29954
|
return Object.hasOwn(RULE_TARGETS, agent);
|
|
@@ -30064,12 +29977,12 @@ function ensureParent(path) {
|
|
|
30064
29977
|
mkdirSync17(dirname10(path), { recursive: true });
|
|
30065
29978
|
}
|
|
30066
29979
|
function writeIfChanged2(path, content) {
|
|
30067
|
-
if (!
|
|
29980
|
+
if (!existsSync27(path)) {
|
|
30068
29981
|
ensureParent(path);
|
|
30069
29982
|
writeFileSync18(path, content, "utf-8");
|
|
30070
29983
|
return "created";
|
|
30071
29984
|
}
|
|
30072
|
-
if (
|
|
29985
|
+
if (readFileSync36(path, "utf-8") === content)
|
|
30073
29986
|
return "unchanged";
|
|
30074
29987
|
writeFileSync18(path, content, "utf-8");
|
|
30075
29988
|
return "updated";
|
|
@@ -30097,14 +30010,14 @@ function buildSection(content, lineEnding = `
|
|
|
30097
30010
|
return `${DOSU_RULE_SECTION_START}${lineEnding}${body}${lineEnding}${DOSU_RULE_SECTION_END}`;
|
|
30098
30011
|
}
|
|
30099
30012
|
function upsertSection(path, content) {
|
|
30100
|
-
if (!
|
|
30013
|
+
if (!existsSync27(path)) {
|
|
30101
30014
|
const section = buildSection(content);
|
|
30102
30015
|
ensureParent(path);
|
|
30103
30016
|
writeFileSync18(path, `${section}
|
|
30104
30017
|
`, "utf-8");
|
|
30105
30018
|
return "created";
|
|
30106
30019
|
}
|
|
30107
|
-
const existing =
|
|
30020
|
+
const existing = readFileSync36(path, "utf-8");
|
|
30108
30021
|
const lineEnding = lineEndingFor(existing);
|
|
30109
30022
|
const section = buildSection(content, lineEnding);
|
|
30110
30023
|
const location = findSection(existing);
|
|
@@ -30134,13 +30047,13 @@ function removeRuleForAgent(agent) {
|
|
|
30134
30047
|
return null;
|
|
30135
30048
|
const target = RULE_TARGETS[agent];
|
|
30136
30049
|
const path = target.path();
|
|
30137
|
-
if (!
|
|
30050
|
+
if (!existsSync27(path))
|
|
30138
30051
|
return { agent, path, action: "not_found" };
|
|
30139
30052
|
if (target.kind === "file") {
|
|
30140
30053
|
unlinkSync7(path);
|
|
30141
30054
|
return { agent, path, action: "removed" };
|
|
30142
30055
|
}
|
|
30143
|
-
const existing =
|
|
30056
|
+
const existing = readFileSync36(path, "utf-8");
|
|
30144
30057
|
const lineEnding = lineEndingFor(existing);
|
|
30145
30058
|
const location = findSection(existing);
|
|
30146
30059
|
if (!location)
|
|
@@ -30177,36 +30090,32 @@ var init_installer = __esm(() => {
|
|
|
30177
30090
|
RULE_TARGETS = {
|
|
30178
30091
|
claude: {
|
|
30179
30092
|
kind: "file",
|
|
30180
|
-
path: () =>
|
|
30093
|
+
path: () => join36(claudeConfigDir4(), "rules", "dosu.md")
|
|
30181
30094
|
},
|
|
30182
30095
|
cursor: {
|
|
30183
30096
|
kind: "file",
|
|
30184
|
-
path: () =>
|
|
30097
|
+
path: () => join36(homedir12(), ".cursor", "rules", "dosu.mdc"),
|
|
30185
30098
|
cursorFrontmatter: true
|
|
30186
30099
|
},
|
|
30187
30100
|
codex: {
|
|
30188
30101
|
kind: "section",
|
|
30189
|
-
path: () =>
|
|
30102
|
+
path: () => join36(codexHome5(), "AGENTS.md")
|
|
30190
30103
|
},
|
|
30191
30104
|
opencode: {
|
|
30192
30105
|
kind: "section",
|
|
30193
|
-
path: () =>
|
|
30106
|
+
path: () => join36(homedir12(), ".config", "opencode", "AGENTS.md")
|
|
30194
30107
|
},
|
|
30195
30108
|
gemini: {
|
|
30196
30109
|
kind: "section",
|
|
30197
|
-
path: () =>
|
|
30198
|
-
},
|
|
30199
|
-
antigravity: {
|
|
30200
|
-
kind: "section",
|
|
30201
|
-
path: () => join43(homedir14(), ".gemini", "GEMINI.md")
|
|
30110
|
+
path: () => join36(homedir12(), ".gemini", "GEMINI.md")
|
|
30202
30111
|
}
|
|
30203
30112
|
};
|
|
30204
30113
|
});
|
|
30205
30114
|
|
|
30206
30115
|
// src/setup/agents-md-step.ts
|
|
30207
30116
|
import { execSync as execSync2 } from "node:child_process";
|
|
30208
|
-
import { existsSync as
|
|
30209
|
-
import { join as
|
|
30117
|
+
import { existsSync as existsSync28, readFileSync as readFileSync37, writeFileSync as writeFileSync19 } from "node:fs";
|
|
30118
|
+
import { join as join37 } from "node:path";
|
|
30210
30119
|
function inGitWorkTree(cwd = process.cwd()) {
|
|
30211
30120
|
try {
|
|
30212
30121
|
const stdout = execSync2("git rev-parse --is-inside-work-tree", {
|
|
@@ -30220,10 +30129,10 @@ function inGitWorkTree(cwd = process.cwd()) {
|
|
|
30220
30129
|
}
|
|
30221
30130
|
function dosuAgentsSectionState(cwd = process.cwd()) {
|
|
30222
30131
|
try {
|
|
30223
|
-
const path =
|
|
30224
|
-
if (!
|
|
30132
|
+
const path = join37(cwd, "AGENTS.md");
|
|
30133
|
+
if (!existsSync28(path))
|
|
30225
30134
|
return "missing";
|
|
30226
|
-
const content =
|
|
30135
|
+
const content = readFileSync37(path, "utf-8");
|
|
30227
30136
|
const startMatch = content.match(SECTION_START_RE);
|
|
30228
30137
|
if (!startMatch || !content.includes(DOSU_SECTION_END))
|
|
30229
30138
|
return "missing";
|
|
@@ -30258,14 +30167,14 @@ function findSection2(content) {
|
|
|
30258
30167
|
return { start, end };
|
|
30259
30168
|
}
|
|
30260
30169
|
function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
|
|
30261
|
-
const path =
|
|
30262
|
-
if (!
|
|
30170
|
+
const path = join37(cwd, "AGENTS.md");
|
|
30171
|
+
if (!existsSync28(path)) {
|
|
30263
30172
|
const section = buildDosuAgentsSection(content);
|
|
30264
30173
|
writeFileSync19(path, `${section}
|
|
30265
30174
|
`);
|
|
30266
30175
|
return { path, action: "created" };
|
|
30267
30176
|
}
|
|
30268
|
-
const existing =
|
|
30177
|
+
const existing = readFileSync37(path, "utf-8");
|
|
30269
30178
|
const lineEnding = lineEndingFor2(existing);
|
|
30270
30179
|
const section = renderDosuAgentsSection(content, lineEnding);
|
|
30271
30180
|
const location = findSection2(existing);
|
|
@@ -30566,6 +30475,58 @@ var init_rules_step = __esm(() => {
|
|
|
30566
30475
|
init_styles();
|
|
30567
30476
|
});
|
|
30568
30477
|
|
|
30478
|
+
// src/setup/scope-step.ts
|
|
30479
|
+
function scopeCandidates(sessions, current) {
|
|
30480
|
+
const byRepo = new Map;
|
|
30481
|
+
for (const { repo, updated } of sessions) {
|
|
30482
|
+
if (!repo)
|
|
30483
|
+
continue;
|
|
30484
|
+
const candidate = byRepo.get(repo);
|
|
30485
|
+
if (!candidate)
|
|
30486
|
+
byRepo.set(repo, { repo, sessions: 1, updated });
|
|
30487
|
+
else {
|
|
30488
|
+
candidate.sessions += 1;
|
|
30489
|
+
if (updated > candidate.updated)
|
|
30490
|
+
candidate.updated = updated;
|
|
30491
|
+
}
|
|
30492
|
+
}
|
|
30493
|
+
for (const repo of current ?? []) {
|
|
30494
|
+
if (!byRepo.has(repo))
|
|
30495
|
+
byRepo.set(repo, { repo, sessions: 0, updated: "" });
|
|
30496
|
+
}
|
|
30497
|
+
return [...byRepo.values()].sort((a, b) => b.sessions - a.sessions || b.updated.localeCompare(a.updated) || a.repo.localeCompare(b.repo));
|
|
30498
|
+
}
|
|
30499
|
+
function canPickScope(candidates) {
|
|
30500
|
+
return process.stdin.isTTY === true && candidates.length > 1;
|
|
30501
|
+
}
|
|
30502
|
+
async function stepPickSyncScope(candidates, current) {
|
|
30503
|
+
const repos = candidates.map((candidate) => candidate.repo);
|
|
30504
|
+
const plural = (n) => n === 1 ? "" : "s";
|
|
30505
|
+
const selected = await multiselect2({
|
|
30506
|
+
message: "Ship sessions to Dosu memory from which repos?",
|
|
30507
|
+
options: candidates.map(({ repo, sessions }) => ({
|
|
30508
|
+
value: repo,
|
|
30509
|
+
label: displayRepo(repo),
|
|
30510
|
+
hint: sessions > 0 ? `${sessions} session${plural(sessions)}` : "no recent sessions"
|
|
30511
|
+
})),
|
|
30512
|
+
initialValues: current ?? repos,
|
|
30513
|
+
summary: (picked) => picked.length === repos.length ? "all repos · new ones included automatically" : `${picked.length} of ${repos.length} repos`,
|
|
30514
|
+
validate: (picked) => picked.length === 0 ? "Select at least one repo." : undefined
|
|
30515
|
+
});
|
|
30516
|
+
if (isCancel2(selected))
|
|
30517
|
+
return current;
|
|
30518
|
+
const scope = selected.length === repos.length ? null : selected;
|
|
30519
|
+
saveRepoFilter(scope);
|
|
30520
|
+
log2.success(`Sync scope ${dim(`· ${scope ? scope.map(displayRepo).join(", ") : "all repos"}`)}`);
|
|
30521
|
+
return scope;
|
|
30522
|
+
}
|
|
30523
|
+
var init_scope_step = __esm(() => {
|
|
30524
|
+
init_repo();
|
|
30525
|
+
init_state();
|
|
30526
|
+
init_prompts();
|
|
30527
|
+
init_styles();
|
|
30528
|
+
});
|
|
30529
|
+
|
|
30569
30530
|
// src/auth/server.ts
|
|
30570
30531
|
function escapeHtml(value) {
|
|
30571
30532
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -31030,7 +30991,7 @@ async function runSetupFlow(opts = {}) {
|
|
|
31030
30991
|
return;
|
|
31031
30992
|
}
|
|
31032
30993
|
if (!refreshed.finishedOnboarding) {
|
|
31033
|
-
log2.warn("Your account still needs onboarding. Finish it in the browser at the Dosu app, then re-run `dosu setup`.");
|
|
30994
|
+
log2.warn(wrapLog("Your account still needs onboarding. Finish it in the browser at the Dosu app, then re-run `dosu setup`."));
|
|
31034
30995
|
trackInBackground(trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
31035
30996
|
reason: "onboarding_incomplete_after_handshake"
|
|
31036
30997
|
}));
|
|
@@ -31130,17 +31091,32 @@ async function stepOfferInitialSync(cfg) {
|
|
|
31130
31091
|
logger.info("setup", "Step: offer initial knowledge sync");
|
|
31131
31092
|
const s = spinner2();
|
|
31132
31093
|
s.start("Checking for agent sessions from the last 30 days...");
|
|
31133
|
-
const outcome = await runKnowledgeSync();
|
|
31134
|
-
const
|
|
31094
|
+
const outcome = await runKnowledgeSync({ everyRepo: true });
|
|
31095
|
+
const storedScope = loadSyncState().repo_filter ?? null;
|
|
31096
|
+
const everyBacklog = outcome.status === "backlog" ? unsettledSessions(outcome.sessions, state) : [];
|
|
31135
31097
|
const lineage = sessionLineage(outcome.sessions);
|
|
31136
|
-
const
|
|
31098
|
+
const offered = (sessions) => withoutSubagents(sessions).filter((session) => !isAgentIncognito(state, session, lineage));
|
|
31099
|
+
const inScope = (scope) => filterSessionsByRepo(everyBacklog, scope, (session) => session.repo ?? null);
|
|
31100
|
+
const candidates = scopeCandidates(offered(everyBacklog), storedScope);
|
|
31101
|
+
const pickScope = canPickScope(candidates);
|
|
31102
|
+
let backlog = pickScope ? everyBacklog : inScope(storedScope);
|
|
31103
|
+
let n = offered(backlog).length;
|
|
31137
31104
|
if (n === 0) {
|
|
31138
31105
|
s.stop("No recent agent sessions. Dosu memory learns from new ones as you work.");
|
|
31139
31106
|
recordCommandFacets({ backfill_offer: "not-offered" });
|
|
31140
31107
|
return;
|
|
31141
31108
|
}
|
|
31142
|
-
const them = n === 1 ? "it" : "them";
|
|
31143
31109
|
s.stop(`Found ${n} agent session${n === 1 ? "" : "s"} from the last 30 days on this machine.`);
|
|
31110
|
+
if (pickScope) {
|
|
31111
|
+
backlog = inScope(await stepPickSyncScope(candidates, storedScope));
|
|
31112
|
+
n = offered(backlog).length;
|
|
31113
|
+
if (n === 0) {
|
|
31114
|
+
log2.info(wrapLog("No sessions from those repos are waiting. Dosu memory learns from new ones."));
|
|
31115
|
+
recordCommandFacets({ backfill_offer: "not-offered" });
|
|
31116
|
+
return;
|
|
31117
|
+
}
|
|
31118
|
+
}
|
|
31119
|
+
const them = n === 1 ? "it" : "them";
|
|
31144
31120
|
const incognito = installedIncognitoCommands();
|
|
31145
31121
|
log2.message(wrapLog([
|
|
31146
31122
|
"Dosu memory learns from finished agent sessions: where things live, commands that work, approaches that failed, so the next agent starts from what the last one learned.",
|
|
@@ -31922,6 +31898,7 @@ var init_flow2 = __esm(() => {
|
|
|
31922
31898
|
init_agents_md_step();
|
|
31923
31899
|
init_analytics2();
|
|
31924
31900
|
init_rules_step();
|
|
31901
|
+
init_scope_step();
|
|
31925
31902
|
init_styles();
|
|
31926
31903
|
import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
31927
31904
|
OAUTH_ANALYTICS_REASONS = new Set([
|
|
@@ -31940,7 +31917,7 @@ var init_flow2 = __esm(() => {
|
|
|
31940
31917
|
// src/commands/upgrade.ts
|
|
31941
31918
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
31942
31919
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
31943
|
-
import { homedir as
|
|
31920
|
+
import { homedir as homedir13 } from "node:os";
|
|
31944
31921
|
import { posix, win32 } from "node:path";
|
|
31945
31922
|
function installSpec(version = VERSION) {
|
|
31946
31923
|
return `${PACKAGE_NAME}@${releaseTag(version)}`;
|
|
@@ -31997,7 +31974,7 @@ function packageRoots(manager, platform, comSpec, env, cwd) {
|
|
|
31997
31974
|
manager === "npm" ? path.join(lines[0], "@dosu", "cli") : path.join(lines[0], "node_modules", "@dosu", "cli")
|
|
31998
31975
|
];
|
|
31999
31976
|
}
|
|
32000
|
-
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd =
|
|
31977
|
+
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd = homedir13()) {
|
|
32001
31978
|
const path = platform === "win32" ? win32 : posix;
|
|
32002
31979
|
if (!entrypoint || !path.isAbsolute(entrypoint))
|
|
32003
31980
|
return null;
|
|
@@ -32055,7 +32032,7 @@ function runUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
|
32055
32032
|
}
|
|
32056
32033
|
const platform = options.platform ?? process.platform;
|
|
32057
32034
|
const env = options.env ?? process.env;
|
|
32058
|
-
const cwd = options.cwd ??
|
|
32035
|
+
const cwd = options.cwd ?? homedir13();
|
|
32059
32036
|
let manager = null;
|
|
32060
32037
|
if (channel === "npm") {
|
|
32061
32038
|
if (isNpxInvocation(channel, env)) {
|
|
@@ -32122,7 +32099,7 @@ function finishWithNewBinary(channel, options) {
|
|
|
32122
32099
|
return;
|
|
32123
32100
|
}
|
|
32124
32101
|
const result = spawnSync2(invocation.command, invocation.args, {
|
|
32125
|
-
cwd: options.cwd ??
|
|
32102
|
+
cwd: options.cwd ?? homedir13(),
|
|
32126
32103
|
shell: false,
|
|
32127
32104
|
stdio: "inherit"
|
|
32128
32105
|
});
|
|
@@ -32240,14 +32217,14 @@ var init_upgrade = __esm(() => {
|
|
|
32240
32217
|
});
|
|
32241
32218
|
|
|
32242
32219
|
// src/version/incognito-backfill-check.ts
|
|
32243
|
-
import { existsSync as
|
|
32244
|
-
import { join as
|
|
32220
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync18, writeFileSync as writeFileSync20 } from "node:fs";
|
|
32221
|
+
import { join as join38 } from "node:path";
|
|
32245
32222
|
function markerPath() {
|
|
32246
|
-
return
|
|
32223
|
+
return join38(getConfigDir(), MARKER_FILENAME);
|
|
32247
32224
|
}
|
|
32248
32225
|
function writeMarker() {
|
|
32249
32226
|
const dir = getConfigDir();
|
|
32250
|
-
if (!
|
|
32227
|
+
if (!existsSync29(dir))
|
|
32251
32228
|
mkdirSync18(dir, { recursive: true, mode: 448 });
|
|
32252
32229
|
writeFileSync20(markerPath(), JSON.stringify({ done: true }), { mode: 384 });
|
|
32253
32230
|
}
|
|
@@ -32260,7 +32237,7 @@ ${import_picocolors40.default.green(`✓ Dosu: added the incognito command to ${
|
|
|
32260
32237
|
function checkForIncognitoBackfill(options = {}) {
|
|
32261
32238
|
const notify = options.notify ?? true;
|
|
32262
32239
|
try {
|
|
32263
|
-
if (
|
|
32240
|
+
if (existsSync29(markerPath()))
|
|
32264
32241
|
return;
|
|
32265
32242
|
const added = [];
|
|
32266
32243
|
let failed = false;
|
|
@@ -32297,8 +32274,8 @@ var init_incognito_backfill_check = __esm(() => {
|
|
|
32297
32274
|
});
|
|
32298
32275
|
|
|
32299
32276
|
// src/version/update-check.ts
|
|
32300
|
-
import { existsSync as
|
|
32301
|
-
import { join as
|
|
32277
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync19, readFileSync as readFileSync38, writeFileSync as writeFileSync21 } from "node:fs";
|
|
32278
|
+
import { join as join39 } from "node:path";
|
|
32302
32279
|
function isValidVersion2(value) {
|
|
32303
32280
|
return typeof value === "string" && SEMVER_PATTERN.test(value);
|
|
32304
32281
|
}
|
|
@@ -32351,14 +32328,14 @@ function isNewerRelease(candidate, current) {
|
|
|
32351
32328
|
return false;
|
|
32352
32329
|
}
|
|
32353
32330
|
function getCachePath3() {
|
|
32354
|
-
return
|
|
32331
|
+
return join39(getConfigDir(), CACHE_FILENAME5);
|
|
32355
32332
|
}
|
|
32356
32333
|
function readCache() {
|
|
32357
32334
|
try {
|
|
32358
32335
|
const path = getCachePath3();
|
|
32359
|
-
if (!
|
|
32336
|
+
if (!existsSync30(path))
|
|
32360
32337
|
return null;
|
|
32361
|
-
const data = JSON.parse(
|
|
32338
|
+
const data = JSON.parse(readFileSync38(path, "utf-8"));
|
|
32362
32339
|
if (typeof data.lastCheck === "number" && isValidVersion2(data.latestVersion)) {
|
|
32363
32340
|
return data;
|
|
32364
32341
|
}
|
|
@@ -32370,7 +32347,7 @@ function readCache() {
|
|
|
32370
32347
|
function writeCache(cache) {
|
|
32371
32348
|
try {
|
|
32372
32349
|
const dir = getConfigDir();
|
|
32373
|
-
if (!
|
|
32350
|
+
if (!existsSync30(dir)) {
|
|
32374
32351
|
mkdirSync19(dir, { recursive: true, mode: 448 });
|
|
32375
32352
|
}
|
|
32376
32353
|
writeFileSync21(getCachePath3(), JSON.stringify(cache), { mode: 384 });
|
|
@@ -32406,9 +32383,9 @@ function styleHint(hint) {
|
|
|
32406
32383
|
return [before && import_picocolors41.default.dim(before), import_picocolors41.default.cyan(command), after && import_picocolors41.default.dim(after)].filter(Boolean).join("");
|
|
32407
32384
|
}
|
|
32408
32385
|
function framedNotice(content, width) {
|
|
32409
|
-
const innerWidth = Math.max(...content.map(
|
|
32386
|
+
const innerWidth = Math.max(...content.map(visibleWidth)) + BOX_PADDING * 2;
|
|
32410
32387
|
const framed = (line) => {
|
|
32411
|
-
const pad = innerWidth -
|
|
32388
|
+
const pad = innerWidth - visibleWidth(line);
|
|
32412
32389
|
const left = Math.floor(pad / 2);
|
|
32413
32390
|
return `${import_picocolors41.default.yellow("│")}${" ".repeat(left)}${line}${" ".repeat(pad - left)}${import_picocolors41.default.yellow("│")}`;
|
|
32414
32391
|
};
|
|
@@ -32826,7 +32803,7 @@ function wrapValue(text, room) {
|
|
|
32826
32803
|
const append = (piece, sep) => {
|
|
32827
32804
|
if (current === "")
|
|
32828
32805
|
current = piece;
|
|
32829
|
-
else if (
|
|
32806
|
+
else if (visibleWidth(current) + sep.length + visibleWidth(piece) <= room) {
|
|
32830
32807
|
current += sep + piece;
|
|
32831
32808
|
} else {
|
|
32832
32809
|
lines.push(current);
|
|
@@ -32834,7 +32811,7 @@ function wrapValue(text, room) {
|
|
|
32834
32811
|
}
|
|
32835
32812
|
};
|
|
32836
32813
|
for (const item of text.split(LIST_SEP)) {
|
|
32837
|
-
const pieces =
|
|
32814
|
+
const pieces = visibleWidth(item) <= room ? [item] : item.split(" ");
|
|
32838
32815
|
pieces.forEach((piece, i) => {
|
|
32839
32816
|
append(piece, i === 0 ? LIST_SEP : " ");
|
|
32840
32817
|
});
|
|
@@ -33534,43 +33511,27 @@ async function runSettings(cfg) {
|
|
|
33534
33511
|
}
|
|
33535
33512
|
}
|
|
33536
33513
|
function discoverSessionRepos(current) {
|
|
33537
|
-
const
|
|
33514
|
+
const inRepos = [];
|
|
33538
33515
|
try {
|
|
33539
33516
|
const resolver = createProjectDirResolver();
|
|
33540
33517
|
for (const session of scanAgentSessions({})) {
|
|
33541
33518
|
const repo = resolver.resolveRepo(session);
|
|
33542
33519
|
if (repo)
|
|
33543
|
-
|
|
33520
|
+
inRepos.push({ ...session, repo });
|
|
33544
33521
|
}
|
|
33545
33522
|
resolver.flush();
|
|
33546
33523
|
} catch {}
|
|
33547
|
-
|
|
33548
|
-
if (!counts.has(repo))
|
|
33549
|
-
counts.set(repo, 0);
|
|
33550
|
-
return [...counts.entries()].sort((a, b) => b[1] - a[1]).map(([repo]) => repo);
|
|
33524
|
+
return scopeCandidates(inRepos, current);
|
|
33551
33525
|
}
|
|
33552
33526
|
async function runStudyingProjectsSetting() {
|
|
33553
33527
|
const state = loadSyncState();
|
|
33554
33528
|
const current = studyRepoFilter(state, () => scanAgentSessions({}), createProjectDirResolver());
|
|
33555
|
-
const
|
|
33556
|
-
if (
|
|
33529
|
+
const candidates = discoverSessionRepos(current);
|
|
33530
|
+
if (candidates.length === 0) {
|
|
33557
33531
|
log2.info("No agent sessions inside a git repo found yet; nothing to scope.");
|
|
33558
33532
|
return;
|
|
33559
33533
|
}
|
|
33560
|
-
|
|
33561
|
-
message: "Ship sessions to Dosu memory from which repos?",
|
|
33562
|
-
options: repos.map((repo) => ({ label: displayRepo(repo), hint: repo, value: repo })),
|
|
33563
|
-
initialValues: current ?? repos,
|
|
33564
|
-
summary: (picked) => picked.length === repos.length ? "all repos · new ones included automatically" : `${picked.length} of ${repos.length} repos`,
|
|
33565
|
-
validate: (picked) => picked.length === 0 ? "Select at least one repo." : undefined
|
|
33566
|
-
});
|
|
33567
|
-
if (isCancel2(selected))
|
|
33568
|
-
return;
|
|
33569
|
-
const { repo_filter: _repos, project_filter: _folders, ...fresh } = loadSyncState();
|
|
33570
|
-
const all = selected.length === repos.length;
|
|
33571
|
-
saveSyncState(all ? fresh : { ...fresh, repo_filter: [...selected] });
|
|
33572
|
-
const scope = all ? "all repos" : selected.map(displayRepo).join(", ");
|
|
33573
|
-
log2.success(`Sync scope ${dim(`· ${scope}`)}`);
|
|
33534
|
+
await stepPickSyncScope(candidates, current);
|
|
33574
33535
|
}
|
|
33575
33536
|
async function handleAuthenticate(cfg) {
|
|
33576
33537
|
const shouldLogin = await confirm2({ message: "Open browser to log in?" });
|
|
@@ -33626,6 +33587,7 @@ var init_tui = __esm(() => {
|
|
|
33626
33587
|
init_scan();
|
|
33627
33588
|
init_agents_md_step();
|
|
33628
33589
|
init_flow2();
|
|
33590
|
+
init_scope_step();
|
|
33629
33591
|
init_styles();
|
|
33630
33592
|
init_state();
|
|
33631
33593
|
init_status();
|
|
@@ -34244,7 +34206,7 @@ var init_flow3 = __esm(() => {
|
|
|
34244
34206
|
});
|
|
34245
34207
|
|
|
34246
34208
|
// src/cli/cli.ts
|
|
34247
|
-
import { readFileSync as
|
|
34209
|
+
import { readFileSync as readFileSync39, unlinkSync as unlinkSync8 } from "node:fs";
|
|
34248
34210
|
function shouldRunBackgroundChecks(command) {
|
|
34249
34211
|
return !NO_BACKGROUND_CHECKS.has(command);
|
|
34250
34212
|
}
|
|
@@ -34698,7 +34660,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
34698
34660
|
}
|
|
34699
34661
|
if (opts.follow) {
|
|
34700
34662
|
try {
|
|
34701
|
-
const lines =
|
|
34663
|
+
const lines = readFileSync39(logPath, "utf-8").split(`
|
|
34702
34664
|
`);
|
|
34703
34665
|
if (lines.at(-1) === "")
|
|
34704
34666
|
lines.pop();
|
|
@@ -34714,7 +34676,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
34714
34676
|
if (opts.tail !== undefined) {
|
|
34715
34677
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
34716
34678
|
try {
|
|
34717
|
-
const content =
|
|
34679
|
+
const content = readFileSync39(logPath, "utf-8");
|
|
34718
34680
|
const lines = content.split(`
|
|
34719
34681
|
`);
|
|
34720
34682
|
console.log(lines.slice(-n).join(`
|
|
@@ -34900,4 +34862,4 @@ main().catch((err) => {
|
|
|
34900
34862
|
process.exit(1);
|
|
34901
34863
|
});
|
|
34902
34864
|
|
|
34903
|
-
//# debugId=
|
|
34865
|
+
//# debugId=38c8fa6e-6a2c-1ace-6475-6e2164756e21
|