@dosu/cli 0.19.3 → 0.20.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 +265 -86
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -4548,7 +4548,7 @@ var init_dist4 = __esm(() => {
|
|
|
4548
4548
|
function getVersionString() {
|
|
4549
4549
|
return `v${VERSION}`;
|
|
4550
4550
|
}
|
|
4551
|
-
var VERSION = "0.
|
|
4551
|
+
var VERSION = "0.20.0";
|
|
4552
4552
|
|
|
4553
4553
|
// src/debug/logger.ts
|
|
4554
4554
|
import {
|
|
@@ -6473,6 +6473,121 @@ var init_codex = __esm(() => {
|
|
|
6473
6473
|
};
|
|
6474
6474
|
});
|
|
6475
6475
|
|
|
6476
|
+
// src/hooks/factory.ts
|
|
6477
|
+
var exports_factory = {};
|
|
6478
|
+
__export(exports_factory, {
|
|
6479
|
+
removeFactoryHooks: () => removeFactoryHooks,
|
|
6480
|
+
installFactoryHooks: () => installFactoryHooks,
|
|
6481
|
+
inspectFactoryHooks: () => inspectFactoryHooks,
|
|
6482
|
+
factoryHooksPath: () => factoryHooksPath,
|
|
6483
|
+
factoryHookCommand: () => factoryHookCommand
|
|
6484
|
+
});
|
|
6485
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "node:fs";
|
|
6486
|
+
import { join as join6 } from "node:path";
|
|
6487
|
+
function factoryHooksPath(dir) {
|
|
6488
|
+
return join6(dir, ".factory", "hooks.json");
|
|
6489
|
+
}
|
|
6490
|
+
function factoryHookCommand(subcommand) {
|
|
6491
|
+
return `dosu hooks ${subcommand} --agent factory`;
|
|
6492
|
+
}
|
|
6493
|
+
function dosuGroup3(event) {
|
|
6494
|
+
const group = {
|
|
6495
|
+
hooks: [{ type: "command", command: factoryHookCommand(EVENT_SUBCOMMAND3[event]) }]
|
|
6496
|
+
};
|
|
6497
|
+
if (event === "PostToolUse")
|
|
6498
|
+
group.matcher = "*";
|
|
6499
|
+
return group;
|
|
6500
|
+
}
|
|
6501
|
+
function readHooksFileOrThrow2(path) {
|
|
6502
|
+
if (!existsSync7(path))
|
|
6503
|
+
return {};
|
|
6504
|
+
const raw = readFileSync8(path, "utf-8").trim();
|
|
6505
|
+
if (!raw)
|
|
6506
|
+
return {};
|
|
6507
|
+
try {
|
|
6508
|
+
return JSON.parse(raw);
|
|
6509
|
+
} catch {
|
|
6510
|
+
throw new Error(`refusing to modify ${path}: file exists but is not valid JSON`);
|
|
6511
|
+
}
|
|
6512
|
+
}
|
|
6513
|
+
function installFactoryHooks(configPath, opts = {}) {
|
|
6514
|
+
const config = readHooksFileOrThrow2(configPath);
|
|
6515
|
+
const events = DEFAULT_HOOK_EVENTS.filter((e2) => e2 !== "Stop" || opts.stop !== false);
|
|
6516
|
+
const hooks = typeof config.hooks === "object" && config.hooks ? config.hooks : {};
|
|
6517
|
+
for (const event of events) {
|
|
6518
|
+
const groups = Array.isArray(hooks[event]) ? hooks[event] : [];
|
|
6519
|
+
const kept = groups.filter((g2) => !isDosuGroup(g2));
|
|
6520
|
+
kept.push(dosuGroup3(event));
|
|
6521
|
+
hooks[event] = kept;
|
|
6522
|
+
}
|
|
6523
|
+
for (const event of DEFAULT_HOOK_EVENTS) {
|
|
6524
|
+
if (!events.includes(event) && Array.isArray(hooks[event])) {
|
|
6525
|
+
const kept = hooks[event].filter((g2) => !isDosuGroup(g2));
|
|
6526
|
+
if (kept.length > 0)
|
|
6527
|
+
hooks[event] = kept;
|
|
6528
|
+
else
|
|
6529
|
+
delete hooks[event];
|
|
6530
|
+
}
|
|
6531
|
+
}
|
|
6532
|
+
config.hooks = hooks;
|
|
6533
|
+
saveJSONConfig(configPath, config);
|
|
6534
|
+
return { events: [...events] };
|
|
6535
|
+
}
|
|
6536
|
+
function removeFactoryHooks(configPath) {
|
|
6537
|
+
if (!existsSync7(configPath))
|
|
6538
|
+
return { removed: false };
|
|
6539
|
+
let config;
|
|
6540
|
+
try {
|
|
6541
|
+
config = readHooksFileOrThrow2(configPath);
|
|
6542
|
+
} catch {
|
|
6543
|
+
return { removed: false };
|
|
6544
|
+
}
|
|
6545
|
+
const hooks = config.hooks;
|
|
6546
|
+
if (typeof hooks !== "object" || !hooks)
|
|
6547
|
+
return { removed: false };
|
|
6548
|
+
let removed = false;
|
|
6549
|
+
for (const event of Object.keys(hooks)) {
|
|
6550
|
+
if (!Array.isArray(hooks[event]))
|
|
6551
|
+
continue;
|
|
6552
|
+
const kept = hooks[event].filter((g2) => !isDosuGroup(g2));
|
|
6553
|
+
if (kept.length !== hooks[event].length) {
|
|
6554
|
+
removed = true;
|
|
6555
|
+
if (kept.length > 0)
|
|
6556
|
+
hooks[event] = kept;
|
|
6557
|
+
else
|
|
6558
|
+
delete hooks[event];
|
|
6559
|
+
}
|
|
6560
|
+
}
|
|
6561
|
+
if (removed)
|
|
6562
|
+
saveJSONConfig(configPath, config);
|
|
6563
|
+
return { removed };
|
|
6564
|
+
}
|
|
6565
|
+
function inspectFactoryHooks(configPath) {
|
|
6566
|
+
if (!existsSync7(configPath))
|
|
6567
|
+
return { fileExists: false, events: [] };
|
|
6568
|
+
let config;
|
|
6569
|
+
try {
|
|
6570
|
+
config = readHooksFileOrThrow2(configPath);
|
|
6571
|
+
} catch {
|
|
6572
|
+
return { fileExists: true, parseError: true, events: [] };
|
|
6573
|
+
}
|
|
6574
|
+
const hooks = config.hooks;
|
|
6575
|
+
if (typeof hooks !== "object" || !hooks)
|
|
6576
|
+
return { fileExists: true, events: [] };
|
|
6577
|
+
const events = Object.keys(hooks).filter((event) => Array.isArray(hooks[event]) && hooks[event].some((g2) => isDosuGroup(g2)));
|
|
6578
|
+
return { fileExists: true, events };
|
|
6579
|
+
}
|
|
6580
|
+
var EVENT_SUBCOMMAND3;
|
|
6581
|
+
var init_factory = __esm(() => {
|
|
6582
|
+
init_config_helpers();
|
|
6583
|
+
init_claude_code();
|
|
6584
|
+
EVENT_SUBCOMMAND3 = {
|
|
6585
|
+
UserPromptSubmit: "user-prompt-submit",
|
|
6586
|
+
PostToolUse: "post-tool-use",
|
|
6587
|
+
Stop: "stop"
|
|
6588
|
+
};
|
|
6589
|
+
});
|
|
6590
|
+
|
|
6476
6591
|
// src/insights/insights.ts
|
|
6477
6592
|
async function buildInsights({
|
|
6478
6593
|
client,
|
|
@@ -7561,17 +7676,17 @@ var init_insights2 = __esm(() => {
|
|
|
7561
7676
|
});
|
|
7562
7677
|
|
|
7563
7678
|
// src/version/skill-update-check.ts
|
|
7564
|
-
import { existsSync as
|
|
7565
|
-
import { join as
|
|
7679
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "node:fs";
|
|
7680
|
+
import { join as join7 } from "node:path";
|
|
7566
7681
|
function getCachePath() {
|
|
7567
|
-
return
|
|
7682
|
+
return join7(getConfigDir(), CACHE_FILENAME);
|
|
7568
7683
|
}
|
|
7569
7684
|
function readSkillCache() {
|
|
7570
7685
|
try {
|
|
7571
7686
|
const path = getCachePath();
|
|
7572
|
-
if (!
|
|
7687
|
+
if (!existsSync8(path))
|
|
7573
7688
|
return null;
|
|
7574
|
-
const data = JSON.parse(
|
|
7689
|
+
const data = JSON.parse(readFileSync10(path, "utf-8"));
|
|
7575
7690
|
if (typeof data.lastCheck === "number" && typeof data.latestSha === "string" && typeof data.installedSha === "string") {
|
|
7576
7691
|
return data;
|
|
7577
7692
|
}
|
|
@@ -7583,7 +7698,7 @@ function readSkillCache() {
|
|
|
7583
7698
|
function writeSkillCache(cache) {
|
|
7584
7699
|
try {
|
|
7585
7700
|
const dir = getConfigDir();
|
|
7586
|
-
if (!
|
|
7701
|
+
if (!existsSync8(dir)) {
|
|
7587
7702
|
mkdirSync5(dir, { recursive: true, mode: 448 });
|
|
7588
7703
|
}
|
|
7589
7704
|
writeFileSync4(getCachePath(), JSON.stringify(cache), { mode: 384 });
|
|
@@ -7760,21 +7875,21 @@ var init_skill = __esm(() => {
|
|
|
7760
7875
|
var MCP_PROVIDER_SLUG = "dosu_mcp";
|
|
7761
7876
|
|
|
7762
7877
|
// src/mcp/detect.ts
|
|
7763
|
-
import { existsSync as
|
|
7878
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
7764
7879
|
import { homedir, platform } from "node:os";
|
|
7765
|
-
import { join as
|
|
7880
|
+
import { join as join8 } from "node:path";
|
|
7766
7881
|
function isInstalled(paths) {
|
|
7767
|
-
return paths.some((p2) =>
|
|
7882
|
+
return paths.some((p2) => existsSync9(expandHome(p2)));
|
|
7768
7883
|
}
|
|
7769
7884
|
function expandHome(path) {
|
|
7770
7885
|
if (!path.startsWith("~"))
|
|
7771
7886
|
return path;
|
|
7772
|
-
return
|
|
7887
|
+
return join8(homedir(), path.slice(1));
|
|
7773
7888
|
}
|
|
7774
7889
|
function appSupportDir() {
|
|
7775
7890
|
switch (platform()) {
|
|
7776
7891
|
case "darwin": {
|
|
7777
|
-
return
|
|
7892
|
+
return join8(homedir(), "Library", "Application Support");
|
|
7778
7893
|
}
|
|
7779
7894
|
case "win32": {
|
|
7780
7895
|
return process.env.APPDATA ?? "";
|
|
@@ -7783,7 +7898,7 @@ function appSupportDir() {
|
|
|
7783
7898
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
7784
7899
|
if (xdg)
|
|
7785
7900
|
return xdg;
|
|
7786
|
-
return
|
|
7901
|
+
return join8(homedir(), ".config");
|
|
7787
7902
|
}
|
|
7788
7903
|
}
|
|
7789
7904
|
}
|
|
@@ -7864,7 +7979,7 @@ var init_antigravity = __esm(() => {
|
|
|
7864
7979
|
});
|
|
7865
7980
|
|
|
7866
7981
|
// src/mcp/providers/claude.ts
|
|
7867
|
-
import { join as
|
|
7982
|
+
import { join as join9 } from "node:path";
|
|
7868
7983
|
var ClaudeProvider = () => createJSONProvider({
|
|
7869
7984
|
providerName: "Claude Code",
|
|
7870
7985
|
providerID: "claude",
|
|
@@ -7873,22 +7988,22 @@ var ClaudeProvider = () => createJSONProvider({
|
|
|
7873
7988
|
paths: ["~/.claude"],
|
|
7874
7989
|
globalPath: "~/.claude.json",
|
|
7875
7990
|
topKey: "mcpServers",
|
|
7876
|
-
localConfigPath: (cwd) =>
|
|
7991
|
+
localConfigPath: (cwd) => join9(cwd, ".mcp.json")
|
|
7877
7992
|
});
|
|
7878
7993
|
var init_claude = __esm(() => {
|
|
7879
7994
|
init_base();
|
|
7880
7995
|
});
|
|
7881
7996
|
|
|
7882
7997
|
// src/mcp/providers/claude-desktop.ts
|
|
7883
|
-
import { join as
|
|
7998
|
+
import { join as join10 } from "node:path";
|
|
7884
7999
|
var ClaudeDesktopProvider = () => ({
|
|
7885
8000
|
name: () => "Claude Desktop",
|
|
7886
8001
|
id: () => "claude-desktop",
|
|
7887
8002
|
supportsLocal: () => false,
|
|
7888
8003
|
priority: () => 2,
|
|
7889
|
-
detectPaths: () => [
|
|
7890
|
-
isInstalled: () => isInstalled([
|
|
7891
|
-
globalConfigPath: () =>
|
|
8004
|
+
detectPaths: () => [join10(appSupportDir(), "Claude")],
|
|
8005
|
+
isInstalled: () => isInstalled([join10(appSupportDir(), "Claude")]),
|
|
8006
|
+
globalConfigPath: () => join10(appSupportDir(), "Claude", "claude_desktop_config.json"),
|
|
7892
8007
|
isConfigured: () => false,
|
|
7893
8008
|
install() {
|
|
7894
8009
|
throw new Error("this tool only supports local (stdio) servers and cannot be configured for remote MCP");
|
|
@@ -7902,14 +8017,14 @@ var init_claude_desktop = __esm(() => {
|
|
|
7902
8017
|
});
|
|
7903
8018
|
|
|
7904
8019
|
// src/mcp/providers/cline.ts
|
|
7905
|
-
import { join as
|
|
7906
|
-
var extensionDir = () =>
|
|
8020
|
+
import { join as join11 } from "node:path";
|
|
8021
|
+
var extensionDir = () => join11(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
|
|
7907
8022
|
providerName: "Cline",
|
|
7908
8023
|
providerID: "cline",
|
|
7909
8024
|
local: false,
|
|
7910
8025
|
priorityValue: 11,
|
|
7911
8026
|
paths: [extensionDir()],
|
|
7912
|
-
globalPath:
|
|
8027
|
+
globalPath: join11(extensionDir(), "settings", "cline_mcp_settings.json"),
|
|
7913
8028
|
topKey: "mcpServers",
|
|
7914
8029
|
buildServer: (cfg) => ({
|
|
7915
8030
|
url: mcpURL(cfg.deployment_id),
|
|
@@ -7925,7 +8040,7 @@ var init_cline = __esm(() => {
|
|
|
7925
8040
|
});
|
|
7926
8041
|
|
|
7927
8042
|
// src/mcp/providers/cline-cli.ts
|
|
7928
|
-
import { join as
|
|
8043
|
+
import { join as join12 } from "node:path";
|
|
7929
8044
|
function clineDir() {
|
|
7930
8045
|
return process.env.CLINE_DIR ?? expandHome("~/.cline");
|
|
7931
8046
|
}
|
|
@@ -7935,7 +8050,7 @@ var ClineCliProvider = () => createJSONProvider({
|
|
|
7935
8050
|
local: false,
|
|
7936
8051
|
priorityValue: 12,
|
|
7937
8052
|
paths: [clineDir()],
|
|
7938
|
-
globalPath:
|
|
8053
|
+
globalPath: join12(clineDir(), "data", "settings", "cline_mcp_settings.json"),
|
|
7939
8054
|
topKey: "mcpServers",
|
|
7940
8055
|
buildServer: (cfg) => ({
|
|
7941
8056
|
url: mcpURL(cfg.deployment_id),
|
|
@@ -7951,20 +8066,20 @@ var init_cline_cli = __esm(() => {
|
|
|
7951
8066
|
});
|
|
7952
8067
|
|
|
7953
8068
|
// src/mcp/providers/codex.ts
|
|
7954
|
-
import { existsSync as
|
|
7955
|
-
import { join as
|
|
8069
|
+
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
|
|
8070
|
+
import { join as join13 } from "node:path";
|
|
7956
8071
|
function codexHome() {
|
|
7957
8072
|
return process.env.CODEX_HOME ?? expandHome("~/.codex");
|
|
7958
8073
|
}
|
|
7959
8074
|
function getConfigPath2(global) {
|
|
7960
8075
|
if (global)
|
|
7961
|
-
return
|
|
7962
|
-
return
|
|
8076
|
+
return join13(codexHome(), "config.toml");
|
|
8077
|
+
return join13(process.cwd(), ".codex", "config.toml");
|
|
7963
8078
|
}
|
|
7964
8079
|
function readTOML(path) {
|
|
7965
|
-
if (!
|
|
8080
|
+
if (!existsSync10(path))
|
|
7966
8081
|
return "";
|
|
7967
|
-
return
|
|
8082
|
+
return readFileSync11(path, "utf-8");
|
|
7968
8083
|
}
|
|
7969
8084
|
function writeTOML(path, content) {
|
|
7970
8085
|
writeSecureFile(path, content);
|
|
@@ -8022,9 +8137,9 @@ var CodexProvider = () => ({
|
|
|
8022
8137
|
priority: () => 8,
|
|
8023
8138
|
detectPaths: () => ["~/.codex"],
|
|
8024
8139
|
isInstalled: () => isInstalled(["~/.codex"]),
|
|
8025
|
-
globalConfigPath: () =>
|
|
8140
|
+
globalConfigPath: () => join13(codexHome(), "config.toml"),
|
|
8026
8141
|
isConfigured: () => {
|
|
8027
|
-
const content = readTOML(
|
|
8142
|
+
const content = readTOML(join13(codexHome(), "config.toml"));
|
|
8028
8143
|
return content.includes("[mcp_servers.dosu]");
|
|
8029
8144
|
},
|
|
8030
8145
|
install(cfg, global) {
|
|
@@ -8046,10 +8161,10 @@ var init_codex2 = __esm(() => {
|
|
|
8046
8161
|
});
|
|
8047
8162
|
|
|
8048
8163
|
// src/mcp/providers/copilot.ts
|
|
8049
|
-
import { join as
|
|
8164
|
+
import { join as join14 } from "node:path";
|
|
8050
8165
|
function globalPath() {
|
|
8051
8166
|
if (process.env.XDG_CONFIG_HOME) {
|
|
8052
|
-
return
|
|
8167
|
+
return join14(process.env.XDG_CONFIG_HOME, "mcp-config.json");
|
|
8053
8168
|
}
|
|
8054
8169
|
return expandHome("~/.copilot/mcp-config.json");
|
|
8055
8170
|
}
|
|
@@ -8080,7 +8195,7 @@ var CopilotProvider = () => ({
|
|
|
8080
8195
|
};
|
|
8081
8196
|
installJSONServer(globalPath(), "mcpServers", server);
|
|
8082
8197
|
} else {
|
|
8083
|
-
const configPath =
|
|
8198
|
+
const configPath = join14(process.cwd(), ".vscode", "mcp.json");
|
|
8084
8199
|
const server = {
|
|
8085
8200
|
type: "http",
|
|
8086
8201
|
url,
|
|
@@ -8093,7 +8208,7 @@ var CopilotProvider = () => ({
|
|
|
8093
8208
|
if (global) {
|
|
8094
8209
|
removeJSONServer(globalPath(), "mcpServers");
|
|
8095
8210
|
} else {
|
|
8096
|
-
const configPath =
|
|
8211
|
+
const configPath = join14(process.cwd(), ".vscode", "mcp.json");
|
|
8097
8212
|
removeJSONServer(configPath, "servers");
|
|
8098
8213
|
}
|
|
8099
8214
|
}
|
|
@@ -8105,7 +8220,7 @@ var init_copilot = __esm(() => {
|
|
|
8105
8220
|
});
|
|
8106
8221
|
|
|
8107
8222
|
// src/mcp/providers/cursor.ts
|
|
8108
|
-
import { join as
|
|
8223
|
+
import { join as join15 } from "node:path";
|
|
8109
8224
|
var CursorProvider = () => createJSONProvider({
|
|
8110
8225
|
providerName: "Cursor",
|
|
8111
8226
|
providerID: "cursor",
|
|
@@ -8118,15 +8233,31 @@ var CursorProvider = () => createJSONProvider({
|
|
|
8118
8233
|
url: mcpURL(cfg.deployment_id),
|
|
8119
8234
|
headers: mcpHeaders(cfg.api_key)
|
|
8120
8235
|
}),
|
|
8121
|
-
localConfigPath: (cwd) =>
|
|
8236
|
+
localConfigPath: (cwd) => join15(cwd, ".cursor", "mcp.json")
|
|
8122
8237
|
});
|
|
8123
8238
|
var init_cursor = __esm(() => {
|
|
8124
8239
|
init_config_helpers();
|
|
8125
8240
|
init_base();
|
|
8126
8241
|
});
|
|
8127
8242
|
|
|
8243
|
+
// src/mcp/providers/factory.ts
|
|
8244
|
+
import { join as join16 } from "node:path";
|
|
8245
|
+
var FactoryProvider = () => createJSONProvider({
|
|
8246
|
+
providerName: "Factory",
|
|
8247
|
+
providerID: "factory",
|
|
8248
|
+
local: true,
|
|
8249
|
+
priorityValue: 17,
|
|
8250
|
+
paths: ["~/.factory"],
|
|
8251
|
+
globalPath: "~/.factory/mcp.json",
|
|
8252
|
+
topKey: "mcpServers",
|
|
8253
|
+
localConfigPath: (cwd) => join16(cwd, ".factory", "mcp.json")
|
|
8254
|
+
});
|
|
8255
|
+
var init_factory2 = __esm(() => {
|
|
8256
|
+
init_base();
|
|
8257
|
+
});
|
|
8258
|
+
|
|
8128
8259
|
// src/mcp/providers/gemini.ts
|
|
8129
|
-
import { join as
|
|
8260
|
+
import { join as join17 } from "node:path";
|
|
8130
8261
|
var GeminiProvider = () => createJSONProvider({
|
|
8131
8262
|
providerName: "Gemini CLI",
|
|
8132
8263
|
providerID: "gemini",
|
|
@@ -8135,7 +8266,7 @@ var GeminiProvider = () => createJSONProvider({
|
|
|
8135
8266
|
paths: ["~/.gemini"],
|
|
8136
8267
|
globalPath: "~/.gemini/settings.json",
|
|
8137
8268
|
topKey: "mcpServers",
|
|
8138
|
-
localConfigPath: (cwd) =>
|
|
8269
|
+
localConfigPath: (cwd) => join17(cwd, ".gemini", "settings.json")
|
|
8139
8270
|
});
|
|
8140
8271
|
var init_gemini = __esm(() => {
|
|
8141
8272
|
init_base();
|
|
@@ -8185,14 +8316,14 @@ var init_manual = __esm(() => {
|
|
|
8185
8316
|
});
|
|
8186
8317
|
|
|
8187
8318
|
// src/mcp/providers/mcporter.ts
|
|
8188
|
-
import { existsSync as
|
|
8189
|
-
import { join as
|
|
8319
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
8320
|
+
import { join as join18 } from "node:path";
|
|
8190
8321
|
function resolveGlobalConfigPath() {
|
|
8191
8322
|
const jsonPath = expandHome("~/.mcporter/mcporter.json");
|
|
8192
|
-
if (
|
|
8323
|
+
if (existsSync11(jsonPath))
|
|
8193
8324
|
return jsonPath;
|
|
8194
8325
|
const jsoncPath = expandHome("~/.mcporter/mcporter.jsonc");
|
|
8195
|
-
if (
|
|
8326
|
+
if (existsSync11(jsoncPath))
|
|
8196
8327
|
return jsoncPath;
|
|
8197
8328
|
return jsonPath;
|
|
8198
8329
|
}
|
|
@@ -8213,7 +8344,7 @@ var MCPorterProvider = () => ({
|
|
|
8213
8344
|
globalConfigPath: () => resolveGlobalConfigPath(),
|
|
8214
8345
|
isConfigured: () => isJSONKeyConfigured(resolveGlobalConfigPath(), "mcpServers"),
|
|
8215
8346
|
install(cfg, global) {
|
|
8216
|
-
const configPath = global ? resolveGlobalConfigPath() :
|
|
8347
|
+
const configPath = global ? resolveGlobalConfigPath() : join18(process.cwd(), "config", "mcporter.json");
|
|
8217
8348
|
const server = {
|
|
8218
8349
|
type: "http",
|
|
8219
8350
|
url: mcpEndpoint4(cfg),
|
|
@@ -8222,7 +8353,7 @@ var MCPorterProvider = () => ({
|
|
|
8222
8353
|
installJSONServer(configPath, "mcpServers", server);
|
|
8223
8354
|
},
|
|
8224
8355
|
remove(global) {
|
|
8225
|
-
const configPath = global ? resolveGlobalConfigPath() :
|
|
8356
|
+
const configPath = global ? resolveGlobalConfigPath() : join18(process.cwd(), "config", "mcporter.json");
|
|
8226
8357
|
removeJSONServer(configPath, "mcpServers");
|
|
8227
8358
|
}
|
|
8228
8359
|
});
|
|
@@ -8233,7 +8364,7 @@ var init_mcporter = __esm(() => {
|
|
|
8233
8364
|
});
|
|
8234
8365
|
|
|
8235
8366
|
// src/mcp/providers/opencode.ts
|
|
8236
|
-
import { join as
|
|
8367
|
+
import { join as join19 } from "node:path";
|
|
8237
8368
|
var OpenCodeProvider = () => createJSONProvider({
|
|
8238
8369
|
providerName: "OpenCode",
|
|
8239
8370
|
providerID: "opencode",
|
|
@@ -8248,7 +8379,7 @@ var OpenCodeProvider = () => createJSONProvider({
|
|
|
8248
8379
|
enabled: true,
|
|
8249
8380
|
headers: mcpHeaders(cfg.api_key)
|
|
8250
8381
|
}),
|
|
8251
|
-
localConfigPath: (cwd) =>
|
|
8382
|
+
localConfigPath: (cwd) => join19(cwd, "opencode.json")
|
|
8252
8383
|
});
|
|
8253
8384
|
var init_opencode = __esm(() => {
|
|
8254
8385
|
init_config_helpers();
|
|
@@ -8256,16 +8387,16 @@ var init_opencode = __esm(() => {
|
|
|
8256
8387
|
});
|
|
8257
8388
|
|
|
8258
8389
|
// src/mcp/providers/vscode.ts
|
|
8259
|
-
import { join as
|
|
8390
|
+
import { join as join20 } from "node:path";
|
|
8260
8391
|
var VSCodeProvider = () => createJSONProvider({
|
|
8261
8392
|
providerName: "VS Code",
|
|
8262
8393
|
providerID: "vscode",
|
|
8263
8394
|
local: true,
|
|
8264
8395
|
priorityValue: 6,
|
|
8265
|
-
paths: [
|
|
8266
|
-
globalPath:
|
|
8396
|
+
paths: [join20(appSupportDir(), "Code")],
|
|
8397
|
+
globalPath: join20(appSupportDir(), "Code", "User", "mcp.json"),
|
|
8267
8398
|
topKey: "servers",
|
|
8268
|
-
localConfigPath: (cwd) =>
|
|
8399
|
+
localConfigPath: (cwd) => join20(cwd, ".vscode", "mcp.json")
|
|
8269
8400
|
});
|
|
8270
8401
|
var init_vscode = __esm(() => {
|
|
8271
8402
|
init_detect();
|
|
@@ -8274,14 +8405,14 @@ var init_vscode = __esm(() => {
|
|
|
8274
8405
|
|
|
8275
8406
|
// src/mcp/providers/windsurf.ts
|
|
8276
8407
|
import { homedir as homedir2 } from "node:os";
|
|
8277
|
-
import { join as
|
|
8408
|
+
import { join as join21 } from "node:path";
|
|
8278
8409
|
var WindsurfProvider = () => createJSONProvider({
|
|
8279
8410
|
providerName: "Windsurf",
|
|
8280
8411
|
providerID: "windsurf",
|
|
8281
8412
|
local: false,
|
|
8282
8413
|
priorityValue: 9,
|
|
8283
|
-
paths: [
|
|
8284
|
-
globalPath:
|
|
8414
|
+
paths: [join21(homedir2(), ".codeium", "windsurf")],
|
|
8415
|
+
globalPath: join21(homedir2(), ".codeium", "windsurf", "mcp_config.json"),
|
|
8285
8416
|
topKey: "mcpServers"
|
|
8286
8417
|
});
|
|
8287
8418
|
var init_windsurf = __esm(() => {
|
|
@@ -8290,12 +8421,12 @@ var init_windsurf = __esm(() => {
|
|
|
8290
8421
|
|
|
8291
8422
|
// src/mcp/providers/zed.ts
|
|
8292
8423
|
import { platform as platform2 } from "node:os";
|
|
8293
|
-
import { join as
|
|
8424
|
+
import { join as join22 } from "node:path";
|
|
8294
8425
|
function zedConfigDir() {
|
|
8295
8426
|
const os = platform2();
|
|
8296
8427
|
if (os === "darwin" || os === "win32")
|
|
8297
|
-
return
|
|
8298
|
-
return
|
|
8428
|
+
return join22(appSupportDir(), "Zed");
|
|
8429
|
+
return join22(appSupportDir(), "zed");
|
|
8299
8430
|
}
|
|
8300
8431
|
var ZedProvider = () => createJSONProvider({
|
|
8301
8432
|
providerName: "Zed",
|
|
@@ -8303,7 +8434,7 @@ var ZedProvider = () => createJSONProvider({
|
|
|
8303
8434
|
local: true,
|
|
8304
8435
|
priorityValue: 10,
|
|
8305
8436
|
paths: [zedConfigDir()],
|
|
8306
|
-
globalPath:
|
|
8437
|
+
globalPath: join22(zedConfigDir(), "settings.json"),
|
|
8307
8438
|
topKey: "context_servers",
|
|
8308
8439
|
buildServer: (cfg) => ({
|
|
8309
8440
|
source: "custom",
|
|
@@ -8311,7 +8442,7 @@ var ZedProvider = () => createJSONProvider({
|
|
|
8311
8442
|
url: mcpURL(cfg.deployment_id),
|
|
8312
8443
|
headers: mcpHeaders(cfg.api_key)
|
|
8313
8444
|
}),
|
|
8314
|
-
localConfigPath: (cwd) =>
|
|
8445
|
+
localConfigPath: (cwd) => join22(cwd, ".zed", "settings.json")
|
|
8315
8446
|
});
|
|
8316
8447
|
var init_zed = __esm(() => {
|
|
8317
8448
|
init_config_helpers();
|
|
@@ -8336,6 +8467,7 @@ function allProviders() {
|
|
|
8336
8467
|
OpenCodeProvider(),
|
|
8337
8468
|
AntigravityProvider(),
|
|
8338
8469
|
MCPorterProvider(),
|
|
8470
|
+
FactoryProvider(),
|
|
8339
8471
|
ManualProvider()
|
|
8340
8472
|
];
|
|
8341
8473
|
}
|
|
@@ -8358,6 +8490,7 @@ var init_providers = __esm(() => {
|
|
|
8358
8490
|
init_codex2();
|
|
8359
8491
|
init_copilot();
|
|
8360
8492
|
init_cursor();
|
|
8493
|
+
init_factory2();
|
|
8361
8494
|
init_gemini();
|
|
8362
8495
|
init_manual();
|
|
8363
8496
|
init_mcporter();
|
|
@@ -10904,8 +11037,8 @@ __export(exports_flow2, {
|
|
|
10904
11037
|
isStdioOnly: () => isStdioOnly
|
|
10905
11038
|
});
|
|
10906
11039
|
import { randomUUID } from "node:crypto";
|
|
10907
|
-
import { existsSync as
|
|
10908
|
-
import { join as
|
|
11040
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
11041
|
+
import { join as join23 } from "node:path";
|
|
10909
11042
|
async function runSetup(opts = {}) {
|
|
10910
11043
|
const onboardingRunID = randomUUID();
|
|
10911
11044
|
logger.info("setup", `Setup flow started${opts.deploymentID ? ` deployment=${opts.deploymentID}` : ""}${opts.mode ? ` mode=${opts.mode}` : ""}`);
|
|
@@ -11077,7 +11210,7 @@ async function runSetup(opts = {}) {
|
|
|
11077
11210
|
showTryItOutPrompt({
|
|
11078
11211
|
mode: cfg.mode,
|
|
11079
11212
|
docsImported: choices.connectGitHub && githubOnboardingDone,
|
|
11080
|
-
hasAgentsMd:
|
|
11213
|
+
hasAgentsMd: existsSync12(join23(process.cwd(), "AGENTS.md"))
|
|
11081
11214
|
});
|
|
11082
11215
|
}
|
|
11083
11216
|
if (mcpCompleted || skillCompleted || docsImported) {
|
|
@@ -11571,8 +11704,8 @@ var init_flow2 = __esm(() => {
|
|
|
11571
11704
|
});
|
|
11572
11705
|
|
|
11573
11706
|
// src/commands/insights.ts
|
|
11574
|
-
import { existsSync as
|
|
11575
|
-
import { dirname as dirname3, join as
|
|
11707
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync6, readdirSync, unlinkSync, writeFileSync as writeFileSync5 } from "node:fs";
|
|
11708
|
+
import { dirname as dirname3, join as join24 } from "node:path";
|
|
11576
11709
|
function shuffled(arr) {
|
|
11577
11710
|
const copy2 = [...arr];
|
|
11578
11711
|
for (let i = copy2.length - 1;i > 0; i--) {
|
|
@@ -11676,17 +11809,17 @@ function makeAskFn(cfg) {
|
|
|
11676
11809
|
};
|
|
11677
11810
|
}
|
|
11678
11811
|
function insightsDir() {
|
|
11679
|
-
return
|
|
11812
|
+
return join24(getConfigDir(), "insights");
|
|
11680
11813
|
}
|
|
11681
11814
|
function reportPath(timestamp) {
|
|
11682
11815
|
const dir = insightsDir();
|
|
11683
11816
|
if (!timestamp)
|
|
11684
|
-
return
|
|
11817
|
+
return join24(dir, "latest.html");
|
|
11685
11818
|
const iso = timestamp.toISOString().slice(0, 19).replace(/:/g, "-");
|
|
11686
|
-
return
|
|
11819
|
+
return join24(dir, `report-${iso}Z.html`);
|
|
11687
11820
|
}
|
|
11688
11821
|
function pruneOldReports(dir, keepN) {
|
|
11689
|
-
if (!
|
|
11822
|
+
if (!existsSync13(dir))
|
|
11690
11823
|
return;
|
|
11691
11824
|
let entries;
|
|
11692
11825
|
try {
|
|
@@ -11698,7 +11831,7 @@ function pruneOldReports(dir, keepN) {
|
|
|
11698
11831
|
const reports = entries.filter((f) => REPORT_FILE_PATTERN.test(f)).sort().reverse();
|
|
11699
11832
|
for (const f of reports.slice(keepN)) {
|
|
11700
11833
|
try {
|
|
11701
|
-
unlinkSync(
|
|
11834
|
+
unlinkSync(join24(dir, f));
|
|
11702
11835
|
} catch (err) {
|
|
11703
11836
|
logger.debug("insights", `failed to prune ${f}: ${err instanceof Error ? err.message : err}`);
|
|
11704
11837
|
}
|
|
@@ -11771,7 +11904,7 @@ function defaultRunner(cfg) {
|
|
|
11771
11904
|
render: renderHTML,
|
|
11772
11905
|
writeFile: (path2, content) => {
|
|
11773
11906
|
const dir = dirname3(path2);
|
|
11774
|
-
if (!
|
|
11907
|
+
if (!existsSync13(dir))
|
|
11775
11908
|
mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
11776
11909
|
writeFileSync5(path2, content, { mode: 384 });
|
|
11777
11910
|
},
|
|
@@ -12436,7 +12569,7 @@ var init_flow3 = __esm(() => {
|
|
|
12436
12569
|
// src/cli/cli.ts
|
|
12437
12570
|
init_esm();
|
|
12438
12571
|
init_client();
|
|
12439
|
-
import { readFileSync as
|
|
12572
|
+
import { readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
|
|
12440
12573
|
|
|
12441
12574
|
// src/commands/analytics.ts
|
|
12442
12575
|
init_esm();
|
|
@@ -13122,7 +13255,7 @@ init_esm();
|
|
|
13122
13255
|
init_config();
|
|
13123
13256
|
init_logger();
|
|
13124
13257
|
init_prompts();
|
|
13125
|
-
import { readFileSync as
|
|
13258
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
13126
13259
|
import { basename } from "node:path";
|
|
13127
13260
|
|
|
13128
13261
|
// src/hooks/state.ts
|
|
@@ -13161,7 +13294,7 @@ var COOLDOWN_DEFAULT_MS = 3000;
|
|
|
13161
13294
|
var TTL_DEFAULT_MS = 10 * 60 * 1000;
|
|
13162
13295
|
var STOP_WAIT_DEFAULT_MS = 8000;
|
|
13163
13296
|
var STOP_POLL_DEFAULT_MS = 1000;
|
|
13164
|
-
var SUPPORTED_AGENTS = ["claude-code", "codex"];
|
|
13297
|
+
var SUPPORTED_AGENTS = ["claude-code", "codex", "factory"];
|
|
13165
13298
|
var DEFAULT_AGENT = "claude-code";
|
|
13166
13299
|
function cooldownMs() {
|
|
13167
13300
|
const n = Number.parseInt(process.env.DOSU_HOOK_CHECK_COOLDOWN_MS ?? "", 10);
|
|
@@ -13391,7 +13524,7 @@ async function runHookEntrypoint(event, raw, now = Date.now(), agent = DEFAULT_A
|
|
|
13391
13524
|
}
|
|
13392
13525
|
function readStdinRaw() {
|
|
13393
13526
|
try {
|
|
13394
|
-
return
|
|
13527
|
+
return readFileSync9(0, "utf8");
|
|
13395
13528
|
} catch {
|
|
13396
13529
|
return "";
|
|
13397
13530
|
}
|
|
@@ -13439,6 +13572,20 @@ async function runInstall(agent, opts) {
|
|
|
13439
13572
|
}
|
|
13440
13573
|
return;
|
|
13441
13574
|
}
|
|
13575
|
+
if (agent === "factory") {
|
|
13576
|
+
const { installFactoryHooks: installFactoryHooks2, factoryHooksPath: factoryHooksPath2 } = await Promise.resolve().then(() => (init_factory(), exports_factory));
|
|
13577
|
+
const configPath2 = factoryHooksPath2(resolveDir(opts.dir));
|
|
13578
|
+
const { events: events2 } = installFactoryHooks2(configPath2, { stop: opts.stop });
|
|
13579
|
+
if (opts.json) {
|
|
13580
|
+
const { emitStep: emitStep2 } = await Promise.resolve().then(() => exports_output);
|
|
13581
|
+
emitStep2({ step: "hooks-install", agent, path: configPath2, events: events2 });
|
|
13582
|
+
} else {
|
|
13583
|
+
console.log(`✓ Installed Dosu hooks for Factory (${events2.join(", ")}).`);
|
|
13584
|
+
console.log(` → ${configPath2}`);
|
|
13585
|
+
console.log(" Start a new Factory session in this project to use them.");
|
|
13586
|
+
}
|
|
13587
|
+
return;
|
|
13588
|
+
}
|
|
13442
13589
|
const { installClaudeHooks: installClaudeHooks2, claudeLocalSettingsPath: claudeLocalSettingsPath2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
|
|
13443
13590
|
const configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
|
|
13444
13591
|
const { events } = installClaudeHooks2(configPath, { stop: opts.stop });
|
|
@@ -13476,6 +13623,10 @@ async function runUninstall(agent, opts) {
|
|
|
13476
13623
|
const { removeCodexHooks: removeCodexHooks2, codexHooksPath: codexHooksPath2 } = await Promise.resolve().then(() => (init_codex(), exports_codex));
|
|
13477
13624
|
configPath = codexHooksPath2(resolveDir(opts.dir));
|
|
13478
13625
|
({ removed } = removeCodexHooks2(configPath));
|
|
13626
|
+
} else if (agent === "factory") {
|
|
13627
|
+
const { removeFactoryHooks: removeFactoryHooks2, factoryHooksPath: factoryHooksPath2 } = await Promise.resolve().then(() => (init_factory(), exports_factory));
|
|
13628
|
+
configPath = factoryHooksPath2(resolveDir(opts.dir));
|
|
13629
|
+
({ removed } = removeFactoryHooks2(configPath));
|
|
13479
13630
|
} else {
|
|
13480
13631
|
const { removeClaudeHooks: removeClaudeHooks2, claudeLocalSettingsPath: claudeLocalSettingsPath2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
|
|
13481
13632
|
configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
|
|
@@ -13494,15 +13645,20 @@ async function collectDoctorChecks(opts) {
|
|
|
13494
13645
|
const checks = [];
|
|
13495
13646
|
const { claudeLocalSettingsPath: claudeLocalSettingsPath2, inspectClaudeHooks: inspectClaudeHooks2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
|
|
13496
13647
|
const { codexHooksPath: codexHooksPath2, inspectCodexHooks: inspectCodexHooks2 } = await Promise.resolve().then(() => (init_codex(), exports_codex));
|
|
13648
|
+
const { factoryHooksPath: factoryHooksPath2, inspectFactoryHooks: inspectFactoryHooks2 } = await Promise.resolve().then(() => (init_factory(), exports_factory));
|
|
13497
13649
|
const configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
|
|
13498
13650
|
const inspection = inspectClaudeHooks2(configPath);
|
|
13499
13651
|
const codexPath = codexHooksPath2(resolveDir(opts.dir));
|
|
13500
13652
|
const codex = inspectCodexHooks2(codexPath);
|
|
13653
|
+
const factoryPath = factoryHooksPath2(resolveDir(opts.dir));
|
|
13654
|
+
const factory = inspectFactoryHooks2(factoryPath);
|
|
13501
13655
|
const codexInstalled = codex.events.includes("UserPromptSubmit") && codex.events.includes("PostToolUse");
|
|
13656
|
+
const factoryInstalled = factory.events.includes("UserPromptSubmit") && factory.events.includes("PostToolUse");
|
|
13657
|
+
const alternativeInstalled = codexInstalled || factoryInstalled;
|
|
13502
13658
|
if (!inspection.fileExists) {
|
|
13503
13659
|
checks.push({
|
|
13504
13660
|
name: "config",
|
|
13505
|
-
status:
|
|
13661
|
+
status: alternativeInstalled ? "warn" : "fail",
|
|
13506
13662
|
detail: `not found: ${configPath} (run 'dosu hooks install claude-code')`
|
|
13507
13663
|
});
|
|
13508
13664
|
} else if (inspection.parseError) {
|
|
@@ -13521,7 +13677,7 @@ async function collectDoctorChecks(opts) {
|
|
|
13521
13677
|
} else {
|
|
13522
13678
|
checks.push({
|
|
13523
13679
|
name: "hooks",
|
|
13524
|
-
status:
|
|
13680
|
+
status: alternativeInstalled ? "warn" : "fail",
|
|
13525
13681
|
detail: "UserPromptSubmit + PostToolUse not both installed"
|
|
13526
13682
|
});
|
|
13527
13683
|
}
|
|
@@ -13547,6 +13703,27 @@ async function collectDoctorChecks(opts) {
|
|
|
13547
13703
|
});
|
|
13548
13704
|
}
|
|
13549
13705
|
}
|
|
13706
|
+
if (factory.fileExists) {
|
|
13707
|
+
if (factory.parseError) {
|
|
13708
|
+
checks.push({
|
|
13709
|
+
name: "factory-config",
|
|
13710
|
+
status: "fail",
|
|
13711
|
+
detail: `invalid JSON: ${factoryPath}`
|
|
13712
|
+
});
|
|
13713
|
+
} else if (factoryInstalled) {
|
|
13714
|
+
checks.push({
|
|
13715
|
+
name: "factory-config",
|
|
13716
|
+
status: "ok",
|
|
13717
|
+
detail: `installed: ${factory.events.join(", ")} (${factoryPath})`
|
|
13718
|
+
});
|
|
13719
|
+
} else {
|
|
13720
|
+
checks.push({
|
|
13721
|
+
name: "factory-config",
|
|
13722
|
+
status: "fail",
|
|
13723
|
+
detail: "UserPromptSubmit + PostToolUse not both installed"
|
|
13724
|
+
});
|
|
13725
|
+
}
|
|
13726
|
+
}
|
|
13550
13727
|
const cfg = loadConfig();
|
|
13551
13728
|
if (isAuthenticated(cfg)) {
|
|
13552
13729
|
checks.push({ name: "auth", status: "ok", detail: "logged in" });
|
|
@@ -13601,7 +13778,7 @@ async function runDoctor(opts) {
|
|
|
13601
13778
|
}
|
|
13602
13779
|
}
|
|
13603
13780
|
function hooksCommand() {
|
|
13604
|
-
const cmd = new Command("hooks").description("Dosu knowledge-injection hooks for coding agents (Claude Code, Codex)");
|
|
13781
|
+
const cmd = new Command("hooks").description("Dosu knowledge-injection hooks for coding agents (Claude Code, Codex, Factory)");
|
|
13605
13782
|
cmd.command("user-prompt-submit").description("Hook entrypoint: create a knowledge ticket on prompt submit").option("--agent <agent>", "Calling agent for ticket attribution", DEFAULT_AGENT).action(async (opts) => {
|
|
13606
13783
|
await runHookEntrypoint("user-prompt-submit", readStdinRaw(), Date.now(), opts.agent);
|
|
13607
13784
|
});
|
|
@@ -13628,6 +13805,7 @@ function hooksCommand() {
|
|
|
13628
13805
|
"Examples:",
|
|
13629
13806
|
" $ dosu hooks install claude-code",
|
|
13630
13807
|
" $ dosu hooks install codex",
|
|
13808
|
+
" $ dosu hooks install factory",
|
|
13631
13809
|
" $ dosu hooks install claude-code --no-stop",
|
|
13632
13810
|
" $ dosu hooks install codex --dir ./my-project",
|
|
13633
13811
|
"",
|
|
@@ -13641,7 +13819,8 @@ function hooksCommand() {
|
|
|
13641
13819
|
"",
|
|
13642
13820
|
"Examples:",
|
|
13643
13821
|
" $ dosu hooks uninstall claude-code",
|
|
13644
|
-
" $ dosu hooks uninstall codex"
|
|
13822
|
+
" $ dosu hooks uninstall codex",
|
|
13823
|
+
" $ dosu hooks uninstall factory"
|
|
13645
13824
|
].join(`
|
|
13646
13825
|
`)).action((agent, opts) => runUninstall(agent, opts));
|
|
13647
13826
|
cmd.command("doctor").description("Diagnose Dosu hook config, auth, deployment, and backend connectivity").option("--dir <path>", "Project root (defaults to current directory)").option("--json", "Emit machine-readable JSON", false).action((opts) => runDoctor(opts));
|
|
@@ -14477,8 +14656,8 @@ init_skill_update_check();
|
|
|
14477
14656
|
init_config();
|
|
14478
14657
|
init_logger();
|
|
14479
14658
|
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
14480
|
-
import { existsSync as
|
|
14481
|
-
import { join as
|
|
14659
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
|
|
14660
|
+
import { join as join25 } from "node:path";
|
|
14482
14661
|
var CACHE_FILENAME2 = "update-check.json";
|
|
14483
14662
|
var CHECK_INTERVAL_MS2 = 24 * 60 * 60 * 1000;
|
|
14484
14663
|
var FETCH_TIMEOUT_MS2 = 5000;
|
|
@@ -14501,14 +14680,14 @@ function isNewerVersion(latest, current) {
|
|
|
14501
14680
|
return false;
|
|
14502
14681
|
}
|
|
14503
14682
|
function getCachePath2() {
|
|
14504
|
-
return
|
|
14683
|
+
return join25(getConfigDir(), CACHE_FILENAME2);
|
|
14505
14684
|
}
|
|
14506
14685
|
function readCache() {
|
|
14507
14686
|
try {
|
|
14508
14687
|
const path2 = getCachePath2();
|
|
14509
|
-
if (!
|
|
14688
|
+
if (!existsSync14(path2))
|
|
14510
14689
|
return null;
|
|
14511
|
-
const data = JSON.parse(
|
|
14690
|
+
const data = JSON.parse(readFileSync12(path2, "utf-8"));
|
|
14512
14691
|
if (typeof data.lastCheck === "number" && typeof data.latestVersion === "string") {
|
|
14513
14692
|
return data;
|
|
14514
14693
|
}
|
|
@@ -14520,7 +14699,7 @@ function readCache() {
|
|
|
14520
14699
|
function writeCache(cache) {
|
|
14521
14700
|
try {
|
|
14522
14701
|
const dir = getConfigDir();
|
|
14523
|
-
if (!
|
|
14702
|
+
if (!existsSync14(dir)) {
|
|
14524
14703
|
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
14525
14704
|
}
|
|
14526
14705
|
writeFileSync6(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
@@ -14810,7 +14989,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
14810
14989
|
if (opts.tail !== undefined) {
|
|
14811
14990
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
14812
14991
|
try {
|
|
14813
|
-
const content =
|
|
14992
|
+
const content = readFileSync13(logPath, "utf-8");
|
|
14814
14993
|
const lines = content.split(`
|
|
14815
14994
|
`);
|
|
14816
14995
|
console.log(lines.slice(-n).join(`
|