@dosu/cli 0.32.1 → 0.33.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/bin/dosu.js +192 -95
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -4577,7 +4577,7 @@ var init_dist4 = __esm(() => {
|
|
|
4577
4577
|
function getVersionString() {
|
|
4578
4578
|
return `v${VERSION}`;
|
|
4579
4579
|
}
|
|
4580
|
-
var VERSION = "0.
|
|
4580
|
+
var VERSION = "0.33.0", INSTALL_CHANNEL = "npm";
|
|
4581
4581
|
|
|
4582
4582
|
// src/debug/logger.ts
|
|
4583
4583
|
import {
|
|
@@ -10981,6 +10981,160 @@ var init_providers = __esm(() => {
|
|
|
10981
10981
|
init_zed();
|
|
10982
10982
|
});
|
|
10983
10983
|
|
|
10984
|
+
// src/setup/audit-handoff.ts
|
|
10985
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
10986
|
+
function buildAuditHandoffPrompt(dosuCmd = dosuInvocation()) {
|
|
10987
|
+
return [
|
|
10988
|
+
"Audit this repository to see what docs Dosu can generate for it.",
|
|
10989
|
+
"1. Run the codebase audit from the Dosu skill. It writes findings to .dosu/audit.json.",
|
|
10990
|
+
"2. Show me the findings and which docs you recommend Dosu generate.",
|
|
10991
|
+
`3. Once I confirm, run \`${dosuCmd} audit --tasks <comma-separated task ids> --json\` to kick off generation. Dosu opens a PR and the CLI notifies me when it's ready.`
|
|
10992
|
+
].join(`
|
|
10993
|
+
`);
|
|
10994
|
+
}
|
|
10995
|
+
function binOnPath(bin) {
|
|
10996
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
10997
|
+
try {
|
|
10998
|
+
return spawnSync2(cmd, [bin], { stdio: "ignore" }).status === 0;
|
|
10999
|
+
} catch {
|
|
11000
|
+
return false;
|
|
11001
|
+
}
|
|
11002
|
+
}
|
|
11003
|
+
function claudeCliAvailable() {
|
|
11004
|
+
return binOnPath("claude");
|
|
11005
|
+
}
|
|
11006
|
+
function dosuInvocation() {
|
|
11007
|
+
return binOnPath("dosu") ? "dosu" : "npx -y @dosu/cli";
|
|
11008
|
+
}
|
|
11009
|
+
function printManualAuditNudge() {
|
|
11010
|
+
log.message(`See what docs Dosu can generate for this repo:
|
|
11011
|
+
|
|
11012
|
+
${info("Ask Dosu to audit this repo and show what docs it can generate.")}
|
|
11013
|
+
|
|
11014
|
+
Or run ${info(`${dosuInvocation()} audit`)} after your agent writes the audit.`);
|
|
11015
|
+
}
|
|
11016
|
+
async function offerAuditHandoff() {
|
|
11017
|
+
if (!detectGitRepo())
|
|
11018
|
+
return false;
|
|
11019
|
+
if (!claudeCliAvailable()) {
|
|
11020
|
+
printManualAuditNudge();
|
|
11021
|
+
return false;
|
|
11022
|
+
}
|
|
11023
|
+
const go = await confirm({
|
|
11024
|
+
message: "Kick off the codebase audit in Claude Code now?",
|
|
11025
|
+
initialValue: true
|
|
11026
|
+
});
|
|
11027
|
+
if (isCancel(go) || !go) {
|
|
11028
|
+
printManualAuditNudge();
|
|
11029
|
+
return false;
|
|
11030
|
+
}
|
|
11031
|
+
return true;
|
|
11032
|
+
}
|
|
11033
|
+
function launchAuditAgent() {
|
|
11034
|
+
logger.info("setup", "Handing off to Claude Code for the codebase audit");
|
|
11035
|
+
const result = spawnSync2("claude", ["--model", AUDIT_AGENT_MODEL, buildAuditHandoffPrompt()], {
|
|
11036
|
+
stdio: "inherit",
|
|
11037
|
+
shell: process.platform === "win32"
|
|
11038
|
+
});
|
|
11039
|
+
if (result.error) {
|
|
11040
|
+
logger.warn("setup", `Claude Code launch failed: ${result.error.message}`);
|
|
11041
|
+
printManualAuditNudge();
|
|
11042
|
+
}
|
|
11043
|
+
}
|
|
11044
|
+
var AUDIT_AGENT_MODEL = "haiku";
|
|
11045
|
+
var init_audit_handoff = __esm(() => {
|
|
11046
|
+
init_dist8();
|
|
11047
|
+
init_logger();
|
|
11048
|
+
init_github_step();
|
|
11049
|
+
init_styles();
|
|
11050
|
+
});
|
|
11051
|
+
|
|
11052
|
+
// src/setup/agents-md-step.ts
|
|
11053
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
11054
|
+
import { existsSync as existsSync16, readFileSync as readFileSync14, writeFileSync as writeFileSync7 } from "node:fs";
|
|
11055
|
+
import { join as join26 } from "node:path";
|
|
11056
|
+
function inGitWorkTree(cwd = process.cwd()) {
|
|
11057
|
+
try {
|
|
11058
|
+
const stdout2 = execSync3("git rev-parse --is-inside-work-tree", {
|
|
11059
|
+
cwd,
|
|
11060
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
11061
|
+
});
|
|
11062
|
+
return stdout2.toString().trim() === "true";
|
|
11063
|
+
} catch {
|
|
11064
|
+
return false;
|
|
11065
|
+
}
|
|
11066
|
+
}
|
|
11067
|
+
function buildDosuAgentsSection(dosuCmd = dosuInvocation()) {
|
|
11068
|
+
return [
|
|
11069
|
+
DOSU_SECTION_START,
|
|
11070
|
+
"## Dosu",
|
|
11071
|
+
"",
|
|
11072
|
+
"Shared team knowledge lives in [Dosu](https://dosu.dev), via the Dosu MCP server.",
|
|
11073
|
+
"",
|
|
11074
|
+
"- Before a task, and for any codebase or docs questions: pull context with `read_knowledge` before digging through source.",
|
|
11075
|
+
"- After a task: save durable learnings with `write_knowledge`.",
|
|
11076
|
+
"",
|
|
11077
|
+
`Missing these tools? Run \`${dosuCmd} setup --help\` — it covers agent-assisted setup.`,
|
|
11078
|
+
DOSU_SECTION_END
|
|
11079
|
+
].join(`
|
|
11080
|
+
`);
|
|
11081
|
+
}
|
|
11082
|
+
function upsertDosuAgentsSection(cwd = process.cwd(), dosuCmd = dosuInvocation()) {
|
|
11083
|
+
const path3 = join26(cwd, "AGENTS.md");
|
|
11084
|
+
const section = buildDosuAgentsSection(dosuCmd);
|
|
11085
|
+
if (!existsSync16(path3)) {
|
|
11086
|
+
writeFileSync7(path3, `${section}
|
|
11087
|
+
`);
|
|
11088
|
+
return { path: path3, action: "created" };
|
|
11089
|
+
}
|
|
11090
|
+
const existing = readFileSync14(path3, "utf-8");
|
|
11091
|
+
const startMatch = existing.match(SECTION_START_RE);
|
|
11092
|
+
const start = startMatch?.index ?? -1;
|
|
11093
|
+
const end = existing.indexOf(DOSU_SECTION_END);
|
|
11094
|
+
let next;
|
|
11095
|
+
if (start !== -1 && end !== -1 && end >= start) {
|
|
11096
|
+
next = existing.slice(0, start) + section + existing.slice(end + DOSU_SECTION_END.length);
|
|
11097
|
+
} else {
|
|
11098
|
+
next = `${existing.trimEnd()}
|
|
11099
|
+
|
|
11100
|
+
${section}
|
|
11101
|
+
`;
|
|
11102
|
+
}
|
|
11103
|
+
if (next === existing)
|
|
11104
|
+
return { path: path3, action: "unchanged" };
|
|
11105
|
+
writeFileSync7(path3, next);
|
|
11106
|
+
return { path: path3, action: "updated" };
|
|
11107
|
+
}
|
|
11108
|
+
function stepUpdateAgentsMd(cwd = process.cwd()) {
|
|
11109
|
+
logger.info("setup", "Step: update AGENTS.md");
|
|
11110
|
+
try {
|
|
11111
|
+
const result = upsertDosuAgentsSection(cwd);
|
|
11112
|
+
logger.info("setup", `AGENTS.md ${result.action} at ${result.path}`);
|
|
11113
|
+
if (result.action === "unchanged") {
|
|
11114
|
+
log.success(`AGENTS.md
|
|
11115
|
+
${dim("Dosu section already up to date")}`);
|
|
11116
|
+
} else {
|
|
11117
|
+
log.success(`AGENTS.md
|
|
11118
|
+
${dim(`Dosu section ${result.action} — ${result.path}`)}`);
|
|
11119
|
+
}
|
|
11120
|
+
return true;
|
|
11121
|
+
} catch (err) {
|
|
11122
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11123
|
+
logger.error("setup", `AGENTS.md update failed: ${msg}`);
|
|
11124
|
+
log.error(`Could not update AGENTS.md: ${msg}`);
|
|
11125
|
+
return false;
|
|
11126
|
+
}
|
|
11127
|
+
}
|
|
11128
|
+
var DOSU_SECTION_VERSION = 1, DOSU_SECTION_START, DOSU_SECTION_END = "<!-- dosu:mcp:end -->", SECTION_START_RE;
|
|
11129
|
+
var init_agents_md_step = __esm(() => {
|
|
11130
|
+
init_dist8();
|
|
11131
|
+
init_logger();
|
|
11132
|
+
init_audit_handoff();
|
|
11133
|
+
init_styles();
|
|
11134
|
+
DOSU_SECTION_START = `<!-- dosu:mcp:start v${DOSU_SECTION_VERSION} -->`;
|
|
11135
|
+
SECTION_START_RE = /<!-- dosu:mcp:start(?: v(\d+))? -->/;
|
|
11136
|
+
});
|
|
11137
|
+
|
|
10984
11138
|
// src/setup/analytics.ts
|
|
10985
11139
|
async function trackCliOnboardingEvent(cfg, onboardingRunID, event, properties = {}) {
|
|
10986
11140
|
if (!cfg.access_token)
|
|
@@ -11066,74 +11220,6 @@ var init_analytics = __esm(() => {
|
|
|
11066
11220
|
init_logger();
|
|
11067
11221
|
});
|
|
11068
11222
|
|
|
11069
|
-
// src/setup/audit-handoff.ts
|
|
11070
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
11071
|
-
function buildAuditHandoffPrompt(dosuCmd = dosuInvocation()) {
|
|
11072
|
-
return [
|
|
11073
|
-
"Audit this repository to see what docs Dosu can generate for it.",
|
|
11074
|
-
"1. Run the codebase audit from the Dosu skill. It writes findings to .dosu/audit.json.",
|
|
11075
|
-
"2. Show me the findings and which docs you recommend Dosu generate.",
|
|
11076
|
-
`3. Once I confirm, run \`${dosuCmd} audit --tasks <comma-separated task ids> --json\` to kick off generation. Dosu opens a PR and the CLI notifies me when it's ready.`
|
|
11077
|
-
].join(`
|
|
11078
|
-
`);
|
|
11079
|
-
}
|
|
11080
|
-
function binOnPath(bin) {
|
|
11081
|
-
const cmd = process.platform === "win32" ? "where" : "which";
|
|
11082
|
-
try {
|
|
11083
|
-
return spawnSync2(cmd, [bin], { stdio: "ignore" }).status === 0;
|
|
11084
|
-
} catch {
|
|
11085
|
-
return false;
|
|
11086
|
-
}
|
|
11087
|
-
}
|
|
11088
|
-
function claudeCliAvailable() {
|
|
11089
|
-
return binOnPath("claude");
|
|
11090
|
-
}
|
|
11091
|
-
function dosuInvocation() {
|
|
11092
|
-
return binOnPath("dosu") ? "dosu" : "npx -y @dosu/cli";
|
|
11093
|
-
}
|
|
11094
|
-
function printManualAuditNudge() {
|
|
11095
|
-
log.message(`See what docs Dosu can generate for this repo:
|
|
11096
|
-
|
|
11097
|
-
${info("Ask Dosu to audit this repo and show what docs it can generate.")}
|
|
11098
|
-
|
|
11099
|
-
Or run ${info(`${dosuInvocation()} audit`)} after your agent writes the audit.`);
|
|
11100
|
-
}
|
|
11101
|
-
async function offerAuditHandoff() {
|
|
11102
|
-
if (!detectGitRepo())
|
|
11103
|
-
return false;
|
|
11104
|
-
if (!claudeCliAvailable()) {
|
|
11105
|
-
printManualAuditNudge();
|
|
11106
|
-
return false;
|
|
11107
|
-
}
|
|
11108
|
-
const go = await confirm({
|
|
11109
|
-
message: "Kick off the codebase audit in Claude Code now?",
|
|
11110
|
-
initialValue: true
|
|
11111
|
-
});
|
|
11112
|
-
if (isCancel(go) || !go) {
|
|
11113
|
-
printManualAuditNudge();
|
|
11114
|
-
return false;
|
|
11115
|
-
}
|
|
11116
|
-
return true;
|
|
11117
|
-
}
|
|
11118
|
-
function launchAuditAgent() {
|
|
11119
|
-
logger.info("setup", "Handing off to Claude Code for the codebase audit");
|
|
11120
|
-
const result = spawnSync2("claude", ["--model", AUDIT_AGENT_MODEL, buildAuditHandoffPrompt()], {
|
|
11121
|
-
stdio: "inherit",
|
|
11122
|
-
shell: process.platform === "win32"
|
|
11123
|
-
});
|
|
11124
|
-
if (result.error) {
|
|
11125
|
-
logger.warn("setup", `Claude Code launch failed: ${result.error.message}`);
|
|
11126
|
-
printManualAuditNudge();
|
|
11127
|
-
}
|
|
11128
|
-
}
|
|
11129
|
-
var AUDIT_AGENT_MODEL = "haiku";
|
|
11130
|
-
var init_audit_handoff = __esm(() => {
|
|
11131
|
-
init_dist8();
|
|
11132
|
-
init_logger();
|
|
11133
|
-
init_github_step();
|
|
11134
|
-
init_styles();
|
|
11135
|
-
});
|
|
11136
|
-
|
|
11137
11223
|
// src/auth/errors.ts
|
|
11138
11224
|
var exports_errors = {};
|
|
11139
11225
|
__export(exports_errors, {
|
|
@@ -11718,7 +11804,7 @@ async function runSetup(opts = {}) {
|
|
|
11718
11804
|
}
|
|
11719
11805
|
cfg.api_key = apiKey;
|
|
11720
11806
|
saveConfig(cfg);
|
|
11721
|
-
const choices = await stepOneShotConfirm();
|
|
11807
|
+
const choices = await stepOneShotConfirm(inGitWorkTree());
|
|
11722
11808
|
if (!choices) {
|
|
11723
11809
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_cancelled", {
|
|
11724
11810
|
reason: "options_cancelled"
|
|
@@ -11727,7 +11813,8 @@ async function runSetup(opts = {}) {
|
|
|
11727
11813
|
}
|
|
11728
11814
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_options_selected", {
|
|
11729
11815
|
configure_mcp: choices.configureMcp,
|
|
11730
|
-
install_skill: choices.installSkill
|
|
11816
|
+
install_skill: choices.installSkill,
|
|
11817
|
+
update_agents_md: choices.updateAgentsMd
|
|
11731
11818
|
});
|
|
11732
11819
|
let mcpConfiguredThisRun = false;
|
|
11733
11820
|
let mcpCompleted = false;
|
|
@@ -11756,14 +11843,19 @@ async function runSetup(opts = {}) {
|
|
|
11756
11843
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_skill_installed");
|
|
11757
11844
|
}
|
|
11758
11845
|
}
|
|
11846
|
+
let agentsMdCompleted = false;
|
|
11847
|
+
if (choices.updateAgentsMd) {
|
|
11848
|
+
agentsMdCompleted = stepUpdateAgentsMd();
|
|
11849
|
+
}
|
|
11759
11850
|
let handoffToAudit = false;
|
|
11760
11851
|
if (mcpConfiguredThisRun && cfg.mode !== MODE_OSS) {
|
|
11761
11852
|
handoffToAudit = await offerAuditHandoff();
|
|
11762
11853
|
}
|
|
11763
|
-
if (mcpCompleted || skillCompleted) {
|
|
11854
|
+
if (mcpCompleted || skillCompleted || agentsMdCompleted) {
|
|
11764
11855
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_completed", {
|
|
11765
11856
|
completed_mcp: mcpCompleted,
|
|
11766
|
-
completed_skill: skillCompleted
|
|
11857
|
+
completed_skill: skillCompleted,
|
|
11858
|
+
completed_agents_md: agentsMdCompleted
|
|
11767
11859
|
});
|
|
11768
11860
|
}
|
|
11769
11861
|
if (cfg.mode === MODE_OSS) {
|
|
@@ -11792,11 +11884,14 @@ function applyModeOverride(cfg, opts) {
|
|
|
11792
11884
|
}
|
|
11793
11885
|
saveConfig(cfg);
|
|
11794
11886
|
}
|
|
11795
|
-
async function stepOneShotConfirm() {
|
|
11887
|
+
async function stepOneShotConfirm(offerAgentsMd) {
|
|
11796
11888
|
const items = [
|
|
11797
11889
|
{ value: "configureMcp", label: "Install Dosu MCP" },
|
|
11798
11890
|
{ value: "installSkill", label: "Install Dosu skill" }
|
|
11799
11891
|
];
|
|
11892
|
+
if (offerAgentsMd) {
|
|
11893
|
+
items.push({ value: "updateAgentsMd", label: "Add Dosu instructions to AGENTS.md" });
|
|
11894
|
+
}
|
|
11800
11895
|
const selected = await multiselect({
|
|
11801
11896
|
message: "Dosu will set these up — press Enter to accept, space to toggle",
|
|
11802
11897
|
options: items.map((it) => ({ value: it.value, label: it.label })),
|
|
@@ -11810,7 +11905,8 @@ async function stepOneShotConfirm() {
|
|
|
11810
11905
|
const chosen = new Set(selected);
|
|
11811
11906
|
return {
|
|
11812
11907
|
configureMcp: chosen.has("configureMcp"),
|
|
11813
|
-
installSkill: chosen.has("installSkill")
|
|
11908
|
+
installSkill: chosen.has("installSkill"),
|
|
11909
|
+
updateAgentsMd: chosen.has("updateAgentsMd")
|
|
11814
11910
|
};
|
|
11815
11911
|
}
|
|
11816
11912
|
async function stepConfigureMcpTools(cfg) {
|
|
@@ -12263,14 +12359,15 @@ var init_flow2 = __esm(() => {
|
|
|
12263
12359
|
init_config();
|
|
12264
12360
|
init_logger();
|
|
12265
12361
|
init_providers();
|
|
12362
|
+
init_agents_md_step();
|
|
12266
12363
|
init_analytics();
|
|
12267
12364
|
init_audit_handoff();
|
|
12268
12365
|
init_styles();
|
|
12269
12366
|
});
|
|
12270
12367
|
|
|
12271
12368
|
// src/commands/insights.ts
|
|
12272
|
-
import { existsSync as
|
|
12273
|
-
import { dirname as dirname5, join as
|
|
12369
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync8, readdirSync, unlinkSync, writeFileSync as writeFileSync8 } from "node:fs";
|
|
12370
|
+
import { dirname as dirname5, join as join27 } from "node:path";
|
|
12274
12371
|
function shuffled(arr) {
|
|
12275
12372
|
const copy2 = [...arr];
|
|
12276
12373
|
for (let i2 = copy2.length - 1;i2 > 0; i2--) {
|
|
@@ -12374,17 +12471,17 @@ function makeAskFn(cfg) {
|
|
|
12374
12471
|
};
|
|
12375
12472
|
}
|
|
12376
12473
|
function insightsDir() {
|
|
12377
|
-
return
|
|
12474
|
+
return join27(getConfigDir(), "insights");
|
|
12378
12475
|
}
|
|
12379
12476
|
function reportPath(timestamp) {
|
|
12380
12477
|
const dir = insightsDir();
|
|
12381
12478
|
if (!timestamp)
|
|
12382
|
-
return
|
|
12479
|
+
return join27(dir, "latest.html");
|
|
12383
12480
|
const iso = timestamp.toISOString().slice(0, 19).replace(/:/g, "-");
|
|
12384
|
-
return
|
|
12481
|
+
return join27(dir, `report-${iso}Z.html`);
|
|
12385
12482
|
}
|
|
12386
12483
|
function pruneOldReports(dir, keepN) {
|
|
12387
|
-
if (!
|
|
12484
|
+
if (!existsSync17(dir))
|
|
12388
12485
|
return;
|
|
12389
12486
|
let entries;
|
|
12390
12487
|
try {
|
|
@@ -12396,7 +12493,7 @@ function pruneOldReports(dir, keepN) {
|
|
|
12396
12493
|
const reports = entries.filter((f2) => REPORT_FILE_PATTERN.test(f2)).sort().reverse();
|
|
12397
12494
|
for (const f2 of reports.slice(keepN)) {
|
|
12398
12495
|
try {
|
|
12399
|
-
unlinkSync(
|
|
12496
|
+
unlinkSync(join27(dir, f2));
|
|
12400
12497
|
} catch (err) {
|
|
12401
12498
|
logger.debug("insights", `failed to prune ${f2}: ${err instanceof Error ? err.message : err}`);
|
|
12402
12499
|
}
|
|
@@ -12469,9 +12566,9 @@ function defaultRunner(cfg) {
|
|
|
12469
12566
|
render: renderHTML,
|
|
12470
12567
|
writeFile: (path3, content) => {
|
|
12471
12568
|
const dir = dirname5(path3);
|
|
12472
|
-
if (!
|
|
12569
|
+
if (!existsSync17(dir))
|
|
12473
12570
|
mkdirSync8(dir, { recursive: true, mode: 448 });
|
|
12474
|
-
|
|
12571
|
+
writeFileSync8(path3, content, { mode: 384 });
|
|
12475
12572
|
},
|
|
12476
12573
|
prune: pruneOldReports,
|
|
12477
12574
|
openInBrowser: async (path3) => {
|
|
@@ -13198,7 +13295,7 @@ var init_flow3 = __esm(() => {
|
|
|
13198
13295
|
// src/cli/cli.ts
|
|
13199
13296
|
init_commander();
|
|
13200
13297
|
init_client();
|
|
13201
|
-
import { readFileSync as
|
|
13298
|
+
import { readFileSync as readFileSync17, unlinkSync as unlinkSync2 } from "node:fs";
|
|
13202
13299
|
|
|
13203
13300
|
// src/commands/analytics.ts
|
|
13204
13301
|
init_commander();
|
|
@@ -15260,7 +15357,7 @@ init_dist();
|
|
|
15260
15357
|
init_commander();
|
|
15261
15358
|
init_trpc();
|
|
15262
15359
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
15263
|
-
import { readFileSync as
|
|
15360
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
15264
15361
|
function requireConfig10() {
|
|
15265
15362
|
return requireLoginConfig();
|
|
15266
15363
|
}
|
|
@@ -15436,7 +15533,7 @@ function reviewCommand() {
|
|
|
15436
15533
|
let body = opts.body;
|
|
15437
15534
|
if (opts.bodyFile) {
|
|
15438
15535
|
try {
|
|
15439
|
-
body =
|
|
15536
|
+
body = readFileSync15(opts.bodyFile, "utf-8");
|
|
15440
15537
|
} catch (err) {
|
|
15441
15538
|
console.error(import_picocolors19.default.red(`Failed to read --body-file: ${err.message}`));
|
|
15442
15539
|
process.exit(1);
|
|
@@ -15956,8 +16053,8 @@ init_skill_update_check();
|
|
|
15956
16053
|
init_config();
|
|
15957
16054
|
init_logger();
|
|
15958
16055
|
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
15959
|
-
import { existsSync as
|
|
15960
|
-
import { join as
|
|
16056
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "node:fs";
|
|
16057
|
+
import { join as join28 } from "node:path";
|
|
15961
16058
|
var CACHE_FILENAME3 = "update-check.json";
|
|
15962
16059
|
var CHECK_INTERVAL_MS3 = 24 * 60 * 60 * 1000;
|
|
15963
16060
|
var FETCH_TIMEOUT_MS3 = 5000;
|
|
@@ -15980,14 +16077,14 @@ function isNewerVersion(latest, current) {
|
|
|
15980
16077
|
return false;
|
|
15981
16078
|
}
|
|
15982
16079
|
function getCachePath3() {
|
|
15983
|
-
return
|
|
16080
|
+
return join28(getConfigDir(), CACHE_FILENAME3);
|
|
15984
16081
|
}
|
|
15985
16082
|
function readCache() {
|
|
15986
16083
|
try {
|
|
15987
16084
|
const path3 = getCachePath3();
|
|
15988
|
-
if (!
|
|
16085
|
+
if (!existsSync18(path3))
|
|
15989
16086
|
return null;
|
|
15990
|
-
const data = JSON.parse(
|
|
16087
|
+
const data = JSON.parse(readFileSync16(path3, "utf-8"));
|
|
15991
16088
|
if (typeof data.lastCheck === "number" && typeof data.latestVersion === "string") {
|
|
15992
16089
|
return data;
|
|
15993
16090
|
}
|
|
@@ -15999,10 +16096,10 @@ function readCache() {
|
|
|
15999
16096
|
function writeCache(cache) {
|
|
16000
16097
|
try {
|
|
16001
16098
|
const dir = getConfigDir();
|
|
16002
|
-
if (!
|
|
16099
|
+
if (!existsSync18(dir)) {
|
|
16003
16100
|
mkdirSync9(dir, { recursive: true, mode: 448 });
|
|
16004
16101
|
}
|
|
16005
|
-
|
|
16102
|
+
writeFileSync9(getCachePath3(), JSON.stringify(cache), { mode: 384 });
|
|
16006
16103
|
} catch {}
|
|
16007
16104
|
}
|
|
16008
16105
|
async function fetchLatestVersion() {
|
|
@@ -16366,7 +16463,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
16366
16463
|
if (opts.tail !== undefined) {
|
|
16367
16464
|
const n2 = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
16368
16465
|
try {
|
|
16369
|
-
const content =
|
|
16466
|
+
const content = readFileSync17(logPath, "utf-8");
|
|
16370
16467
|
const lines = content.split(`
|
|
16371
16468
|
`);
|
|
16372
16469
|
console.log(lines.slice(-n2).join(`
|