@dosu/cli 0.60.2 → 0.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/bin/dosu.js +360 -119
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -107,6 +107,8 @@ Or right-click the binary, select "Open", and click "Open" in the dialog.
|
|
|
107
107
|
|
|
108
108
|
`dosu upgrade` delegates to npm, pnpm, Yarn Classic, or Homebrew only after confirming which manager owns the current installation. Temporary package-runner invocations stay ephemeral, ambiguous or local installs are left unchanged, and standalone binaries receive the latest safe manual download path. After a successful update it hands off to the new version, which re-applies the bundled skills and, only if the update crossed a release that changed the agent config format, runs `dosu setup` (or the non-interactive `dosu mcp refresh` without a TTY). Upgrades done outside `dosu upgrade` (npm, brew, `npx @dosu/cli@latest`) get a safety net: when the new version changed the shape of the MCP entry, the first command on it silently rewrites configured tools' MCP entries and prompts you to run `dosu setup` for the rest; the bundled agent skills are always re-applied on the first command after any version change.
|
|
109
109
|
|
|
110
|
+
Dosu also updates itself automatically. When the update check (every six hours) finds a newer release, npm, pnpm, Yarn Classic, and Homebrew installs start the same package-manager update in a detached background process. The current command runs unchanged, and your next command uses the new version, whose first run applies the skill and MCP refreshes above. Hooks, rules, and the status line still need `dosu setup` when a release changes them. Background updates never run for `npx` invocations, standalone binaries, CI, or `DOSU_DEV=true`. A failed install (for example, a global npm prefix that needs `sudo`) falls back to the "Run `dosu upgrade`" notice and is retried after six hours. Turn background updates off with `dosu upgrade --auto off` (and back on with `--auto on`), or with `DOSU_DISABLE_AUTOUPDATE=1` for a single environment.
|
|
111
|
+
|
|
110
112
|
### Platform commands
|
|
111
113
|
|
|
112
114
|
Once authenticated against a deployment, you can drive the Dosu platform without leaving the terminal:
|
package/bin/dosu.js
CHANGED
|
@@ -1083,7 +1083,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
1083
1083
|
function getVersionString() {
|
|
1084
1084
|
return `v${VERSION}`;
|
|
1085
1085
|
}
|
|
1086
|
-
var VERSION = "0.
|
|
1086
|
+
var VERSION = "0.61.0", INSTALL_CHANNEL = "npm";
|
|
1087
1087
|
|
|
1088
1088
|
// src/debug/logger.ts
|
|
1089
1089
|
import {
|
|
@@ -13800,7 +13800,7 @@ var init_conflicts = __esm(() => {
|
|
|
13800
13800
|
});
|
|
13801
13801
|
|
|
13802
13802
|
// src/telemetry/debug-id.ts
|
|
13803
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
13803
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "41cac967-78f1-f75a-6475-6e2164756e21";
|
|
13804
13804
|
|
|
13805
13805
|
// src/telemetry/telemetry.ts
|
|
13806
13806
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -60326,11 +60326,11 @@ dosu skill install | remove | update
|
|
|
60326
60326
|
dosu telemetry status [--json]
|
|
60327
60327
|
dosu telemetry enable | disable | reset
|
|
60328
60328
|
dosu insights
|
|
60329
|
-
dosu upgrade
|
|
60329
|
+
dosu upgrade [--auto on|off]
|
|
60330
60330
|
dosu logs [--tail [n]] [--clear]
|
|
60331
60331
|
\`\`\`
|
|
60332
60332
|
|
|
60333
|
-
\`deployments\` selects the MCP deployment stored in local config; it is distinct from \`agents\`. \`insights\` opens an interactive visual report. \`logs --clear\` deletes the CLI log file.
|
|
60333
|
+
\`deployments\` selects the MCP deployment stored in local config; it is distinct from \`agents\`. \`insights\` opens an interactive visual report. \`logs --clear\` deletes the CLI log file. The CLI updates itself in the background by default; a \`[dosu:update] Installing ...\` notice on stderr needs no action. \`upgrade --auto off\` turns that off.
|
|
60334
60334
|
|
|
60335
60335
|
## Codebase audit
|
|
60336
60336
|
|
|
@@ -62341,10 +62341,204 @@ var init_refresh = __esm(() => {
|
|
|
62341
62341
|
init_providers();
|
|
62342
62342
|
});
|
|
62343
62343
|
|
|
62344
|
-
// src/version/update
|
|
62345
|
-
import {
|
|
62344
|
+
// src/version/auto-update.ts
|
|
62345
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
62346
|
+
import {
|
|
62347
|
+
closeSync as closeSync6,
|
|
62348
|
+
existsSync as existsSync23,
|
|
62349
|
+
mkdirSync as mkdirSync13,
|
|
62350
|
+
openSync as openSync6,
|
|
62351
|
+
readFileSync as readFileSync22,
|
|
62352
|
+
rmSync as rmSync7,
|
|
62353
|
+
statSync as statSync8,
|
|
62354
|
+
writeFileSync as writeFileSync14,
|
|
62355
|
+
writeSync
|
|
62356
|
+
} from "node:fs";
|
|
62357
|
+
import { homedir as homedir11 } from "node:os";
|
|
62346
62358
|
import { join as join38 } from "node:path";
|
|
62359
|
+
function statePath() {
|
|
62360
|
+
return join38(getConfigDir(), STATE_FILENAME2);
|
|
62361
|
+
}
|
|
62362
|
+
function lockPath2() {
|
|
62363
|
+
return join38(getConfigDir(), LOCK_FILENAME2);
|
|
62364
|
+
}
|
|
62347
62365
|
function isValidVersion(value) {
|
|
62366
|
+
return typeof value === "string" && VERSION_PATTERN.test(value);
|
|
62367
|
+
}
|
|
62368
|
+
function readState() {
|
|
62369
|
+
try {
|
|
62370
|
+
const raw = JSON.parse(readFileSync22(statePath(), "utf-8"));
|
|
62371
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
62372
|
+
return {};
|
|
62373
|
+
const data = raw;
|
|
62374
|
+
const state = {};
|
|
62375
|
+
if (data.disabled === true)
|
|
62376
|
+
state.disabled = true;
|
|
62377
|
+
const last = data.lastAttempt;
|
|
62378
|
+
if (last && isValidVersion(last.version) && typeof last.ok === "boolean" && typeof last.finishedAt === "number") {
|
|
62379
|
+
state.lastAttempt = { version: last.version, ok: last.ok, finishedAt: last.finishedAt };
|
|
62380
|
+
}
|
|
62381
|
+
return state;
|
|
62382
|
+
} catch {
|
|
62383
|
+
return {};
|
|
62384
|
+
}
|
|
62385
|
+
}
|
|
62386
|
+
function writeState(state) {
|
|
62387
|
+
try {
|
|
62388
|
+
const dir = getConfigDir();
|
|
62389
|
+
if (!existsSync23(dir))
|
|
62390
|
+
mkdirSync13(dir, { recursive: true, mode: 448 });
|
|
62391
|
+
writeFileSync14(statePath(), `${JSON.stringify(state, null, 2)}
|
|
62392
|
+
`, { mode: 384 });
|
|
62393
|
+
return true;
|
|
62394
|
+
} catch {
|
|
62395
|
+
return false;
|
|
62396
|
+
}
|
|
62397
|
+
}
|
|
62398
|
+
function isEnabledFlag(value) {
|
|
62399
|
+
if (value === undefined)
|
|
62400
|
+
return false;
|
|
62401
|
+
const normalized = value.trim().toLowerCase();
|
|
62402
|
+
return normalized !== "" && !["0", "false", "no", "off"].includes(normalized);
|
|
62403
|
+
}
|
|
62404
|
+
function autoUpdateDisabledReason(env = process.env) {
|
|
62405
|
+
if (isEnabledFlag(env[AUTO_UPDATE_ENV]))
|
|
62406
|
+
return "env";
|
|
62407
|
+
if (readState().disabled)
|
|
62408
|
+
return "settings";
|
|
62409
|
+
return;
|
|
62410
|
+
}
|
|
62411
|
+
function setAutoUpdateEnabled(enabled) {
|
|
62412
|
+
const state = readState();
|
|
62413
|
+
if (enabled)
|
|
62414
|
+
delete state.disabled;
|
|
62415
|
+
else
|
|
62416
|
+
state.disabled = true;
|
|
62417
|
+
return writeState(state);
|
|
62418
|
+
}
|
|
62419
|
+
function canAutoUpdate(channel, env) {
|
|
62420
|
+
if (env.NODE_ENV === "test" || env.CI || env.DOSU_DEV === "true")
|
|
62421
|
+
return false;
|
|
62422
|
+
if (!SUPPORTED_CHANNELS.has(channel) || isNpxInvocation(channel, env))
|
|
62423
|
+
return false;
|
|
62424
|
+
return autoUpdateDisabledReason(env) === undefined;
|
|
62425
|
+
}
|
|
62426
|
+
function backgroundInvocation(channel, entrypoint = process.argv[1], execPath = process.execPath) {
|
|
62427
|
+
const args = ["upgrade", "--background"];
|
|
62428
|
+
if (channel === "npm") {
|
|
62429
|
+
return entrypoint ? { command: execPath, args: [entrypoint, ...args] } : null;
|
|
62430
|
+
}
|
|
62431
|
+
if (channel === "homebrew")
|
|
62432
|
+
return { command: execPath, args };
|
|
62433
|
+
return null;
|
|
62434
|
+
}
|
|
62435
|
+
function lockIsFresh(now) {
|
|
62436
|
+
try {
|
|
62437
|
+
return now - statSync8(lockPath2()).mtimeMs < LOCK_STALE_MS;
|
|
62438
|
+
} catch {
|
|
62439
|
+
return false;
|
|
62440
|
+
}
|
|
62441
|
+
}
|
|
62442
|
+
function claimLock(version, now) {
|
|
62443
|
+
try {
|
|
62444
|
+
mkdirSync13(getConfigDir(), { recursive: true, mode: 448 });
|
|
62445
|
+
if (!lockIsFresh(now))
|
|
62446
|
+
rmSync7(lockPath2(), { force: true });
|
|
62447
|
+
const fd = openSync6(lockPath2(), "wx", 384);
|
|
62448
|
+
try {
|
|
62449
|
+
writeSync(fd, version);
|
|
62450
|
+
} finally {
|
|
62451
|
+
closeSync6(fd);
|
|
62452
|
+
}
|
|
62453
|
+
return "claimed";
|
|
62454
|
+
} catch (err) {
|
|
62455
|
+
return err.code === "EEXIST" ? "held" : "failed";
|
|
62456
|
+
}
|
|
62457
|
+
}
|
|
62458
|
+
function releaseLock() {
|
|
62459
|
+
try {
|
|
62460
|
+
rmSync7(lockPath2(), { force: true });
|
|
62461
|
+
} catch {}
|
|
62462
|
+
}
|
|
62463
|
+
function readLockVersion() {
|
|
62464
|
+
try {
|
|
62465
|
+
const version = readFileSync22(lockPath2(), "utf-8").trim();
|
|
62466
|
+
return isValidVersion(version) ? version : undefined;
|
|
62467
|
+
} catch {
|
|
62468
|
+
return;
|
|
62469
|
+
}
|
|
62470
|
+
}
|
|
62471
|
+
function startAutoUpdate(version, options = {}) {
|
|
62472
|
+
const channel = options.channel ?? INSTALL_CHANNEL;
|
|
62473
|
+
const env = options.env ?? process.env;
|
|
62474
|
+
const now = options.now ?? Date.now();
|
|
62475
|
+
try {
|
|
62476
|
+
if (!isValidVersion(version) || !canAutoUpdate(channel, env))
|
|
62477
|
+
return "unavailable";
|
|
62478
|
+
if (lockIsFresh(now))
|
|
62479
|
+
return "in_progress";
|
|
62480
|
+
const last = readState().lastAttempt;
|
|
62481
|
+
if (last?.version === version && now - last.finishedAt < RETRY_INTERVAL_MS) {
|
|
62482
|
+
return "unavailable";
|
|
62483
|
+
}
|
|
62484
|
+
const invocation = backgroundInvocation(channel, options.entrypoint, options.execPath);
|
|
62485
|
+
if (!invocation)
|
|
62486
|
+
return "unavailable";
|
|
62487
|
+
const claim = claimLock(version, now);
|
|
62488
|
+
if (claim !== "claimed")
|
|
62489
|
+
return claim === "held" ? "in_progress" : "unavailable";
|
|
62490
|
+
try {
|
|
62491
|
+
const child = spawn3(invocation.command, invocation.args, {
|
|
62492
|
+
cwd: homedir11(),
|
|
62493
|
+
detached: true,
|
|
62494
|
+
stdio: "ignore",
|
|
62495
|
+
windowsHide: true,
|
|
62496
|
+
env: { ...env, DOSU_TELEMETRY_DISABLED: "1" }
|
|
62497
|
+
});
|
|
62498
|
+
child.on("error", releaseLock);
|
|
62499
|
+
child.unref();
|
|
62500
|
+
} catch (err) {
|
|
62501
|
+
releaseLock();
|
|
62502
|
+
throw err;
|
|
62503
|
+
}
|
|
62504
|
+
logger.info("auto-update", `Started background update to ${version}`);
|
|
62505
|
+
return "started";
|
|
62506
|
+
} catch (err) {
|
|
62507
|
+
logger.error("auto-update", `Could not start background update: ${err}`);
|
|
62508
|
+
return "unavailable";
|
|
62509
|
+
}
|
|
62510
|
+
}
|
|
62511
|
+
function runBackgroundUpgrade(upgrade, now = Date.now) {
|
|
62512
|
+
const version = readLockVersion();
|
|
62513
|
+
let status = 1;
|
|
62514
|
+
try {
|
|
62515
|
+
status = upgrade();
|
|
62516
|
+
} catch (err) {
|
|
62517
|
+
logger.error("auto-update", `Background update threw: ${err}`);
|
|
62518
|
+
}
|
|
62519
|
+
if (version) {
|
|
62520
|
+
const state = readState();
|
|
62521
|
+
state.lastAttempt = { version, ok: status === 0, finishedAt: now() };
|
|
62522
|
+
writeState(state);
|
|
62523
|
+
}
|
|
62524
|
+
logger.info("auto-update", `Background update ${status === 0 ? "finished" : "failed"}`);
|
|
62525
|
+
releaseLock();
|
|
62526
|
+
return status;
|
|
62527
|
+
}
|
|
62528
|
+
var STATE_FILENAME2 = "auto-update.json", LOCK_FILENAME2 = "auto-update.lock", LOCK_STALE_MS, RETRY_INTERVAL_MS, SUPPORTED_CHANNELS, VERSION_PATTERN, AUTO_UPDATE_ENV = "DOSU_DISABLE_AUTOUPDATE";
|
|
62529
|
+
var init_auto_update = __esm(() => {
|
|
62530
|
+
init_config();
|
|
62531
|
+
init_logger();
|
|
62532
|
+
LOCK_STALE_MS = 15 * 60 * 1000;
|
|
62533
|
+
RETRY_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
62534
|
+
SUPPORTED_CHANNELS = new Set(["npm", "homebrew"]);
|
|
62535
|
+
VERSION_PATTERN = /^[0-9A-Za-z.+-]{1,64}$/;
|
|
62536
|
+
});
|
|
62537
|
+
|
|
62538
|
+
// src/version/update-check.ts
|
|
62539
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
62540
|
+
import { join as join39 } from "node:path";
|
|
62541
|
+
function isValidVersion2(value) {
|
|
62348
62542
|
return typeof value === "string" && SEMVER_PATTERN.test(value);
|
|
62349
62543
|
}
|
|
62350
62544
|
function stripPrerelease(version) {
|
|
@@ -62365,15 +62559,15 @@ function isNewerVersion(latest, current) {
|
|
|
62365
62559
|
return false;
|
|
62366
62560
|
}
|
|
62367
62561
|
function getCachePath2() {
|
|
62368
|
-
return
|
|
62562
|
+
return join39(getConfigDir(), CACHE_FILENAME3);
|
|
62369
62563
|
}
|
|
62370
62564
|
function readCache() {
|
|
62371
62565
|
try {
|
|
62372
62566
|
const path = getCachePath2();
|
|
62373
|
-
if (!
|
|
62567
|
+
if (!existsSync24(path))
|
|
62374
62568
|
return null;
|
|
62375
|
-
const data = JSON.parse(
|
|
62376
|
-
if (typeof data.lastCheck === "number" &&
|
|
62569
|
+
const data = JSON.parse(readFileSync23(path, "utf-8"));
|
|
62570
|
+
if (typeof data.lastCheck === "number" && isValidVersion2(data.latestVersion)) {
|
|
62377
62571
|
return data;
|
|
62378
62572
|
}
|
|
62379
62573
|
return null;
|
|
@@ -62384,10 +62578,10 @@ function readCache() {
|
|
|
62384
62578
|
function writeCache(cache) {
|
|
62385
62579
|
try {
|
|
62386
62580
|
const dir = getConfigDir();
|
|
62387
|
-
if (!
|
|
62388
|
-
|
|
62581
|
+
if (!existsSync24(dir)) {
|
|
62582
|
+
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
62389
62583
|
}
|
|
62390
|
-
|
|
62584
|
+
writeFileSync15(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
62391
62585
|
} catch {}
|
|
62392
62586
|
}
|
|
62393
62587
|
async function fetchLatestVersion() {
|
|
@@ -62399,7 +62593,7 @@ async function fetchLatestVersion() {
|
|
|
62399
62593
|
return null;
|
|
62400
62594
|
const data = await resp.json();
|
|
62401
62595
|
const latest = data.latest;
|
|
62402
|
-
return
|
|
62596
|
+
return isValidVersion2(latest) ? latest : null;
|
|
62403
62597
|
} catch {
|
|
62404
62598
|
return null;
|
|
62405
62599
|
} finally {
|
|
@@ -62419,30 +62613,43 @@ function styleHint(hint) {
|
|
|
62419
62613
|
const [, before, command, after] = match;
|
|
62420
62614
|
return [before && import_picocolors30.default.dim(before), import_picocolors30.default.cyan(command), after && import_picocolors30.default.dim(after)].filter(Boolean).join("");
|
|
62421
62615
|
}
|
|
62422
|
-
function
|
|
62423
|
-
const
|
|
62424
|
-
|
|
62425
|
-
const
|
|
62426
|
-
|
|
62427
|
-
|
|
62428
|
-
|
|
62429
|
-
|
|
62430
|
-
|
|
62431
|
-
|
|
62432
|
-
|
|
62433
|
-
|
|
62434
|
-
}
|
|
62435
|
-
|
|
62436
|
-
|
|
62437
|
-
framed(""),
|
|
62438
|
-
...content.map(framed),
|
|
62439
|
-
framed(""),
|
|
62440
|
-
import_picocolors30.default.yellow(`╰${"─".repeat(innerWidth)}╯`)
|
|
62441
|
-
];
|
|
62442
|
-
return `
|
|
62616
|
+
function framedNotice(content, width) {
|
|
62617
|
+
const innerWidth = Math.max(...content.map(visibleWidth2)) + BOX_PADDING * 2;
|
|
62618
|
+
const framed = (line) => {
|
|
62619
|
+
const pad = innerWidth - visibleWidth2(line);
|
|
62620
|
+
const left = Math.floor(pad / 2);
|
|
62621
|
+
return `${import_picocolors30.default.yellow("│")}${" ".repeat(left)}${line}${" ".repeat(pad - left)}${import_picocolors30.default.yellow("│")}`;
|
|
62622
|
+
};
|
|
62623
|
+
const box = [
|
|
62624
|
+
import_picocolors30.default.yellow(`╭${"─".repeat(innerWidth)}╮`),
|
|
62625
|
+
framed(""),
|
|
62626
|
+
...content.map(framed),
|
|
62627
|
+
framed(""),
|
|
62628
|
+
import_picocolors30.default.yellow(`╰${"─".repeat(innerWidth)}╯`)
|
|
62629
|
+
];
|
|
62630
|
+
return `
|
|
62443
62631
|
${centerBlock(box, width).join(`
|
|
62444
62632
|
`)}
|
|
62445
62633
|
`;
|
|
62634
|
+
}
|
|
62635
|
+
function versionArrow(current, latest) {
|
|
62636
|
+
return `${import_picocolors30.default.dim(current)} ${import_picocolors30.default.dim("→")} ${import_picocolors30.default.bold(brand(latest))}`;
|
|
62637
|
+
}
|
|
62638
|
+
function buildAutoUpdateNotice(current, latest, interactive, width = process.stderr.columns ?? 80) {
|
|
62639
|
+
if (interactive) {
|
|
62640
|
+
return framedNotice([
|
|
62641
|
+
`Updating Dosu: ${versionArrow(current, latest)}`,
|
|
62642
|
+
import_picocolors30.default.dim("Installing in the background; your next command uses it")
|
|
62643
|
+
], width);
|
|
62644
|
+
}
|
|
62645
|
+
return `
|
|
62646
|
+
[dosu:update] Installing Dosu ${latest} in the background (running ${current}). ` + `The next Dosu command uses it; no action needed.
|
|
62647
|
+
`;
|
|
62648
|
+
}
|
|
62649
|
+
function buildUpdateNotice(current, latest, channel, interactive, npx = false, width = process.stderr.columns ?? 80) {
|
|
62650
|
+
const hint = buildUpdateHint(channel, npx);
|
|
62651
|
+
if (interactive) {
|
|
62652
|
+
return framedNotice([`Update available: ${versionArrow(current, latest)}`, styleHint(hint)], width);
|
|
62446
62653
|
}
|
|
62447
62654
|
const agentAction = hint[0].toLowerCase() + hint.slice(1);
|
|
62448
62655
|
const verifyCommand = npx ? "npx -y @dosu/cli@latest --version" : "dosu --version";
|
|
@@ -62455,8 +62662,12 @@ function getAvailableUpdate() {
|
|
|
62455
62662
|
const cache = readCache();
|
|
62456
62663
|
return cache && isNewerVersion(cache.latestVersion, VERSION) ? cache.latestVersion : null;
|
|
62457
62664
|
}
|
|
62458
|
-
function
|
|
62459
|
-
|
|
62665
|
+
function handleNewerVersion(latest, notify) {
|
|
62666
|
+
const autoUpdate = startAutoUpdate(latest);
|
|
62667
|
+
if (!notify)
|
|
62668
|
+
return;
|
|
62669
|
+
const interactive = process.stderr.isTTY === true;
|
|
62670
|
+
console.error(autoUpdate === "unavailable" ? buildUpdateNotice(VERSION, latest, INSTALL_CHANNEL, interactive, isNpxInvocation()) : buildAutoUpdateNotice(VERSION, latest, interactive));
|
|
62460
62671
|
}
|
|
62461
62672
|
async function checkForUpdates(options = {}) {
|
|
62462
62673
|
const notify = options.notify ?? true;
|
|
@@ -62464,8 +62675,8 @@ async function checkForUpdates(options = {}) {
|
|
|
62464
62675
|
const cache = readCache();
|
|
62465
62676
|
const isStale = !cache || Date.now() - cache.lastCheck > CHECK_INTERVAL_MS2;
|
|
62466
62677
|
if (!isStale) {
|
|
62467
|
-
if (
|
|
62468
|
-
|
|
62678
|
+
if (isNewerVersion(cache.latestVersion, VERSION)) {
|
|
62679
|
+
handleNewerVersion(cache.latestVersion, notify);
|
|
62469
62680
|
}
|
|
62470
62681
|
return;
|
|
62471
62682
|
}
|
|
@@ -62478,8 +62689,8 @@ async function checkForUpdates(options = {}) {
|
|
|
62478
62689
|
if (latest) {
|
|
62479
62690
|
logger.debug("update-check", `Cached latest version: ${latest}`);
|
|
62480
62691
|
}
|
|
62481
|
-
if (
|
|
62482
|
-
|
|
62692
|
+
if (isNewerVersion(latestKnownVersion, VERSION)) {
|
|
62693
|
+
handleNewerVersion(latestKnownVersion, notify);
|
|
62483
62694
|
}
|
|
62484
62695
|
} catch (err) {
|
|
62485
62696
|
logger.error("update-check", `Update check failed: ${err}`);
|
|
@@ -62491,14 +62702,15 @@ var init_update_check = __esm(() => {
|
|
|
62491
62702
|
init_logger();
|
|
62492
62703
|
init_styles();
|
|
62493
62704
|
init_layout();
|
|
62705
|
+
init_auto_update();
|
|
62494
62706
|
import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
62495
62707
|
CHECK_INTERVAL_MS2 = 6 * 60 * 60 * 1000;
|
|
62496
62708
|
SEMVER_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
62497
62709
|
});
|
|
62498
62710
|
|
|
62499
62711
|
// src/version/mcp-refresh-check.ts
|
|
62500
|
-
import { existsSync as
|
|
62501
|
-
import { join as
|
|
62712
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
|
|
62713
|
+
import { join as join40 } from "node:path";
|
|
62502
62714
|
function needsMcpRefresh(previous, current) {
|
|
62503
62715
|
if (previous === null)
|
|
62504
62716
|
return true;
|
|
@@ -62508,14 +62720,14 @@ function needsMcpRefresh(previous, current) {
|
|
|
62508
62720
|
return MCP_FORMAT_CHANGES.some((change) => isNewerVersion(change, older) && !isNewerVersion(change, newer));
|
|
62509
62721
|
}
|
|
62510
62722
|
function getCachePath3() {
|
|
62511
|
-
return
|
|
62723
|
+
return join40(getConfigDir(), CACHE_FILENAME4);
|
|
62512
62724
|
}
|
|
62513
62725
|
function readMcpRefreshCache() {
|
|
62514
62726
|
try {
|
|
62515
62727
|
const path = getCachePath3();
|
|
62516
|
-
if (!
|
|
62728
|
+
if (!existsSync25(path))
|
|
62517
62729
|
return null;
|
|
62518
|
-
const data = JSON.parse(
|
|
62730
|
+
const data = JSON.parse(readFileSync24(path, "utf-8"));
|
|
62519
62731
|
if (typeof data?.version === "string")
|
|
62520
62732
|
return { version: data.version };
|
|
62521
62733
|
return null;
|
|
@@ -62526,10 +62738,10 @@ function readMcpRefreshCache() {
|
|
|
62526
62738
|
function writeMcpRefreshCache(cache) {
|
|
62527
62739
|
try {
|
|
62528
62740
|
const dir = getConfigDir();
|
|
62529
|
-
if (!
|
|
62530
|
-
|
|
62741
|
+
if (!existsSync25(dir)) {
|
|
62742
|
+
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
62531
62743
|
}
|
|
62532
|
-
|
|
62744
|
+
writeFileSync16(getCachePath3(), JSON.stringify(cache), { mode: 384 });
|
|
62533
62745
|
} catch {}
|
|
62534
62746
|
}
|
|
62535
62747
|
function canRefreshMcp(cfg) {
|
|
@@ -62538,7 +62750,7 @@ function canRefreshMcp(cfg) {
|
|
|
62538
62750
|
return false;
|
|
62539
62751
|
return cfg.mode === MODE_OSS || Boolean(target.deployment_id);
|
|
62540
62752
|
}
|
|
62541
|
-
function
|
|
62753
|
+
function displayNotice(names) {
|
|
62542
62754
|
console.error(`
|
|
62543
62755
|
${import_picocolors31.default.green(`✓ Dosu ${VERSION}: refreshed MCP config for ${names.join(", ")}`)}
|
|
62544
62756
|
` + `${import_picocolors31.default.dim(` Run ${import_picocolors31.default.cyan('"dosu setup"')} to also update hooks and rules, then restart your AI agents.`)}
|
|
@@ -62563,7 +62775,7 @@ function checkForMcpRefresh(options = {}) {
|
|
|
62563
62775
|
writeMcpRefreshCache({ version: VERSION });
|
|
62564
62776
|
logger.info("mcp-refresh", `Version ${VERSION}: refreshed ${result.updated.length}, failed ${result.failed.length}`);
|
|
62565
62777
|
if (notify && result.updated.length > 0) {
|
|
62566
|
-
|
|
62778
|
+
displayNotice(result.updated.map((provider) => provider.name()));
|
|
62567
62779
|
}
|
|
62568
62780
|
} catch (err) {
|
|
62569
62781
|
logger.error("mcp-refresh", `MCP refresh check failed: ${err}`);
|
|
@@ -62580,7 +62792,7 @@ var init_mcp_refresh_check = __esm(() => {
|
|
|
62580
62792
|
});
|
|
62581
62793
|
|
|
62582
62794
|
// src/version/skill-update-check.ts
|
|
62583
|
-
function
|
|
62795
|
+
function displayNotice2() {
|
|
62584
62796
|
console.error(`
|
|
62585
62797
|
${import_picocolors32.default.green(`✓ Dosu ${VERSION}: refreshed the bundled agent skills`)}
|
|
62586
62798
|
` + `${import_picocolors32.default.dim(" Restart your AI agents to pick up the new skill content.")}
|
|
@@ -62599,7 +62811,7 @@ function checkForSkillUpdates(options = {}) {
|
|
|
62599
62811
|
}
|
|
62600
62812
|
logger.info("skill-update-check", `Refreshed skills from ${state.version} to ${VERSION}`);
|
|
62601
62813
|
if (notify && result.version)
|
|
62602
|
-
|
|
62814
|
+
displayNotice2();
|
|
62603
62815
|
} catch (err) {
|
|
62604
62816
|
logger.error("skill-update-check", `Skill update check failed: ${err}`);
|
|
62605
62817
|
}
|
|
@@ -62639,11 +62851,11 @@ var init_errors3 = __esm(() => {
|
|
|
62639
62851
|
var MCP_PROVIDER_SLUG2 = "dosu_mcp";
|
|
62640
62852
|
|
|
62641
62853
|
// src/debug/follow.ts
|
|
62642
|
-
import { closeSync as
|
|
62854
|
+
import { closeSync as closeSync7, openSync as openSync7, readSync as readSync5, statSync as statSync9 } from "node:fs";
|
|
62643
62855
|
function createLogFollower(path, emit) {
|
|
62644
62856
|
const sizeOf = () => {
|
|
62645
62857
|
try {
|
|
62646
|
-
return
|
|
62858
|
+
return statSync9(path).size;
|
|
62647
62859
|
} catch {
|
|
62648
62860
|
return 0;
|
|
62649
62861
|
}
|
|
@@ -62657,7 +62869,7 @@ function createLogFollower(path, emit) {
|
|
|
62657
62869
|
if (size === offset)
|
|
62658
62870
|
return;
|
|
62659
62871
|
try {
|
|
62660
|
-
const fd =
|
|
62872
|
+
const fd = openSync7(path, "r");
|
|
62661
62873
|
try {
|
|
62662
62874
|
const buf = Buffer.alloc(size - offset);
|
|
62663
62875
|
const read = readSync5(fd, buf, 0, buf.length, offset);
|
|
@@ -62665,7 +62877,7 @@ function createLogFollower(path, emit) {
|
|
|
62665
62877
|
if (read > 0)
|
|
62666
62878
|
emit(buf.toString("utf-8", 0, read));
|
|
62667
62879
|
} finally {
|
|
62668
|
-
|
|
62880
|
+
closeSync7(fd);
|
|
62669
62881
|
}
|
|
62670
62882
|
} catch {}
|
|
62671
62883
|
}
|
|
@@ -62674,15 +62886,15 @@ function createLogFollower(path, emit) {
|
|
|
62674
62886
|
var init_follow = () => {};
|
|
62675
62887
|
|
|
62676
62888
|
// src/sessions/session-title.ts
|
|
62677
|
-
import { existsSync as
|
|
62678
|
-
import { homedir as
|
|
62679
|
-
import { join as
|
|
62889
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync25, renameSync as renameSync6, statSync as statSync10, writeFileSync as writeFileSync17 } from "node:fs";
|
|
62890
|
+
import { homedir as homedir12 } from "node:os";
|
|
62891
|
+
import { join as join41 } from "node:path";
|
|
62680
62892
|
function cachePath2(configDir) {
|
|
62681
|
-
return
|
|
62893
|
+
return join41(configDir, CACHE_FILENAME5);
|
|
62682
62894
|
}
|
|
62683
62895
|
function loadCacheFile2(configDir) {
|
|
62684
62896
|
try {
|
|
62685
|
-
const raw = JSON.parse(
|
|
62897
|
+
const raw = JSON.parse(readFileSync25(cachePath2(configDir), "utf-8"));
|
|
62686
62898
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION2 || typeof raw.entries !== "object")
|
|
62687
62899
|
return {};
|
|
62688
62900
|
return raw.entries;
|
|
@@ -62692,12 +62904,12 @@ function loadCacheFile2(configDir) {
|
|
|
62692
62904
|
}
|
|
62693
62905
|
function saveCacheFile2(configDir, entries) {
|
|
62694
62906
|
try {
|
|
62695
|
-
if (!
|
|
62696
|
-
|
|
62907
|
+
if (!existsSync26(configDir))
|
|
62908
|
+
mkdirSync16(configDir, { recursive: true, mode: 448 });
|
|
62697
62909
|
const path = cachePath2(configDir);
|
|
62698
62910
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
62699
62911
|
const file = { schema_version: CACHE_SCHEMA_VERSION2, entries };
|
|
62700
|
-
|
|
62912
|
+
writeFileSync17(tmp, JSON.stringify(file), { mode: 384 });
|
|
62701
62913
|
renameSync6(tmp, path);
|
|
62702
62914
|
} catch {}
|
|
62703
62915
|
}
|
|
@@ -62730,15 +62942,15 @@ function claudeSummaryFromHead(text) {
|
|
|
62730
62942
|
}
|
|
62731
62943
|
return null;
|
|
62732
62944
|
}
|
|
62733
|
-
function reconstructSession(harness, id, slug, home =
|
|
62945
|
+
function reconstructSession(harness, id, slug, home = homedir12(), exists = existsSync26) {
|
|
62734
62946
|
if (!slug)
|
|
62735
62947
|
return null;
|
|
62736
62948
|
const candidates = [];
|
|
62737
62949
|
if (harness === "claude") {
|
|
62738
|
-
candidates.push(
|
|
62950
|
+
candidates.push(join41(home, ".claude", "projects", slug, `${id}.jsonl`));
|
|
62739
62951
|
} else if (harness === "cursor") {
|
|
62740
|
-
const project =
|
|
62741
|
-
candidates.push(
|
|
62952
|
+
const project = join41(home, ".cursor", "projects", slug);
|
|
62953
|
+
candidates.push(join41(project, "agent-transcripts", id, `${id}.jsonl`), join41(project, "agent-transcripts", `${id}.jsonl`));
|
|
62742
62954
|
} else {
|
|
62743
62955
|
return null;
|
|
62744
62956
|
}
|
|
@@ -62750,14 +62962,14 @@ function reconstructSession(harness, id, slug, home = homedir11(), exists = exis
|
|
|
62750
62962
|
}
|
|
62751
62963
|
function readHead2(path) {
|
|
62752
62964
|
try {
|
|
62753
|
-
return
|
|
62965
|
+
return readFileSync25(path, "utf-8").slice(0, 128 * 1024);
|
|
62754
62966
|
} catch {
|
|
62755
62967
|
return null;
|
|
62756
62968
|
}
|
|
62757
62969
|
}
|
|
62758
62970
|
function fileMtime2(path) {
|
|
62759
62971
|
try {
|
|
62760
|
-
return
|
|
62972
|
+
return statSync10(path).mtime.toISOString();
|
|
62761
62973
|
} catch {
|
|
62762
62974
|
return "";
|
|
62763
62975
|
}
|
|
@@ -62830,7 +63042,7 @@ var init_alt_screen = __esm(() => {
|
|
|
62830
63042
|
});
|
|
62831
63043
|
|
|
62832
63044
|
// src/tui/activity-view.ts
|
|
62833
|
-
import { existsSync as
|
|
63045
|
+
import { existsSync as existsSync27, readFileSync as readFileSync26 } from "node:fs";
|
|
62834
63046
|
import { basename as basename5 } from "node:path";
|
|
62835
63047
|
function reduceActivityViewKey(key) {
|
|
62836
63048
|
if (key === "q" || key === ESC7 || key === CTRL_C4)
|
|
@@ -63151,7 +63363,7 @@ function createRowNamer() {
|
|
|
63151
63363
|
names.titles[key] = t;
|
|
63152
63364
|
};
|
|
63153
63365
|
for (const s of [...backlog.queued, ...backlog.open]) {
|
|
63154
|
-
if (!
|
|
63366
|
+
if (!existsSync27(s.path))
|
|
63155
63367
|
continue;
|
|
63156
63368
|
const key = `${s.harness}/${s.id}`;
|
|
63157
63369
|
const dir = dirs.resolve(s);
|
|
@@ -63188,7 +63400,7 @@ function createRowNamer() {
|
|
|
63188
63400
|
}
|
|
63189
63401
|
function defaultReadLog2() {
|
|
63190
63402
|
try {
|
|
63191
|
-
return
|
|
63403
|
+
return readFileSync26(logger.getLogPath(), "utf-8");
|
|
63192
63404
|
} catch {
|
|
63193
63405
|
return "";
|
|
63194
63406
|
}
|
|
@@ -63405,14 +63617,14 @@ var init_activity_view = __esm(() => {
|
|
|
63405
63617
|
});
|
|
63406
63618
|
|
|
63407
63619
|
// src/rules/installer.ts
|
|
63408
|
-
import { existsSync as
|
|
63409
|
-
import { homedir as
|
|
63410
|
-
import { dirname as dirname12, join as
|
|
63620
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync27, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
|
|
63621
|
+
import { homedir as homedir13 } from "node:os";
|
|
63622
|
+
import { dirname as dirname12, join as join42 } from "node:path";
|
|
63411
63623
|
function claudeConfigDir4() {
|
|
63412
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
63624
|
+
return process.env.CLAUDE_CONFIG_DIR || join42(homedir13(), ".claude");
|
|
63413
63625
|
}
|
|
63414
63626
|
function codexHome4() {
|
|
63415
|
-
return process.env.CODEX_HOME ||
|
|
63627
|
+
return process.env.CODEX_HOME || join42(homedir13(), ".codex");
|
|
63416
63628
|
}
|
|
63417
63629
|
function isRuleAgent(agent) {
|
|
63418
63630
|
return Object.hasOwn(RULE_TARGETS, agent);
|
|
@@ -63438,17 +63650,17 @@ async function fetchDosuRule(fetchImpl = globalThis.fetch) {
|
|
|
63438
63650
|
return normalizeRule(FALLBACK_DOSU_RULE);
|
|
63439
63651
|
}
|
|
63440
63652
|
function ensureParent(path) {
|
|
63441
|
-
|
|
63653
|
+
mkdirSync17(dirname12(path), { recursive: true });
|
|
63442
63654
|
}
|
|
63443
63655
|
function writeIfChanged(path, content) {
|
|
63444
|
-
if (!
|
|
63656
|
+
if (!existsSync28(path)) {
|
|
63445
63657
|
ensureParent(path);
|
|
63446
|
-
|
|
63658
|
+
writeFileSync18(path, content, "utf-8");
|
|
63447
63659
|
return "created";
|
|
63448
63660
|
}
|
|
63449
|
-
if (
|
|
63661
|
+
if (readFileSync27(path, "utf-8") === content)
|
|
63450
63662
|
return "unchanged";
|
|
63451
|
-
|
|
63663
|
+
writeFileSync18(path, content, "utf-8");
|
|
63452
63664
|
return "updated";
|
|
63453
63665
|
}
|
|
63454
63666
|
function findSection(content) {
|
|
@@ -63474,14 +63686,14 @@ function buildSection(content, lineEnding = `
|
|
|
63474
63686
|
return `${DOSU_RULE_SECTION_START}${lineEnding}${body}${lineEnding}${DOSU_RULE_SECTION_END}`;
|
|
63475
63687
|
}
|
|
63476
63688
|
function upsertSection(path, content) {
|
|
63477
|
-
if (!
|
|
63689
|
+
if (!existsSync28(path)) {
|
|
63478
63690
|
const section = buildSection(content);
|
|
63479
63691
|
ensureParent(path);
|
|
63480
|
-
|
|
63692
|
+
writeFileSync18(path, `${section}
|
|
63481
63693
|
`, "utf-8");
|
|
63482
63694
|
return "created";
|
|
63483
63695
|
}
|
|
63484
|
-
const existing =
|
|
63696
|
+
const existing = readFileSync27(path, "utf-8");
|
|
63485
63697
|
const lineEnding = lineEndingFor(existing);
|
|
63486
63698
|
const section = buildSection(content, lineEnding);
|
|
63487
63699
|
const location = findSection(existing);
|
|
@@ -63494,7 +63706,7 @@ function upsertSection(path, content) {
|
|
|
63494
63706
|
}
|
|
63495
63707
|
if (next === existing)
|
|
63496
63708
|
return "unchanged";
|
|
63497
|
-
|
|
63709
|
+
writeFileSync18(path, next, "utf-8");
|
|
63498
63710
|
return "updated";
|
|
63499
63711
|
}
|
|
63500
63712
|
function installRuleForAgent(agent, content) {
|
|
@@ -63511,13 +63723,13 @@ function removeRuleForAgent(agent) {
|
|
|
63511
63723
|
return null;
|
|
63512
63724
|
const target = RULE_TARGETS[agent];
|
|
63513
63725
|
const path = target.path();
|
|
63514
|
-
if (!
|
|
63726
|
+
if (!existsSync28(path))
|
|
63515
63727
|
return { agent, path, action: "not_found" };
|
|
63516
63728
|
if (target.kind === "file") {
|
|
63517
63729
|
unlinkSync5(path);
|
|
63518
63730
|
return { agent, path, action: "removed" };
|
|
63519
63731
|
}
|
|
63520
|
-
const existing =
|
|
63732
|
+
const existing = readFileSync27(path, "utf-8");
|
|
63521
63733
|
const lineEnding = lineEndingFor(existing);
|
|
63522
63734
|
const location = findSection(existing);
|
|
63523
63735
|
if (!location)
|
|
@@ -63526,7 +63738,7 @@ function removeRuleForAgent(agent) {
|
|
|
63526
63738
|
if (!next) {
|
|
63527
63739
|
unlinkSync5(path);
|
|
63528
63740
|
} else {
|
|
63529
|
-
|
|
63741
|
+
writeFileSync18(path, `${next}${lineEnding}`, "utf-8");
|
|
63530
63742
|
}
|
|
63531
63743
|
return { agent, path, action: "removed" };
|
|
63532
63744
|
}
|
|
@@ -63554,36 +63766,36 @@ var init_installer = __esm(() => {
|
|
|
63554
63766
|
RULE_TARGETS = {
|
|
63555
63767
|
claude: {
|
|
63556
63768
|
kind: "file",
|
|
63557
|
-
path: () =>
|
|
63769
|
+
path: () => join42(claudeConfigDir4(), "rules", "dosu.md")
|
|
63558
63770
|
},
|
|
63559
63771
|
cursor: {
|
|
63560
63772
|
kind: "file",
|
|
63561
|
-
path: () =>
|
|
63773
|
+
path: () => join42(homedir13(), ".cursor", "rules", "dosu.mdc"),
|
|
63562
63774
|
cursorFrontmatter: true
|
|
63563
63775
|
},
|
|
63564
63776
|
codex: {
|
|
63565
63777
|
kind: "section",
|
|
63566
|
-
path: () =>
|
|
63778
|
+
path: () => join42(codexHome4(), "AGENTS.md")
|
|
63567
63779
|
},
|
|
63568
63780
|
opencode: {
|
|
63569
63781
|
kind: "section",
|
|
63570
|
-
path: () =>
|
|
63782
|
+
path: () => join42(homedir13(), ".config", "opencode", "AGENTS.md")
|
|
63571
63783
|
},
|
|
63572
63784
|
gemini: {
|
|
63573
63785
|
kind: "section",
|
|
63574
|
-
path: () =>
|
|
63786
|
+
path: () => join42(homedir13(), ".gemini", "GEMINI.md")
|
|
63575
63787
|
},
|
|
63576
63788
|
antigravity: {
|
|
63577
63789
|
kind: "section",
|
|
63578
|
-
path: () =>
|
|
63790
|
+
path: () => join42(homedir13(), ".gemini", "GEMINI.md")
|
|
63579
63791
|
}
|
|
63580
63792
|
};
|
|
63581
63793
|
});
|
|
63582
63794
|
|
|
63583
63795
|
// src/setup/agents-md-step.ts
|
|
63584
63796
|
import { execSync as execSync2 } from "node:child_process";
|
|
63585
|
-
import { existsSync as
|
|
63586
|
-
import { join as
|
|
63797
|
+
import { existsSync as existsSync29, readFileSync as readFileSync28, writeFileSync as writeFileSync19 } from "node:fs";
|
|
63798
|
+
import { join as join43 } from "node:path";
|
|
63587
63799
|
function inGitWorkTree(cwd = process.cwd()) {
|
|
63588
63800
|
try {
|
|
63589
63801
|
const stdout = execSync2("git rev-parse --is-inside-work-tree", {
|
|
@@ -63597,10 +63809,10 @@ function inGitWorkTree(cwd = process.cwd()) {
|
|
|
63597
63809
|
}
|
|
63598
63810
|
function dosuAgentsSectionState(cwd = process.cwd()) {
|
|
63599
63811
|
try {
|
|
63600
|
-
const path =
|
|
63601
|
-
if (!
|
|
63812
|
+
const path = join43(cwd, "AGENTS.md");
|
|
63813
|
+
if (!existsSync29(path))
|
|
63602
63814
|
return "missing";
|
|
63603
|
-
const content =
|
|
63815
|
+
const content = readFileSync28(path, "utf-8");
|
|
63604
63816
|
const startMatch = content.match(SECTION_START_RE);
|
|
63605
63817
|
if (!startMatch || !content.includes(DOSU_SECTION_END))
|
|
63606
63818
|
return "missing";
|
|
@@ -63635,14 +63847,14 @@ function findSection2(content) {
|
|
|
63635
63847
|
return { start, end };
|
|
63636
63848
|
}
|
|
63637
63849
|
function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
|
|
63638
|
-
const path =
|
|
63639
|
-
if (!
|
|
63850
|
+
const path = join43(cwd, "AGENTS.md");
|
|
63851
|
+
if (!existsSync29(path)) {
|
|
63640
63852
|
const section = buildDosuAgentsSection(content);
|
|
63641
|
-
|
|
63853
|
+
writeFileSync19(path, `${section}
|
|
63642
63854
|
`);
|
|
63643
63855
|
return { path, action: "created" };
|
|
63644
63856
|
}
|
|
63645
|
-
const existing =
|
|
63857
|
+
const existing = readFileSync28(path, "utf-8");
|
|
63646
63858
|
const lineEnding = lineEndingFor2(existing);
|
|
63647
63859
|
const section = renderDosuAgentsSection(content, lineEnding);
|
|
63648
63860
|
const location = findSection2(existing);
|
|
@@ -63654,7 +63866,7 @@ function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RU
|
|
|
63654
63866
|
}
|
|
63655
63867
|
if (next === existing)
|
|
63656
63868
|
return { path, action: "unchanged" };
|
|
63657
|
-
|
|
63869
|
+
writeFileSync19(path, next);
|
|
63658
63870
|
return { path, action: "updated" };
|
|
63659
63871
|
}
|
|
63660
63872
|
async function stepUpdateAgentsMd(cwd = process.cwd(), content) {
|
|
@@ -65366,7 +65578,7 @@ var init_flow2 = __esm(() => {
|
|
|
65366
65578
|
// src/commands/upgrade.ts
|
|
65367
65579
|
import { spawnSync } from "node:child_process";
|
|
65368
65580
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
65369
|
-
import { homedir as
|
|
65581
|
+
import { homedir as homedir14 } from "node:os";
|
|
65370
65582
|
import { posix, win32 as win322 } from "node:path";
|
|
65371
65583
|
function isAbsoluteCommandProcessor(value) {
|
|
65372
65584
|
return Boolean(value && win322.isAbsolute(value) && win322.basename(value).toLowerCase() === "cmd.exe");
|
|
@@ -65420,7 +65632,7 @@ function packageRoots(manager, platform, comSpec, env, cwd) {
|
|
|
65420
65632
|
manager === "npm" ? path.join(lines[0], "@dosu", "cli") : path.join(lines[0], "node_modules", "@dosu", "cli")
|
|
65421
65633
|
];
|
|
65422
65634
|
}
|
|
65423
|
-
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd =
|
|
65635
|
+
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd = homedir14()) {
|
|
65424
65636
|
const path = platform === "win32" ? win322 : posix;
|
|
65425
65637
|
if (!entrypoint || !path.isAbsolute(entrypoint))
|
|
65426
65638
|
return null;
|
|
@@ -65473,7 +65685,7 @@ Or install Dosu globally with your package manager:`);
|
|
|
65473
65685
|
function runUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
65474
65686
|
const platform = options.platform ?? process.platform;
|
|
65475
65687
|
const env = options.env ?? process.env;
|
|
65476
|
-
const cwd = options.cwd ??
|
|
65688
|
+
const cwd = options.cwd ?? homedir14();
|
|
65477
65689
|
let manager = null;
|
|
65478
65690
|
if (channel === "npm") {
|
|
65479
65691
|
if (isNpxInvocation(channel, env)) {
|
|
@@ -65540,7 +65752,7 @@ function finishWithNewBinary(channel, options) {
|
|
|
65540
65752
|
return;
|
|
65541
65753
|
}
|
|
65542
65754
|
const result = spawnSync(invocation.command, invocation.args, {
|
|
65543
|
-
cwd: options.cwd ??
|
|
65755
|
+
cwd: options.cwd ?? homedir14(),
|
|
65544
65756
|
shell: false,
|
|
65545
65757
|
stdio: "inherit"
|
|
65546
65758
|
});
|
|
@@ -65590,9 +65802,37 @@ Refreshing agent MCP configs with the new version...`);
|
|
|
65590
65802
|
console.error(SETUP_FALLBACK);
|
|
65591
65803
|
return 0;
|
|
65592
65804
|
}
|
|
65805
|
+
function setAutoUpdate(value) {
|
|
65806
|
+
const normalized = value.trim().toLowerCase();
|
|
65807
|
+
if (normalized !== "on" && normalized !== "off") {
|
|
65808
|
+
console.error(`Invalid --auto value '${value}' (expected 'on' or 'off').`);
|
|
65809
|
+
return 2;
|
|
65810
|
+
}
|
|
65811
|
+
if (!setAutoUpdateEnabled(normalized === "on")) {
|
|
65812
|
+
console.error("Could not save the auto-update setting.");
|
|
65813
|
+
return 1;
|
|
65814
|
+
}
|
|
65815
|
+
if (normalized === "off") {
|
|
65816
|
+
console.log('Automatic updates are off. Run "dosu upgrade" to update by hand.');
|
|
65817
|
+
} else if (autoUpdateDisabledReason() === "env") {
|
|
65818
|
+
console.log(`Automatic updates are on, but ${AUTO_UPDATE_ENV} still disables them here.`);
|
|
65819
|
+
} else {
|
|
65820
|
+
console.log("Automatic updates are on.");
|
|
65821
|
+
}
|
|
65822
|
+
return 0;
|
|
65823
|
+
}
|
|
65593
65824
|
function upgradeCommand() {
|
|
65594
|
-
return new Command("upgrade").description("Update Dosu to the latest version, re-running setup when the update changes agent config").addOption(new Option("--finish <from>").hideHelp()).action(async (opts) => {
|
|
65595
|
-
|
|
65825
|
+
return new Command("upgrade").description("Update Dosu to the latest version, re-running setup when the update changes agent config").option("--auto <on|off>", "Turn automatic background updates on or off").addOption(new Option("--background").hideHelp()).addOption(new Option("--finish <from>").hideHelp()).action(async (opts) => {
|
|
65826
|
+
let status;
|
|
65827
|
+
if (opts.auto !== undefined) {
|
|
65828
|
+
status = setAutoUpdate(opts.auto);
|
|
65829
|
+
} else if (opts.background) {
|
|
65830
|
+
status = runBackgroundUpgrade(() => runUpgrade());
|
|
65831
|
+
} else if (opts.finish !== undefined) {
|
|
65832
|
+
status = await finishUpgrade(opts.finish);
|
|
65833
|
+
} else {
|
|
65834
|
+
status = await completeUpgrade();
|
|
65835
|
+
}
|
|
65596
65836
|
if (status !== 0)
|
|
65597
65837
|
process.exitCode = status;
|
|
65598
65838
|
});
|
|
@@ -65602,6 +65842,7 @@ var init_upgrade = __esm(() => {
|
|
|
65602
65842
|
init_commander();
|
|
65603
65843
|
init_config();
|
|
65604
65844
|
init_refresh();
|
|
65845
|
+
init_auto_update();
|
|
65605
65846
|
init_mcp_refresh_check();
|
|
65606
65847
|
init_skill_update_check();
|
|
65607
65848
|
import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
@@ -66309,7 +66550,7 @@ var init_pages_view = __esm(() => {
|
|
|
66309
66550
|
});
|
|
66310
66551
|
|
|
66311
66552
|
// src/tui/tui.ts
|
|
66312
|
-
import { homedir as
|
|
66553
|
+
import { homedir as homedir15 } from "node:os";
|
|
66313
66554
|
import { basename as basename6 } from "node:path";
|
|
66314
66555
|
async function probeSession(cfg) {
|
|
66315
66556
|
if (!isAuthenticated(cfg) || !isTokenExpired(cfg))
|
|
@@ -66574,7 +66815,7 @@ async function runSettings(cfg) {
|
|
|
66574
66815
|
}
|
|
66575
66816
|
}
|
|
66576
66817
|
function displayDir(dir) {
|
|
66577
|
-
const home =
|
|
66818
|
+
const home = homedir15();
|
|
66578
66819
|
return dir === home ? "~" : dir.startsWith(`${home}/`) ? `~${dir.slice(home.length)}` : dir;
|
|
66579
66820
|
}
|
|
66580
66821
|
function discoverProjectDirs() {
|
|
@@ -67284,7 +67525,7 @@ var init_flow3 = __esm(() => {
|
|
|
67284
67525
|
});
|
|
67285
67526
|
|
|
67286
67527
|
// src/cli/cli.ts
|
|
67287
|
-
import { readFileSync as
|
|
67528
|
+
import { readFileSync as readFileSync29, unlinkSync as unlinkSync6 } from "node:fs";
|
|
67288
67529
|
function shouldRunBackgroundChecks(actionName) {
|
|
67289
67530
|
return actionName !== "upgrade";
|
|
67290
67531
|
}
|
|
@@ -67730,7 +67971,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
67730
67971
|
}
|
|
67731
67972
|
if (opts.follow) {
|
|
67732
67973
|
try {
|
|
67733
|
-
const lines =
|
|
67974
|
+
const lines = readFileSync29(logPath, "utf-8").split(`
|
|
67734
67975
|
`);
|
|
67735
67976
|
if (lines.at(-1) === "")
|
|
67736
67977
|
lines.pop();
|
|
@@ -67746,7 +67987,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
67746
67987
|
if (opts.tail !== undefined) {
|
|
67747
67988
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
67748
67989
|
try {
|
|
67749
|
-
const content =
|
|
67990
|
+
const content = readFileSync29(logPath, "utf-8");
|
|
67750
67991
|
const lines = content.split(`
|
|
67751
67992
|
`);
|
|
67752
67993
|
console.log(lines.slice(-n).join(`
|
|
@@ -67872,4 +68113,4 @@ main().catch((err) => {
|
|
|
67872
68113
|
process.exit(1);
|
|
67873
68114
|
});
|
|
67874
68115
|
|
|
67875
|
-
//# debugId=
|
|
68116
|
+
//# debugId=41cac967-78f1-f75a-6475-6e2164756e21
|