@dosu/cli 0.60.2 → 0.62.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 +365 -120
- 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.62.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 = "da3b44a3-063b-fb2c-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
|
|
|
@@ -61719,6 +61719,7 @@ var ClaudeProvider = () => createJSONProvider({
|
|
|
61719
61719
|
paths: ["~/.claude"],
|
|
61720
61720
|
globalPath: "~/.claude.json",
|
|
61721
61721
|
topKey: "mcpServers",
|
|
61722
|
+
buildServer: ({ url, headers }) => ({ type: "http", url, headers, alwaysLoad: true }),
|
|
61722
61723
|
localConfigPath: (cwd) => join24(cwd, ".mcp.json")
|
|
61723
61724
|
});
|
|
61724
61725
|
var init_claude = __esm(() => {
|
|
@@ -62341,10 +62342,204 @@ var init_refresh = __esm(() => {
|
|
|
62341
62342
|
init_providers();
|
|
62342
62343
|
});
|
|
62343
62344
|
|
|
62344
|
-
// src/version/update
|
|
62345
|
-
import {
|
|
62345
|
+
// src/version/auto-update.ts
|
|
62346
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
62347
|
+
import {
|
|
62348
|
+
closeSync as closeSync6,
|
|
62349
|
+
existsSync as existsSync23,
|
|
62350
|
+
mkdirSync as mkdirSync13,
|
|
62351
|
+
openSync as openSync6,
|
|
62352
|
+
readFileSync as readFileSync22,
|
|
62353
|
+
rmSync as rmSync7,
|
|
62354
|
+
statSync as statSync8,
|
|
62355
|
+
writeFileSync as writeFileSync14,
|
|
62356
|
+
writeSync
|
|
62357
|
+
} from "node:fs";
|
|
62358
|
+
import { homedir as homedir11 } from "node:os";
|
|
62346
62359
|
import { join as join38 } from "node:path";
|
|
62360
|
+
function statePath() {
|
|
62361
|
+
return join38(getConfigDir(), STATE_FILENAME2);
|
|
62362
|
+
}
|
|
62363
|
+
function lockPath2() {
|
|
62364
|
+
return join38(getConfigDir(), LOCK_FILENAME2);
|
|
62365
|
+
}
|
|
62347
62366
|
function isValidVersion(value) {
|
|
62367
|
+
return typeof value === "string" && VERSION_PATTERN.test(value);
|
|
62368
|
+
}
|
|
62369
|
+
function readState() {
|
|
62370
|
+
try {
|
|
62371
|
+
const raw = JSON.parse(readFileSync22(statePath(), "utf-8"));
|
|
62372
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw))
|
|
62373
|
+
return {};
|
|
62374
|
+
const data = raw;
|
|
62375
|
+
const state = {};
|
|
62376
|
+
if (data.disabled === true)
|
|
62377
|
+
state.disabled = true;
|
|
62378
|
+
const last = data.lastAttempt;
|
|
62379
|
+
if (last && isValidVersion(last.version) && typeof last.ok === "boolean" && typeof last.finishedAt === "number") {
|
|
62380
|
+
state.lastAttempt = { version: last.version, ok: last.ok, finishedAt: last.finishedAt };
|
|
62381
|
+
}
|
|
62382
|
+
return state;
|
|
62383
|
+
} catch {
|
|
62384
|
+
return {};
|
|
62385
|
+
}
|
|
62386
|
+
}
|
|
62387
|
+
function writeState(state) {
|
|
62388
|
+
try {
|
|
62389
|
+
const dir = getConfigDir();
|
|
62390
|
+
if (!existsSync23(dir))
|
|
62391
|
+
mkdirSync13(dir, { recursive: true, mode: 448 });
|
|
62392
|
+
writeFileSync14(statePath(), `${JSON.stringify(state, null, 2)}
|
|
62393
|
+
`, { mode: 384 });
|
|
62394
|
+
return true;
|
|
62395
|
+
} catch {
|
|
62396
|
+
return false;
|
|
62397
|
+
}
|
|
62398
|
+
}
|
|
62399
|
+
function isEnabledFlag(value) {
|
|
62400
|
+
if (value === undefined)
|
|
62401
|
+
return false;
|
|
62402
|
+
const normalized = value.trim().toLowerCase();
|
|
62403
|
+
return normalized !== "" && !["0", "false", "no", "off"].includes(normalized);
|
|
62404
|
+
}
|
|
62405
|
+
function autoUpdateDisabledReason(env = process.env) {
|
|
62406
|
+
if (isEnabledFlag(env[AUTO_UPDATE_ENV]))
|
|
62407
|
+
return "env";
|
|
62408
|
+
if (readState().disabled)
|
|
62409
|
+
return "settings";
|
|
62410
|
+
return;
|
|
62411
|
+
}
|
|
62412
|
+
function setAutoUpdateEnabled(enabled) {
|
|
62413
|
+
const state = readState();
|
|
62414
|
+
if (enabled)
|
|
62415
|
+
delete state.disabled;
|
|
62416
|
+
else
|
|
62417
|
+
state.disabled = true;
|
|
62418
|
+
return writeState(state);
|
|
62419
|
+
}
|
|
62420
|
+
function canAutoUpdate(channel, env) {
|
|
62421
|
+
if (env.NODE_ENV === "test" || env.CI || env.DOSU_DEV === "true")
|
|
62422
|
+
return false;
|
|
62423
|
+
if (!SUPPORTED_CHANNELS.has(channel) || isNpxInvocation(channel, env))
|
|
62424
|
+
return false;
|
|
62425
|
+
return autoUpdateDisabledReason(env) === undefined;
|
|
62426
|
+
}
|
|
62427
|
+
function backgroundInvocation(channel, entrypoint = process.argv[1], execPath = process.execPath) {
|
|
62428
|
+
const args = ["upgrade", "--background"];
|
|
62429
|
+
if (channel === "npm") {
|
|
62430
|
+
return entrypoint ? { command: execPath, args: [entrypoint, ...args] } : null;
|
|
62431
|
+
}
|
|
62432
|
+
if (channel === "homebrew")
|
|
62433
|
+
return { command: execPath, args };
|
|
62434
|
+
return null;
|
|
62435
|
+
}
|
|
62436
|
+
function lockIsFresh(now) {
|
|
62437
|
+
try {
|
|
62438
|
+
return now - statSync8(lockPath2()).mtimeMs < LOCK_STALE_MS;
|
|
62439
|
+
} catch {
|
|
62440
|
+
return false;
|
|
62441
|
+
}
|
|
62442
|
+
}
|
|
62443
|
+
function claimLock(version, now) {
|
|
62444
|
+
try {
|
|
62445
|
+
mkdirSync13(getConfigDir(), { recursive: true, mode: 448 });
|
|
62446
|
+
if (!lockIsFresh(now))
|
|
62447
|
+
rmSync7(lockPath2(), { force: true });
|
|
62448
|
+
const fd = openSync6(lockPath2(), "wx", 384);
|
|
62449
|
+
try {
|
|
62450
|
+
writeSync(fd, version);
|
|
62451
|
+
} finally {
|
|
62452
|
+
closeSync6(fd);
|
|
62453
|
+
}
|
|
62454
|
+
return "claimed";
|
|
62455
|
+
} catch (err) {
|
|
62456
|
+
return err.code === "EEXIST" ? "held" : "failed";
|
|
62457
|
+
}
|
|
62458
|
+
}
|
|
62459
|
+
function releaseLock() {
|
|
62460
|
+
try {
|
|
62461
|
+
rmSync7(lockPath2(), { force: true });
|
|
62462
|
+
} catch {}
|
|
62463
|
+
}
|
|
62464
|
+
function readLockVersion() {
|
|
62465
|
+
try {
|
|
62466
|
+
const version = readFileSync22(lockPath2(), "utf-8").trim();
|
|
62467
|
+
return isValidVersion(version) ? version : undefined;
|
|
62468
|
+
} catch {
|
|
62469
|
+
return;
|
|
62470
|
+
}
|
|
62471
|
+
}
|
|
62472
|
+
function startAutoUpdate(version, options = {}) {
|
|
62473
|
+
const channel = options.channel ?? INSTALL_CHANNEL;
|
|
62474
|
+
const env = options.env ?? process.env;
|
|
62475
|
+
const now = options.now ?? Date.now();
|
|
62476
|
+
try {
|
|
62477
|
+
if (!isValidVersion(version) || !canAutoUpdate(channel, env))
|
|
62478
|
+
return "unavailable";
|
|
62479
|
+
if (lockIsFresh(now))
|
|
62480
|
+
return "in_progress";
|
|
62481
|
+
const last = readState().lastAttempt;
|
|
62482
|
+
if (last?.version === version && now - last.finishedAt < RETRY_INTERVAL_MS) {
|
|
62483
|
+
return "unavailable";
|
|
62484
|
+
}
|
|
62485
|
+
const invocation = backgroundInvocation(channel, options.entrypoint, options.execPath);
|
|
62486
|
+
if (!invocation)
|
|
62487
|
+
return "unavailable";
|
|
62488
|
+
const claim = claimLock(version, now);
|
|
62489
|
+
if (claim !== "claimed")
|
|
62490
|
+
return claim === "held" ? "in_progress" : "unavailable";
|
|
62491
|
+
try {
|
|
62492
|
+
const child = spawn3(invocation.command, invocation.args, {
|
|
62493
|
+
cwd: homedir11(),
|
|
62494
|
+
detached: true,
|
|
62495
|
+
stdio: "ignore",
|
|
62496
|
+
windowsHide: true,
|
|
62497
|
+
env: { ...env, DOSU_TELEMETRY_DISABLED: "1" }
|
|
62498
|
+
});
|
|
62499
|
+
child.on("error", releaseLock);
|
|
62500
|
+
child.unref();
|
|
62501
|
+
} catch (err) {
|
|
62502
|
+
releaseLock();
|
|
62503
|
+
throw err;
|
|
62504
|
+
}
|
|
62505
|
+
logger.info("auto-update", `Started background update to ${version}`);
|
|
62506
|
+
return "started";
|
|
62507
|
+
} catch (err) {
|
|
62508
|
+
logger.error("auto-update", `Could not start background update: ${err}`);
|
|
62509
|
+
return "unavailable";
|
|
62510
|
+
}
|
|
62511
|
+
}
|
|
62512
|
+
function runBackgroundUpgrade(upgrade, now = Date.now) {
|
|
62513
|
+
const version = readLockVersion();
|
|
62514
|
+
let status = 1;
|
|
62515
|
+
try {
|
|
62516
|
+
status = upgrade();
|
|
62517
|
+
} catch (err) {
|
|
62518
|
+
logger.error("auto-update", `Background update threw: ${err}`);
|
|
62519
|
+
}
|
|
62520
|
+
if (version) {
|
|
62521
|
+
const state = readState();
|
|
62522
|
+
state.lastAttempt = { version, ok: status === 0, finishedAt: now() };
|
|
62523
|
+
writeState(state);
|
|
62524
|
+
}
|
|
62525
|
+
logger.info("auto-update", `Background update ${status === 0 ? "finished" : "failed"}`);
|
|
62526
|
+
releaseLock();
|
|
62527
|
+
return status;
|
|
62528
|
+
}
|
|
62529
|
+
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";
|
|
62530
|
+
var init_auto_update = __esm(() => {
|
|
62531
|
+
init_config();
|
|
62532
|
+
init_logger();
|
|
62533
|
+
LOCK_STALE_MS = 15 * 60 * 1000;
|
|
62534
|
+
RETRY_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
62535
|
+
SUPPORTED_CHANNELS = new Set(["npm", "homebrew"]);
|
|
62536
|
+
VERSION_PATTERN = /^[0-9A-Za-z.+-]{1,64}$/;
|
|
62537
|
+
});
|
|
62538
|
+
|
|
62539
|
+
// src/version/update-check.ts
|
|
62540
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync14, readFileSync as readFileSync23, writeFileSync as writeFileSync15 } from "node:fs";
|
|
62541
|
+
import { join as join39 } from "node:path";
|
|
62542
|
+
function isValidVersion2(value) {
|
|
62348
62543
|
return typeof value === "string" && SEMVER_PATTERN.test(value);
|
|
62349
62544
|
}
|
|
62350
62545
|
function stripPrerelease(version) {
|
|
@@ -62365,15 +62560,15 @@ function isNewerVersion(latest, current) {
|
|
|
62365
62560
|
return false;
|
|
62366
62561
|
}
|
|
62367
62562
|
function getCachePath2() {
|
|
62368
|
-
return
|
|
62563
|
+
return join39(getConfigDir(), CACHE_FILENAME3);
|
|
62369
62564
|
}
|
|
62370
62565
|
function readCache() {
|
|
62371
62566
|
try {
|
|
62372
62567
|
const path = getCachePath2();
|
|
62373
|
-
if (!
|
|
62568
|
+
if (!existsSync24(path))
|
|
62374
62569
|
return null;
|
|
62375
|
-
const data = JSON.parse(
|
|
62376
|
-
if (typeof data.lastCheck === "number" &&
|
|
62570
|
+
const data = JSON.parse(readFileSync23(path, "utf-8"));
|
|
62571
|
+
if (typeof data.lastCheck === "number" && isValidVersion2(data.latestVersion)) {
|
|
62377
62572
|
return data;
|
|
62378
62573
|
}
|
|
62379
62574
|
return null;
|
|
@@ -62384,10 +62579,10 @@ function readCache() {
|
|
|
62384
62579
|
function writeCache(cache) {
|
|
62385
62580
|
try {
|
|
62386
62581
|
const dir = getConfigDir();
|
|
62387
|
-
if (!
|
|
62388
|
-
|
|
62582
|
+
if (!existsSync24(dir)) {
|
|
62583
|
+
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
62389
62584
|
}
|
|
62390
|
-
|
|
62585
|
+
writeFileSync15(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
62391
62586
|
} catch {}
|
|
62392
62587
|
}
|
|
62393
62588
|
async function fetchLatestVersion() {
|
|
@@ -62399,7 +62594,7 @@ async function fetchLatestVersion() {
|
|
|
62399
62594
|
return null;
|
|
62400
62595
|
const data = await resp.json();
|
|
62401
62596
|
const latest = data.latest;
|
|
62402
|
-
return
|
|
62597
|
+
return isValidVersion2(latest) ? latest : null;
|
|
62403
62598
|
} catch {
|
|
62404
62599
|
return null;
|
|
62405
62600
|
} finally {
|
|
@@ -62419,30 +62614,43 @@ function styleHint(hint) {
|
|
|
62419
62614
|
const [, before, command, after] = match;
|
|
62420
62615
|
return [before && import_picocolors30.default.dim(before), import_picocolors30.default.cyan(command), after && import_picocolors30.default.dim(after)].filter(Boolean).join("");
|
|
62421
62616
|
}
|
|
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 `
|
|
62617
|
+
function framedNotice(content, width) {
|
|
62618
|
+
const innerWidth = Math.max(...content.map(visibleWidth2)) + BOX_PADDING * 2;
|
|
62619
|
+
const framed = (line) => {
|
|
62620
|
+
const pad = innerWidth - visibleWidth2(line);
|
|
62621
|
+
const left = Math.floor(pad / 2);
|
|
62622
|
+
return `${import_picocolors30.default.yellow("│")}${" ".repeat(left)}${line}${" ".repeat(pad - left)}${import_picocolors30.default.yellow("│")}`;
|
|
62623
|
+
};
|
|
62624
|
+
const box = [
|
|
62625
|
+
import_picocolors30.default.yellow(`╭${"─".repeat(innerWidth)}╮`),
|
|
62626
|
+
framed(""),
|
|
62627
|
+
...content.map(framed),
|
|
62628
|
+
framed(""),
|
|
62629
|
+
import_picocolors30.default.yellow(`╰${"─".repeat(innerWidth)}╯`)
|
|
62630
|
+
];
|
|
62631
|
+
return `
|
|
62443
62632
|
${centerBlock(box, width).join(`
|
|
62444
62633
|
`)}
|
|
62445
62634
|
`;
|
|
62635
|
+
}
|
|
62636
|
+
function versionArrow(current, latest) {
|
|
62637
|
+
return `${import_picocolors30.default.dim(current)} ${import_picocolors30.default.dim("→")} ${import_picocolors30.default.bold(brand(latest))}`;
|
|
62638
|
+
}
|
|
62639
|
+
function buildAutoUpdateNotice(current, latest, interactive, width = process.stderr.columns ?? 80) {
|
|
62640
|
+
if (interactive) {
|
|
62641
|
+
return framedNotice([
|
|
62642
|
+
`Updating Dosu: ${versionArrow(current, latest)}`,
|
|
62643
|
+
import_picocolors30.default.dim("Installing in the background; your next command uses it")
|
|
62644
|
+
], width);
|
|
62645
|
+
}
|
|
62646
|
+
return `
|
|
62647
|
+
[dosu:update] Installing Dosu ${latest} in the background (running ${current}). ` + `The next Dosu command uses it; no action needed.
|
|
62648
|
+
`;
|
|
62649
|
+
}
|
|
62650
|
+
function buildUpdateNotice(current, latest, channel, interactive, npx = false, width = process.stderr.columns ?? 80) {
|
|
62651
|
+
const hint = buildUpdateHint(channel, npx);
|
|
62652
|
+
if (interactive) {
|
|
62653
|
+
return framedNotice([`Update available: ${versionArrow(current, latest)}`, styleHint(hint)], width);
|
|
62446
62654
|
}
|
|
62447
62655
|
const agentAction = hint[0].toLowerCase() + hint.slice(1);
|
|
62448
62656
|
const verifyCommand = npx ? "npx -y @dosu/cli@latest --version" : "dosu --version";
|
|
@@ -62455,8 +62663,12 @@ function getAvailableUpdate() {
|
|
|
62455
62663
|
const cache = readCache();
|
|
62456
62664
|
return cache && isNewerVersion(cache.latestVersion, VERSION) ? cache.latestVersion : null;
|
|
62457
62665
|
}
|
|
62458
|
-
function
|
|
62459
|
-
|
|
62666
|
+
function handleNewerVersion(latest, notify) {
|
|
62667
|
+
const autoUpdate = startAutoUpdate(latest);
|
|
62668
|
+
if (!notify)
|
|
62669
|
+
return;
|
|
62670
|
+
const interactive = process.stderr.isTTY === true;
|
|
62671
|
+
console.error(autoUpdate === "unavailable" ? buildUpdateNotice(VERSION, latest, INSTALL_CHANNEL, interactive, isNpxInvocation()) : buildAutoUpdateNotice(VERSION, latest, interactive));
|
|
62460
62672
|
}
|
|
62461
62673
|
async function checkForUpdates(options = {}) {
|
|
62462
62674
|
const notify = options.notify ?? true;
|
|
@@ -62464,8 +62676,8 @@ async function checkForUpdates(options = {}) {
|
|
|
62464
62676
|
const cache = readCache();
|
|
62465
62677
|
const isStale = !cache || Date.now() - cache.lastCheck > CHECK_INTERVAL_MS2;
|
|
62466
62678
|
if (!isStale) {
|
|
62467
|
-
if (
|
|
62468
|
-
|
|
62679
|
+
if (isNewerVersion(cache.latestVersion, VERSION)) {
|
|
62680
|
+
handleNewerVersion(cache.latestVersion, notify);
|
|
62469
62681
|
}
|
|
62470
62682
|
return;
|
|
62471
62683
|
}
|
|
@@ -62478,8 +62690,8 @@ async function checkForUpdates(options = {}) {
|
|
|
62478
62690
|
if (latest) {
|
|
62479
62691
|
logger.debug("update-check", `Cached latest version: ${latest}`);
|
|
62480
62692
|
}
|
|
62481
|
-
if (
|
|
62482
|
-
|
|
62693
|
+
if (isNewerVersion(latestKnownVersion, VERSION)) {
|
|
62694
|
+
handleNewerVersion(latestKnownVersion, notify);
|
|
62483
62695
|
}
|
|
62484
62696
|
} catch (err) {
|
|
62485
62697
|
logger.error("update-check", `Update check failed: ${err}`);
|
|
@@ -62491,14 +62703,15 @@ var init_update_check = __esm(() => {
|
|
|
62491
62703
|
init_logger();
|
|
62492
62704
|
init_styles();
|
|
62493
62705
|
init_layout();
|
|
62706
|
+
init_auto_update();
|
|
62494
62707
|
import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
62495
62708
|
CHECK_INTERVAL_MS2 = 6 * 60 * 60 * 1000;
|
|
62496
62709
|
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
62710
|
});
|
|
62498
62711
|
|
|
62499
62712
|
// src/version/mcp-refresh-check.ts
|
|
62500
|
-
import { existsSync as
|
|
62501
|
-
import { join as
|
|
62713
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
|
|
62714
|
+
import { join as join40 } from "node:path";
|
|
62502
62715
|
function needsMcpRefresh(previous, current) {
|
|
62503
62716
|
if (previous === null)
|
|
62504
62717
|
return true;
|
|
@@ -62508,14 +62721,14 @@ function needsMcpRefresh(previous, current) {
|
|
|
62508
62721
|
return MCP_FORMAT_CHANGES.some((change) => isNewerVersion(change, older) && !isNewerVersion(change, newer));
|
|
62509
62722
|
}
|
|
62510
62723
|
function getCachePath3() {
|
|
62511
|
-
return
|
|
62724
|
+
return join40(getConfigDir(), CACHE_FILENAME4);
|
|
62512
62725
|
}
|
|
62513
62726
|
function readMcpRefreshCache() {
|
|
62514
62727
|
try {
|
|
62515
62728
|
const path = getCachePath3();
|
|
62516
|
-
if (!
|
|
62729
|
+
if (!existsSync25(path))
|
|
62517
62730
|
return null;
|
|
62518
|
-
const data = JSON.parse(
|
|
62731
|
+
const data = JSON.parse(readFileSync24(path, "utf-8"));
|
|
62519
62732
|
if (typeof data?.version === "string")
|
|
62520
62733
|
return { version: data.version };
|
|
62521
62734
|
return null;
|
|
@@ -62526,10 +62739,10 @@ function readMcpRefreshCache() {
|
|
|
62526
62739
|
function writeMcpRefreshCache(cache) {
|
|
62527
62740
|
try {
|
|
62528
62741
|
const dir = getConfigDir();
|
|
62529
|
-
if (!
|
|
62530
|
-
|
|
62742
|
+
if (!existsSync25(dir)) {
|
|
62743
|
+
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
62531
62744
|
}
|
|
62532
|
-
|
|
62745
|
+
writeFileSync16(getCachePath3(), JSON.stringify(cache), { mode: 384 });
|
|
62533
62746
|
} catch {}
|
|
62534
62747
|
}
|
|
62535
62748
|
function canRefreshMcp(cfg) {
|
|
@@ -62538,7 +62751,7 @@ function canRefreshMcp(cfg) {
|
|
|
62538
62751
|
return false;
|
|
62539
62752
|
return cfg.mode === MODE_OSS || Boolean(target.deployment_id);
|
|
62540
62753
|
}
|
|
62541
|
-
function
|
|
62754
|
+
function displayNotice(names) {
|
|
62542
62755
|
console.error(`
|
|
62543
62756
|
${import_picocolors31.default.green(`✓ Dosu ${VERSION}: refreshed MCP config for ${names.join(", ")}`)}
|
|
62544
62757
|
` + `${import_picocolors31.default.dim(` Run ${import_picocolors31.default.cyan('"dosu setup"')} to also update hooks and rules, then restart your AI agents.`)}
|
|
@@ -62563,7 +62776,7 @@ function checkForMcpRefresh(options = {}) {
|
|
|
62563
62776
|
writeMcpRefreshCache({ version: VERSION });
|
|
62564
62777
|
logger.info("mcp-refresh", `Version ${VERSION}: refreshed ${result.updated.length}, failed ${result.failed.length}`);
|
|
62565
62778
|
if (notify && result.updated.length > 0) {
|
|
62566
|
-
|
|
62779
|
+
displayNotice(result.updated.map((provider) => provider.name()));
|
|
62567
62780
|
}
|
|
62568
62781
|
} catch (err) {
|
|
62569
62782
|
logger.error("mcp-refresh", `MCP refresh check failed: ${err}`);
|
|
@@ -62576,11 +62789,14 @@ var init_mcp_refresh_check = __esm(() => {
|
|
|
62576
62789
|
init_refresh();
|
|
62577
62790
|
init_update_check();
|
|
62578
62791
|
import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
62579
|
-
MCP_FORMAT_CHANGES = [
|
|
62792
|
+
MCP_FORMAT_CHANGES = [
|
|
62793
|
+
"0.53.0",
|
|
62794
|
+
"0.62.0"
|
|
62795
|
+
];
|
|
62580
62796
|
});
|
|
62581
62797
|
|
|
62582
62798
|
// src/version/skill-update-check.ts
|
|
62583
|
-
function
|
|
62799
|
+
function displayNotice2() {
|
|
62584
62800
|
console.error(`
|
|
62585
62801
|
${import_picocolors32.default.green(`✓ Dosu ${VERSION}: refreshed the bundled agent skills`)}
|
|
62586
62802
|
` + `${import_picocolors32.default.dim(" Restart your AI agents to pick up the new skill content.")}
|
|
@@ -62599,7 +62815,7 @@ function checkForSkillUpdates(options = {}) {
|
|
|
62599
62815
|
}
|
|
62600
62816
|
logger.info("skill-update-check", `Refreshed skills from ${state.version} to ${VERSION}`);
|
|
62601
62817
|
if (notify && result.version)
|
|
62602
|
-
|
|
62818
|
+
displayNotice2();
|
|
62603
62819
|
} catch (err) {
|
|
62604
62820
|
logger.error("skill-update-check", `Skill update check failed: ${err}`);
|
|
62605
62821
|
}
|
|
@@ -62639,11 +62855,11 @@ var init_errors3 = __esm(() => {
|
|
|
62639
62855
|
var MCP_PROVIDER_SLUG2 = "dosu_mcp";
|
|
62640
62856
|
|
|
62641
62857
|
// src/debug/follow.ts
|
|
62642
|
-
import { closeSync as
|
|
62858
|
+
import { closeSync as closeSync7, openSync as openSync7, readSync as readSync5, statSync as statSync9 } from "node:fs";
|
|
62643
62859
|
function createLogFollower(path, emit) {
|
|
62644
62860
|
const sizeOf = () => {
|
|
62645
62861
|
try {
|
|
62646
|
-
return
|
|
62862
|
+
return statSync9(path).size;
|
|
62647
62863
|
} catch {
|
|
62648
62864
|
return 0;
|
|
62649
62865
|
}
|
|
@@ -62657,7 +62873,7 @@ function createLogFollower(path, emit) {
|
|
|
62657
62873
|
if (size === offset)
|
|
62658
62874
|
return;
|
|
62659
62875
|
try {
|
|
62660
|
-
const fd =
|
|
62876
|
+
const fd = openSync7(path, "r");
|
|
62661
62877
|
try {
|
|
62662
62878
|
const buf = Buffer.alloc(size - offset);
|
|
62663
62879
|
const read = readSync5(fd, buf, 0, buf.length, offset);
|
|
@@ -62665,7 +62881,7 @@ function createLogFollower(path, emit) {
|
|
|
62665
62881
|
if (read > 0)
|
|
62666
62882
|
emit(buf.toString("utf-8", 0, read));
|
|
62667
62883
|
} finally {
|
|
62668
|
-
|
|
62884
|
+
closeSync7(fd);
|
|
62669
62885
|
}
|
|
62670
62886
|
} catch {}
|
|
62671
62887
|
}
|
|
@@ -62674,15 +62890,15 @@ function createLogFollower(path, emit) {
|
|
|
62674
62890
|
var init_follow = () => {};
|
|
62675
62891
|
|
|
62676
62892
|
// src/sessions/session-title.ts
|
|
62677
|
-
import { existsSync as
|
|
62678
|
-
import { homedir as
|
|
62679
|
-
import { join as
|
|
62893
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync25, renameSync as renameSync6, statSync as statSync10, writeFileSync as writeFileSync17 } from "node:fs";
|
|
62894
|
+
import { homedir as homedir12 } from "node:os";
|
|
62895
|
+
import { join as join41 } from "node:path";
|
|
62680
62896
|
function cachePath2(configDir) {
|
|
62681
|
-
return
|
|
62897
|
+
return join41(configDir, CACHE_FILENAME5);
|
|
62682
62898
|
}
|
|
62683
62899
|
function loadCacheFile2(configDir) {
|
|
62684
62900
|
try {
|
|
62685
|
-
const raw = JSON.parse(
|
|
62901
|
+
const raw = JSON.parse(readFileSync25(cachePath2(configDir), "utf-8"));
|
|
62686
62902
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION2 || typeof raw.entries !== "object")
|
|
62687
62903
|
return {};
|
|
62688
62904
|
return raw.entries;
|
|
@@ -62692,12 +62908,12 @@ function loadCacheFile2(configDir) {
|
|
|
62692
62908
|
}
|
|
62693
62909
|
function saveCacheFile2(configDir, entries) {
|
|
62694
62910
|
try {
|
|
62695
|
-
if (!
|
|
62696
|
-
|
|
62911
|
+
if (!existsSync26(configDir))
|
|
62912
|
+
mkdirSync16(configDir, { recursive: true, mode: 448 });
|
|
62697
62913
|
const path = cachePath2(configDir);
|
|
62698
62914
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
62699
62915
|
const file = { schema_version: CACHE_SCHEMA_VERSION2, entries };
|
|
62700
|
-
|
|
62916
|
+
writeFileSync17(tmp, JSON.stringify(file), { mode: 384 });
|
|
62701
62917
|
renameSync6(tmp, path);
|
|
62702
62918
|
} catch {}
|
|
62703
62919
|
}
|
|
@@ -62730,15 +62946,15 @@ function claudeSummaryFromHead(text) {
|
|
|
62730
62946
|
}
|
|
62731
62947
|
return null;
|
|
62732
62948
|
}
|
|
62733
|
-
function reconstructSession(harness, id, slug, home =
|
|
62949
|
+
function reconstructSession(harness, id, slug, home = homedir12(), exists = existsSync26) {
|
|
62734
62950
|
if (!slug)
|
|
62735
62951
|
return null;
|
|
62736
62952
|
const candidates = [];
|
|
62737
62953
|
if (harness === "claude") {
|
|
62738
|
-
candidates.push(
|
|
62954
|
+
candidates.push(join41(home, ".claude", "projects", slug, `${id}.jsonl`));
|
|
62739
62955
|
} else if (harness === "cursor") {
|
|
62740
|
-
const project =
|
|
62741
|
-
candidates.push(
|
|
62956
|
+
const project = join41(home, ".cursor", "projects", slug);
|
|
62957
|
+
candidates.push(join41(project, "agent-transcripts", id, `${id}.jsonl`), join41(project, "agent-transcripts", `${id}.jsonl`));
|
|
62742
62958
|
} else {
|
|
62743
62959
|
return null;
|
|
62744
62960
|
}
|
|
@@ -62750,14 +62966,14 @@ function reconstructSession(harness, id, slug, home = homedir11(), exists = exis
|
|
|
62750
62966
|
}
|
|
62751
62967
|
function readHead2(path) {
|
|
62752
62968
|
try {
|
|
62753
|
-
return
|
|
62969
|
+
return readFileSync25(path, "utf-8").slice(0, 128 * 1024);
|
|
62754
62970
|
} catch {
|
|
62755
62971
|
return null;
|
|
62756
62972
|
}
|
|
62757
62973
|
}
|
|
62758
62974
|
function fileMtime2(path) {
|
|
62759
62975
|
try {
|
|
62760
|
-
return
|
|
62976
|
+
return statSync10(path).mtime.toISOString();
|
|
62761
62977
|
} catch {
|
|
62762
62978
|
return "";
|
|
62763
62979
|
}
|
|
@@ -62830,7 +63046,7 @@ var init_alt_screen = __esm(() => {
|
|
|
62830
63046
|
});
|
|
62831
63047
|
|
|
62832
63048
|
// src/tui/activity-view.ts
|
|
62833
|
-
import { existsSync as
|
|
63049
|
+
import { existsSync as existsSync27, readFileSync as readFileSync26 } from "node:fs";
|
|
62834
63050
|
import { basename as basename5 } from "node:path";
|
|
62835
63051
|
function reduceActivityViewKey(key) {
|
|
62836
63052
|
if (key === "q" || key === ESC7 || key === CTRL_C4)
|
|
@@ -63151,7 +63367,7 @@ function createRowNamer() {
|
|
|
63151
63367
|
names.titles[key] = t;
|
|
63152
63368
|
};
|
|
63153
63369
|
for (const s of [...backlog.queued, ...backlog.open]) {
|
|
63154
|
-
if (!
|
|
63370
|
+
if (!existsSync27(s.path))
|
|
63155
63371
|
continue;
|
|
63156
63372
|
const key = `${s.harness}/${s.id}`;
|
|
63157
63373
|
const dir = dirs.resolve(s);
|
|
@@ -63188,7 +63404,7 @@ function createRowNamer() {
|
|
|
63188
63404
|
}
|
|
63189
63405
|
function defaultReadLog2() {
|
|
63190
63406
|
try {
|
|
63191
|
-
return
|
|
63407
|
+
return readFileSync26(logger.getLogPath(), "utf-8");
|
|
63192
63408
|
} catch {
|
|
63193
63409
|
return "";
|
|
63194
63410
|
}
|
|
@@ -63405,14 +63621,14 @@ var init_activity_view = __esm(() => {
|
|
|
63405
63621
|
});
|
|
63406
63622
|
|
|
63407
63623
|
// src/rules/installer.ts
|
|
63408
|
-
import { existsSync as
|
|
63409
|
-
import { homedir as
|
|
63410
|
-
import { dirname as dirname12, join as
|
|
63624
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync27, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
|
|
63625
|
+
import { homedir as homedir13 } from "node:os";
|
|
63626
|
+
import { dirname as dirname12, join as join42 } from "node:path";
|
|
63411
63627
|
function claudeConfigDir4() {
|
|
63412
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
63628
|
+
return process.env.CLAUDE_CONFIG_DIR || join42(homedir13(), ".claude");
|
|
63413
63629
|
}
|
|
63414
63630
|
function codexHome4() {
|
|
63415
|
-
return process.env.CODEX_HOME ||
|
|
63631
|
+
return process.env.CODEX_HOME || join42(homedir13(), ".codex");
|
|
63416
63632
|
}
|
|
63417
63633
|
function isRuleAgent(agent) {
|
|
63418
63634
|
return Object.hasOwn(RULE_TARGETS, agent);
|
|
@@ -63438,17 +63654,17 @@ async function fetchDosuRule(fetchImpl = globalThis.fetch) {
|
|
|
63438
63654
|
return normalizeRule(FALLBACK_DOSU_RULE);
|
|
63439
63655
|
}
|
|
63440
63656
|
function ensureParent(path) {
|
|
63441
|
-
|
|
63657
|
+
mkdirSync17(dirname12(path), { recursive: true });
|
|
63442
63658
|
}
|
|
63443
63659
|
function writeIfChanged(path, content) {
|
|
63444
|
-
if (!
|
|
63660
|
+
if (!existsSync28(path)) {
|
|
63445
63661
|
ensureParent(path);
|
|
63446
|
-
|
|
63662
|
+
writeFileSync18(path, content, "utf-8");
|
|
63447
63663
|
return "created";
|
|
63448
63664
|
}
|
|
63449
|
-
if (
|
|
63665
|
+
if (readFileSync27(path, "utf-8") === content)
|
|
63450
63666
|
return "unchanged";
|
|
63451
|
-
|
|
63667
|
+
writeFileSync18(path, content, "utf-8");
|
|
63452
63668
|
return "updated";
|
|
63453
63669
|
}
|
|
63454
63670
|
function findSection(content) {
|
|
@@ -63474,14 +63690,14 @@ function buildSection(content, lineEnding = `
|
|
|
63474
63690
|
return `${DOSU_RULE_SECTION_START}${lineEnding}${body}${lineEnding}${DOSU_RULE_SECTION_END}`;
|
|
63475
63691
|
}
|
|
63476
63692
|
function upsertSection(path, content) {
|
|
63477
|
-
if (!
|
|
63693
|
+
if (!existsSync28(path)) {
|
|
63478
63694
|
const section = buildSection(content);
|
|
63479
63695
|
ensureParent(path);
|
|
63480
|
-
|
|
63696
|
+
writeFileSync18(path, `${section}
|
|
63481
63697
|
`, "utf-8");
|
|
63482
63698
|
return "created";
|
|
63483
63699
|
}
|
|
63484
|
-
const existing =
|
|
63700
|
+
const existing = readFileSync27(path, "utf-8");
|
|
63485
63701
|
const lineEnding = lineEndingFor(existing);
|
|
63486
63702
|
const section = buildSection(content, lineEnding);
|
|
63487
63703
|
const location = findSection(existing);
|
|
@@ -63494,7 +63710,7 @@ function upsertSection(path, content) {
|
|
|
63494
63710
|
}
|
|
63495
63711
|
if (next === existing)
|
|
63496
63712
|
return "unchanged";
|
|
63497
|
-
|
|
63713
|
+
writeFileSync18(path, next, "utf-8");
|
|
63498
63714
|
return "updated";
|
|
63499
63715
|
}
|
|
63500
63716
|
function installRuleForAgent(agent, content) {
|
|
@@ -63511,13 +63727,13 @@ function removeRuleForAgent(agent) {
|
|
|
63511
63727
|
return null;
|
|
63512
63728
|
const target = RULE_TARGETS[agent];
|
|
63513
63729
|
const path = target.path();
|
|
63514
|
-
if (!
|
|
63730
|
+
if (!existsSync28(path))
|
|
63515
63731
|
return { agent, path, action: "not_found" };
|
|
63516
63732
|
if (target.kind === "file") {
|
|
63517
63733
|
unlinkSync5(path);
|
|
63518
63734
|
return { agent, path, action: "removed" };
|
|
63519
63735
|
}
|
|
63520
|
-
const existing =
|
|
63736
|
+
const existing = readFileSync27(path, "utf-8");
|
|
63521
63737
|
const lineEnding = lineEndingFor(existing);
|
|
63522
63738
|
const location = findSection(existing);
|
|
63523
63739
|
if (!location)
|
|
@@ -63526,7 +63742,7 @@ function removeRuleForAgent(agent) {
|
|
|
63526
63742
|
if (!next) {
|
|
63527
63743
|
unlinkSync5(path);
|
|
63528
63744
|
} else {
|
|
63529
|
-
|
|
63745
|
+
writeFileSync18(path, `${next}${lineEnding}`, "utf-8");
|
|
63530
63746
|
}
|
|
63531
63747
|
return { agent, path, action: "removed" };
|
|
63532
63748
|
}
|
|
@@ -63554,36 +63770,36 @@ var init_installer = __esm(() => {
|
|
|
63554
63770
|
RULE_TARGETS = {
|
|
63555
63771
|
claude: {
|
|
63556
63772
|
kind: "file",
|
|
63557
|
-
path: () =>
|
|
63773
|
+
path: () => join42(claudeConfigDir4(), "rules", "dosu.md")
|
|
63558
63774
|
},
|
|
63559
63775
|
cursor: {
|
|
63560
63776
|
kind: "file",
|
|
63561
|
-
path: () =>
|
|
63777
|
+
path: () => join42(homedir13(), ".cursor", "rules", "dosu.mdc"),
|
|
63562
63778
|
cursorFrontmatter: true
|
|
63563
63779
|
},
|
|
63564
63780
|
codex: {
|
|
63565
63781
|
kind: "section",
|
|
63566
|
-
path: () =>
|
|
63782
|
+
path: () => join42(codexHome4(), "AGENTS.md")
|
|
63567
63783
|
},
|
|
63568
63784
|
opencode: {
|
|
63569
63785
|
kind: "section",
|
|
63570
|
-
path: () =>
|
|
63786
|
+
path: () => join42(homedir13(), ".config", "opencode", "AGENTS.md")
|
|
63571
63787
|
},
|
|
63572
63788
|
gemini: {
|
|
63573
63789
|
kind: "section",
|
|
63574
|
-
path: () =>
|
|
63790
|
+
path: () => join42(homedir13(), ".gemini", "GEMINI.md")
|
|
63575
63791
|
},
|
|
63576
63792
|
antigravity: {
|
|
63577
63793
|
kind: "section",
|
|
63578
|
-
path: () =>
|
|
63794
|
+
path: () => join42(homedir13(), ".gemini", "GEMINI.md")
|
|
63579
63795
|
}
|
|
63580
63796
|
};
|
|
63581
63797
|
});
|
|
63582
63798
|
|
|
63583
63799
|
// src/setup/agents-md-step.ts
|
|
63584
63800
|
import { execSync as execSync2 } from "node:child_process";
|
|
63585
|
-
import { existsSync as
|
|
63586
|
-
import { join as
|
|
63801
|
+
import { existsSync as existsSync29, readFileSync as readFileSync28, writeFileSync as writeFileSync19 } from "node:fs";
|
|
63802
|
+
import { join as join43 } from "node:path";
|
|
63587
63803
|
function inGitWorkTree(cwd = process.cwd()) {
|
|
63588
63804
|
try {
|
|
63589
63805
|
const stdout = execSync2("git rev-parse --is-inside-work-tree", {
|
|
@@ -63597,10 +63813,10 @@ function inGitWorkTree(cwd = process.cwd()) {
|
|
|
63597
63813
|
}
|
|
63598
63814
|
function dosuAgentsSectionState(cwd = process.cwd()) {
|
|
63599
63815
|
try {
|
|
63600
|
-
const path =
|
|
63601
|
-
if (!
|
|
63816
|
+
const path = join43(cwd, "AGENTS.md");
|
|
63817
|
+
if (!existsSync29(path))
|
|
63602
63818
|
return "missing";
|
|
63603
|
-
const content =
|
|
63819
|
+
const content = readFileSync28(path, "utf-8");
|
|
63604
63820
|
const startMatch = content.match(SECTION_START_RE);
|
|
63605
63821
|
if (!startMatch || !content.includes(DOSU_SECTION_END))
|
|
63606
63822
|
return "missing";
|
|
@@ -63635,14 +63851,14 @@ function findSection2(content) {
|
|
|
63635
63851
|
return { start, end };
|
|
63636
63852
|
}
|
|
63637
63853
|
function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
|
|
63638
|
-
const path =
|
|
63639
|
-
if (!
|
|
63854
|
+
const path = join43(cwd, "AGENTS.md");
|
|
63855
|
+
if (!existsSync29(path)) {
|
|
63640
63856
|
const section = buildDosuAgentsSection(content);
|
|
63641
|
-
|
|
63857
|
+
writeFileSync19(path, `${section}
|
|
63642
63858
|
`);
|
|
63643
63859
|
return { path, action: "created" };
|
|
63644
63860
|
}
|
|
63645
|
-
const existing =
|
|
63861
|
+
const existing = readFileSync28(path, "utf-8");
|
|
63646
63862
|
const lineEnding = lineEndingFor2(existing);
|
|
63647
63863
|
const section = renderDosuAgentsSection(content, lineEnding);
|
|
63648
63864
|
const location = findSection2(existing);
|
|
@@ -63654,7 +63870,7 @@ function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RU
|
|
|
63654
63870
|
}
|
|
63655
63871
|
if (next === existing)
|
|
63656
63872
|
return { path, action: "unchanged" };
|
|
63657
|
-
|
|
63873
|
+
writeFileSync19(path, next);
|
|
63658
63874
|
return { path, action: "updated" };
|
|
63659
63875
|
}
|
|
63660
63876
|
async function stepUpdateAgentsMd(cwd = process.cwd(), content) {
|
|
@@ -65366,7 +65582,7 @@ var init_flow2 = __esm(() => {
|
|
|
65366
65582
|
// src/commands/upgrade.ts
|
|
65367
65583
|
import { spawnSync } from "node:child_process";
|
|
65368
65584
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
65369
|
-
import { homedir as
|
|
65585
|
+
import { homedir as homedir14 } from "node:os";
|
|
65370
65586
|
import { posix, win32 as win322 } from "node:path";
|
|
65371
65587
|
function isAbsoluteCommandProcessor(value) {
|
|
65372
65588
|
return Boolean(value && win322.isAbsolute(value) && win322.basename(value).toLowerCase() === "cmd.exe");
|
|
@@ -65420,7 +65636,7 @@ function packageRoots(manager, platform, comSpec, env, cwd) {
|
|
|
65420
65636
|
manager === "npm" ? path.join(lines[0], "@dosu", "cli") : path.join(lines[0], "node_modules", "@dosu", "cli")
|
|
65421
65637
|
];
|
|
65422
65638
|
}
|
|
65423
|
-
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd =
|
|
65639
|
+
function owningPackageManager(entrypoint, platform, comSpec, env = process.env, cwd = homedir14()) {
|
|
65424
65640
|
const path = platform === "win32" ? win322 : posix;
|
|
65425
65641
|
if (!entrypoint || !path.isAbsolute(entrypoint))
|
|
65426
65642
|
return null;
|
|
@@ -65473,7 +65689,7 @@ Or install Dosu globally with your package manager:`);
|
|
|
65473
65689
|
function runUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
65474
65690
|
const platform = options.platform ?? process.platform;
|
|
65475
65691
|
const env = options.env ?? process.env;
|
|
65476
|
-
const cwd = options.cwd ??
|
|
65692
|
+
const cwd = options.cwd ?? homedir14();
|
|
65477
65693
|
let manager = null;
|
|
65478
65694
|
if (channel === "npm") {
|
|
65479
65695
|
if (isNpxInvocation(channel, env)) {
|
|
@@ -65540,7 +65756,7 @@ function finishWithNewBinary(channel, options) {
|
|
|
65540
65756
|
return;
|
|
65541
65757
|
}
|
|
65542
65758
|
const result = spawnSync(invocation.command, invocation.args, {
|
|
65543
|
-
cwd: options.cwd ??
|
|
65759
|
+
cwd: options.cwd ?? homedir14(),
|
|
65544
65760
|
shell: false,
|
|
65545
65761
|
stdio: "inherit"
|
|
65546
65762
|
});
|
|
@@ -65590,9 +65806,37 @@ Refreshing agent MCP configs with the new version...`);
|
|
|
65590
65806
|
console.error(SETUP_FALLBACK);
|
|
65591
65807
|
return 0;
|
|
65592
65808
|
}
|
|
65809
|
+
function setAutoUpdate(value) {
|
|
65810
|
+
const normalized = value.trim().toLowerCase();
|
|
65811
|
+
if (normalized !== "on" && normalized !== "off") {
|
|
65812
|
+
console.error(`Invalid --auto value '${value}' (expected 'on' or 'off').`);
|
|
65813
|
+
return 2;
|
|
65814
|
+
}
|
|
65815
|
+
if (!setAutoUpdateEnabled(normalized === "on")) {
|
|
65816
|
+
console.error("Could not save the auto-update setting.");
|
|
65817
|
+
return 1;
|
|
65818
|
+
}
|
|
65819
|
+
if (normalized === "off") {
|
|
65820
|
+
console.log('Automatic updates are off. Run "dosu upgrade" to update by hand.');
|
|
65821
|
+
} else if (autoUpdateDisabledReason() === "env") {
|
|
65822
|
+
console.log(`Automatic updates are on, but ${AUTO_UPDATE_ENV} still disables them here.`);
|
|
65823
|
+
} else {
|
|
65824
|
+
console.log("Automatic updates are on.");
|
|
65825
|
+
}
|
|
65826
|
+
return 0;
|
|
65827
|
+
}
|
|
65593
65828
|
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
|
-
|
|
65829
|
+
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) => {
|
|
65830
|
+
let status;
|
|
65831
|
+
if (opts.auto !== undefined) {
|
|
65832
|
+
status = setAutoUpdate(opts.auto);
|
|
65833
|
+
} else if (opts.background) {
|
|
65834
|
+
status = runBackgroundUpgrade(() => runUpgrade());
|
|
65835
|
+
} else if (opts.finish !== undefined) {
|
|
65836
|
+
status = await finishUpgrade(opts.finish);
|
|
65837
|
+
} else {
|
|
65838
|
+
status = await completeUpgrade();
|
|
65839
|
+
}
|
|
65596
65840
|
if (status !== 0)
|
|
65597
65841
|
process.exitCode = status;
|
|
65598
65842
|
});
|
|
@@ -65602,6 +65846,7 @@ var init_upgrade = __esm(() => {
|
|
|
65602
65846
|
init_commander();
|
|
65603
65847
|
init_config();
|
|
65604
65848
|
init_refresh();
|
|
65849
|
+
init_auto_update();
|
|
65605
65850
|
init_mcp_refresh_check();
|
|
65606
65851
|
init_skill_update_check();
|
|
65607
65852
|
import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
@@ -66309,7 +66554,7 @@ var init_pages_view = __esm(() => {
|
|
|
66309
66554
|
});
|
|
66310
66555
|
|
|
66311
66556
|
// src/tui/tui.ts
|
|
66312
|
-
import { homedir as
|
|
66557
|
+
import { homedir as homedir15 } from "node:os";
|
|
66313
66558
|
import { basename as basename6 } from "node:path";
|
|
66314
66559
|
async function probeSession(cfg) {
|
|
66315
66560
|
if (!isAuthenticated(cfg) || !isTokenExpired(cfg))
|
|
@@ -66574,7 +66819,7 @@ async function runSettings(cfg) {
|
|
|
66574
66819
|
}
|
|
66575
66820
|
}
|
|
66576
66821
|
function displayDir(dir) {
|
|
66577
|
-
const home =
|
|
66822
|
+
const home = homedir15();
|
|
66578
66823
|
return dir === home ? "~" : dir.startsWith(`${home}/`) ? `~${dir.slice(home.length)}` : dir;
|
|
66579
66824
|
}
|
|
66580
66825
|
function discoverProjectDirs() {
|
|
@@ -67284,7 +67529,7 @@ var init_flow3 = __esm(() => {
|
|
|
67284
67529
|
});
|
|
67285
67530
|
|
|
67286
67531
|
// src/cli/cli.ts
|
|
67287
|
-
import { readFileSync as
|
|
67532
|
+
import { readFileSync as readFileSync29, unlinkSync as unlinkSync6 } from "node:fs";
|
|
67288
67533
|
function shouldRunBackgroundChecks(actionName) {
|
|
67289
67534
|
return actionName !== "upgrade";
|
|
67290
67535
|
}
|
|
@@ -67730,7 +67975,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
67730
67975
|
}
|
|
67731
67976
|
if (opts.follow) {
|
|
67732
67977
|
try {
|
|
67733
|
-
const lines =
|
|
67978
|
+
const lines = readFileSync29(logPath, "utf-8").split(`
|
|
67734
67979
|
`);
|
|
67735
67980
|
if (lines.at(-1) === "")
|
|
67736
67981
|
lines.pop();
|
|
@@ -67746,7 +67991,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
67746
67991
|
if (opts.tail !== undefined) {
|
|
67747
67992
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
67748
67993
|
try {
|
|
67749
|
-
const content =
|
|
67994
|
+
const content = readFileSync29(logPath, "utf-8");
|
|
67750
67995
|
const lines = content.split(`
|
|
67751
67996
|
`);
|
|
67752
67997
|
console.log(lines.slice(-n).join(`
|
|
@@ -67872,4 +68117,4 @@ main().catch((err) => {
|
|
|
67872
68117
|
process.exit(1);
|
|
67873
68118
|
});
|
|
67874
68119
|
|
|
67875
|
-
//# debugId=
|
|
68120
|
+
//# debugId=da3b44a3-063b-fb2c-6475-6e2164756e21
|