@dosu/cli 0.19.2 → 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 +282 -88
- 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 });
|
|
@@ -7667,9 +7782,12 @@ var init_skill_update_check = __esm(() => {
|
|
|
7667
7782
|
|
|
7668
7783
|
// src/commands/skill.ts
|
|
7669
7784
|
import { execSync } from "node:child_process";
|
|
7785
|
+
function supportedSkillAgentArgs() {
|
|
7786
|
+
return SUPPORTED_SKILL_AGENTS.map((agent) => `-a ${agent}`).join(" ");
|
|
7787
|
+
}
|
|
7670
7788
|
async function installSkill() {
|
|
7671
7789
|
try {
|
|
7672
|
-
execSync(`npx skills add ${SKILL_REPO} -g -s ${SKILL_NAME} -y`, {
|
|
7790
|
+
execSync(`npx skills add ${SKILL_REPO} -g ${supportedSkillAgentArgs()} -s ${SKILL_NAME} -y`, {
|
|
7673
7791
|
stdio: "inherit"
|
|
7674
7792
|
});
|
|
7675
7793
|
} catch (err) {
|
|
@@ -7733,33 +7851,45 @@ Failed to update skill.`));
|
|
|
7733
7851
|
});
|
|
7734
7852
|
return cmd;
|
|
7735
7853
|
}
|
|
7736
|
-
var import_picocolors10, SKILL_REPO = "dosu-ai/dosu-skill", SKILL_NAME = "dosu";
|
|
7854
|
+
var import_picocolors10, SKILL_REPO = "dosu-ai/dosu-skill", SKILL_NAME = "dosu", SUPPORTED_SKILL_AGENTS;
|
|
7737
7855
|
var init_skill = __esm(() => {
|
|
7738
7856
|
init_esm();
|
|
7739
7857
|
init_logger();
|
|
7740
7858
|
init_skill_update_check();
|
|
7741
7859
|
import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
7860
|
+
SUPPORTED_SKILL_AGENTS = [
|
|
7861
|
+
"claude-code",
|
|
7862
|
+
"cursor",
|
|
7863
|
+
"gemini-cli",
|
|
7864
|
+
"codex",
|
|
7865
|
+
"windsurf",
|
|
7866
|
+
"zed",
|
|
7867
|
+
"cline",
|
|
7868
|
+
"github-copilot",
|
|
7869
|
+
"opencode",
|
|
7870
|
+
"antigravity"
|
|
7871
|
+
];
|
|
7742
7872
|
});
|
|
7743
7873
|
|
|
7744
7874
|
// src/mcp/constants.ts
|
|
7745
7875
|
var MCP_PROVIDER_SLUG = "dosu_mcp";
|
|
7746
7876
|
|
|
7747
7877
|
// src/mcp/detect.ts
|
|
7748
|
-
import { existsSync as
|
|
7878
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
7749
7879
|
import { homedir, platform } from "node:os";
|
|
7750
|
-
import { join as
|
|
7880
|
+
import { join as join8 } from "node:path";
|
|
7751
7881
|
function isInstalled(paths) {
|
|
7752
|
-
return paths.some((p2) =>
|
|
7882
|
+
return paths.some((p2) => existsSync9(expandHome(p2)));
|
|
7753
7883
|
}
|
|
7754
7884
|
function expandHome(path) {
|
|
7755
7885
|
if (!path.startsWith("~"))
|
|
7756
7886
|
return path;
|
|
7757
|
-
return
|
|
7887
|
+
return join8(homedir(), path.slice(1));
|
|
7758
7888
|
}
|
|
7759
7889
|
function appSupportDir() {
|
|
7760
7890
|
switch (platform()) {
|
|
7761
7891
|
case "darwin": {
|
|
7762
|
-
return
|
|
7892
|
+
return join8(homedir(), "Library", "Application Support");
|
|
7763
7893
|
}
|
|
7764
7894
|
case "win32": {
|
|
7765
7895
|
return process.env.APPDATA ?? "";
|
|
@@ -7768,7 +7898,7 @@ function appSupportDir() {
|
|
|
7768
7898
|
const xdg = process.env.XDG_CONFIG_HOME;
|
|
7769
7899
|
if (xdg)
|
|
7770
7900
|
return xdg;
|
|
7771
|
-
return
|
|
7901
|
+
return join8(homedir(), ".config");
|
|
7772
7902
|
}
|
|
7773
7903
|
}
|
|
7774
7904
|
}
|
|
@@ -7849,7 +7979,7 @@ var init_antigravity = __esm(() => {
|
|
|
7849
7979
|
});
|
|
7850
7980
|
|
|
7851
7981
|
// src/mcp/providers/claude.ts
|
|
7852
|
-
import { join as
|
|
7982
|
+
import { join as join9 } from "node:path";
|
|
7853
7983
|
var ClaudeProvider = () => createJSONProvider({
|
|
7854
7984
|
providerName: "Claude Code",
|
|
7855
7985
|
providerID: "claude",
|
|
@@ -7858,22 +7988,22 @@ var ClaudeProvider = () => createJSONProvider({
|
|
|
7858
7988
|
paths: ["~/.claude"],
|
|
7859
7989
|
globalPath: "~/.claude.json",
|
|
7860
7990
|
topKey: "mcpServers",
|
|
7861
|
-
localConfigPath: (cwd) =>
|
|
7991
|
+
localConfigPath: (cwd) => join9(cwd, ".mcp.json")
|
|
7862
7992
|
});
|
|
7863
7993
|
var init_claude = __esm(() => {
|
|
7864
7994
|
init_base();
|
|
7865
7995
|
});
|
|
7866
7996
|
|
|
7867
7997
|
// src/mcp/providers/claude-desktop.ts
|
|
7868
|
-
import { join as
|
|
7998
|
+
import { join as join10 } from "node:path";
|
|
7869
7999
|
var ClaudeDesktopProvider = () => ({
|
|
7870
8000
|
name: () => "Claude Desktop",
|
|
7871
8001
|
id: () => "claude-desktop",
|
|
7872
8002
|
supportsLocal: () => false,
|
|
7873
8003
|
priority: () => 2,
|
|
7874
|
-
detectPaths: () => [
|
|
7875
|
-
isInstalled: () => isInstalled([
|
|
7876
|
-
globalConfigPath: () =>
|
|
8004
|
+
detectPaths: () => [join10(appSupportDir(), "Claude")],
|
|
8005
|
+
isInstalled: () => isInstalled([join10(appSupportDir(), "Claude")]),
|
|
8006
|
+
globalConfigPath: () => join10(appSupportDir(), "Claude", "claude_desktop_config.json"),
|
|
7877
8007
|
isConfigured: () => false,
|
|
7878
8008
|
install() {
|
|
7879
8009
|
throw new Error("this tool only supports local (stdio) servers and cannot be configured for remote MCP");
|
|
@@ -7887,14 +8017,14 @@ var init_claude_desktop = __esm(() => {
|
|
|
7887
8017
|
});
|
|
7888
8018
|
|
|
7889
8019
|
// src/mcp/providers/cline.ts
|
|
7890
|
-
import { join as
|
|
7891
|
-
var extensionDir = () =>
|
|
8020
|
+
import { join as join11 } from "node:path";
|
|
8021
|
+
var extensionDir = () => join11(appSupportDir(), "Code", "User", "globalStorage", "saoudrizwan.claude-dev"), ClineProvider = () => createJSONProvider({
|
|
7892
8022
|
providerName: "Cline",
|
|
7893
8023
|
providerID: "cline",
|
|
7894
8024
|
local: false,
|
|
7895
8025
|
priorityValue: 11,
|
|
7896
8026
|
paths: [extensionDir()],
|
|
7897
|
-
globalPath:
|
|
8027
|
+
globalPath: join11(extensionDir(), "settings", "cline_mcp_settings.json"),
|
|
7898
8028
|
topKey: "mcpServers",
|
|
7899
8029
|
buildServer: (cfg) => ({
|
|
7900
8030
|
url: mcpURL(cfg.deployment_id),
|
|
@@ -7910,7 +8040,7 @@ var init_cline = __esm(() => {
|
|
|
7910
8040
|
});
|
|
7911
8041
|
|
|
7912
8042
|
// src/mcp/providers/cline-cli.ts
|
|
7913
|
-
import { join as
|
|
8043
|
+
import { join as join12 } from "node:path";
|
|
7914
8044
|
function clineDir() {
|
|
7915
8045
|
return process.env.CLINE_DIR ?? expandHome("~/.cline");
|
|
7916
8046
|
}
|
|
@@ -7920,7 +8050,7 @@ var ClineCliProvider = () => createJSONProvider({
|
|
|
7920
8050
|
local: false,
|
|
7921
8051
|
priorityValue: 12,
|
|
7922
8052
|
paths: [clineDir()],
|
|
7923
|
-
globalPath:
|
|
8053
|
+
globalPath: join12(clineDir(), "data", "settings", "cline_mcp_settings.json"),
|
|
7924
8054
|
topKey: "mcpServers",
|
|
7925
8055
|
buildServer: (cfg) => ({
|
|
7926
8056
|
url: mcpURL(cfg.deployment_id),
|
|
@@ -7936,20 +8066,20 @@ var init_cline_cli = __esm(() => {
|
|
|
7936
8066
|
});
|
|
7937
8067
|
|
|
7938
8068
|
// src/mcp/providers/codex.ts
|
|
7939
|
-
import { existsSync as
|
|
7940
|
-
import { join as
|
|
8069
|
+
import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
|
|
8070
|
+
import { join as join13 } from "node:path";
|
|
7941
8071
|
function codexHome() {
|
|
7942
8072
|
return process.env.CODEX_HOME ?? expandHome("~/.codex");
|
|
7943
8073
|
}
|
|
7944
8074
|
function getConfigPath2(global) {
|
|
7945
8075
|
if (global)
|
|
7946
|
-
return
|
|
7947
|
-
return
|
|
8076
|
+
return join13(codexHome(), "config.toml");
|
|
8077
|
+
return join13(process.cwd(), ".codex", "config.toml");
|
|
7948
8078
|
}
|
|
7949
8079
|
function readTOML(path) {
|
|
7950
|
-
if (!
|
|
8080
|
+
if (!existsSync10(path))
|
|
7951
8081
|
return "";
|
|
7952
|
-
return
|
|
8082
|
+
return readFileSync11(path, "utf-8");
|
|
7953
8083
|
}
|
|
7954
8084
|
function writeTOML(path, content) {
|
|
7955
8085
|
writeSecureFile(path, content);
|
|
@@ -8007,9 +8137,9 @@ var CodexProvider = () => ({
|
|
|
8007
8137
|
priority: () => 8,
|
|
8008
8138
|
detectPaths: () => ["~/.codex"],
|
|
8009
8139
|
isInstalled: () => isInstalled(["~/.codex"]),
|
|
8010
|
-
globalConfigPath: () =>
|
|
8140
|
+
globalConfigPath: () => join13(codexHome(), "config.toml"),
|
|
8011
8141
|
isConfigured: () => {
|
|
8012
|
-
const content = readTOML(
|
|
8142
|
+
const content = readTOML(join13(codexHome(), "config.toml"));
|
|
8013
8143
|
return content.includes("[mcp_servers.dosu]");
|
|
8014
8144
|
},
|
|
8015
8145
|
install(cfg, global) {
|
|
@@ -8031,10 +8161,10 @@ var init_codex2 = __esm(() => {
|
|
|
8031
8161
|
});
|
|
8032
8162
|
|
|
8033
8163
|
// src/mcp/providers/copilot.ts
|
|
8034
|
-
import { join as
|
|
8164
|
+
import { join as join14 } from "node:path";
|
|
8035
8165
|
function globalPath() {
|
|
8036
8166
|
if (process.env.XDG_CONFIG_HOME) {
|
|
8037
|
-
return
|
|
8167
|
+
return join14(process.env.XDG_CONFIG_HOME, "mcp-config.json");
|
|
8038
8168
|
}
|
|
8039
8169
|
return expandHome("~/.copilot/mcp-config.json");
|
|
8040
8170
|
}
|
|
@@ -8065,7 +8195,7 @@ var CopilotProvider = () => ({
|
|
|
8065
8195
|
};
|
|
8066
8196
|
installJSONServer(globalPath(), "mcpServers", server);
|
|
8067
8197
|
} else {
|
|
8068
|
-
const configPath =
|
|
8198
|
+
const configPath = join14(process.cwd(), ".vscode", "mcp.json");
|
|
8069
8199
|
const server = {
|
|
8070
8200
|
type: "http",
|
|
8071
8201
|
url,
|
|
@@ -8078,7 +8208,7 @@ var CopilotProvider = () => ({
|
|
|
8078
8208
|
if (global) {
|
|
8079
8209
|
removeJSONServer(globalPath(), "mcpServers");
|
|
8080
8210
|
} else {
|
|
8081
|
-
const configPath =
|
|
8211
|
+
const configPath = join14(process.cwd(), ".vscode", "mcp.json");
|
|
8082
8212
|
removeJSONServer(configPath, "servers");
|
|
8083
8213
|
}
|
|
8084
8214
|
}
|
|
@@ -8090,7 +8220,7 @@ var init_copilot = __esm(() => {
|
|
|
8090
8220
|
});
|
|
8091
8221
|
|
|
8092
8222
|
// src/mcp/providers/cursor.ts
|
|
8093
|
-
import { join as
|
|
8223
|
+
import { join as join15 } from "node:path";
|
|
8094
8224
|
var CursorProvider = () => createJSONProvider({
|
|
8095
8225
|
providerName: "Cursor",
|
|
8096
8226
|
providerID: "cursor",
|
|
@@ -8103,15 +8233,31 @@ var CursorProvider = () => createJSONProvider({
|
|
|
8103
8233
|
url: mcpURL(cfg.deployment_id),
|
|
8104
8234
|
headers: mcpHeaders(cfg.api_key)
|
|
8105
8235
|
}),
|
|
8106
|
-
localConfigPath: (cwd) =>
|
|
8236
|
+
localConfigPath: (cwd) => join15(cwd, ".cursor", "mcp.json")
|
|
8107
8237
|
});
|
|
8108
8238
|
var init_cursor = __esm(() => {
|
|
8109
8239
|
init_config_helpers();
|
|
8110
8240
|
init_base();
|
|
8111
8241
|
});
|
|
8112
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
|
+
|
|
8113
8259
|
// src/mcp/providers/gemini.ts
|
|
8114
|
-
import { join as
|
|
8260
|
+
import { join as join17 } from "node:path";
|
|
8115
8261
|
var GeminiProvider = () => createJSONProvider({
|
|
8116
8262
|
providerName: "Gemini CLI",
|
|
8117
8263
|
providerID: "gemini",
|
|
@@ -8120,7 +8266,7 @@ var GeminiProvider = () => createJSONProvider({
|
|
|
8120
8266
|
paths: ["~/.gemini"],
|
|
8121
8267
|
globalPath: "~/.gemini/settings.json",
|
|
8122
8268
|
topKey: "mcpServers",
|
|
8123
|
-
localConfigPath: (cwd) =>
|
|
8269
|
+
localConfigPath: (cwd) => join17(cwd, ".gemini", "settings.json")
|
|
8124
8270
|
});
|
|
8125
8271
|
var init_gemini = __esm(() => {
|
|
8126
8272
|
init_base();
|
|
@@ -8170,14 +8316,14 @@ var init_manual = __esm(() => {
|
|
|
8170
8316
|
});
|
|
8171
8317
|
|
|
8172
8318
|
// src/mcp/providers/mcporter.ts
|
|
8173
|
-
import { existsSync as
|
|
8174
|
-
import { join as
|
|
8319
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
8320
|
+
import { join as join18 } from "node:path";
|
|
8175
8321
|
function resolveGlobalConfigPath() {
|
|
8176
8322
|
const jsonPath = expandHome("~/.mcporter/mcporter.json");
|
|
8177
|
-
if (
|
|
8323
|
+
if (existsSync11(jsonPath))
|
|
8178
8324
|
return jsonPath;
|
|
8179
8325
|
const jsoncPath = expandHome("~/.mcporter/mcporter.jsonc");
|
|
8180
|
-
if (
|
|
8326
|
+
if (existsSync11(jsoncPath))
|
|
8181
8327
|
return jsoncPath;
|
|
8182
8328
|
return jsonPath;
|
|
8183
8329
|
}
|
|
@@ -8198,7 +8344,7 @@ var MCPorterProvider = () => ({
|
|
|
8198
8344
|
globalConfigPath: () => resolveGlobalConfigPath(),
|
|
8199
8345
|
isConfigured: () => isJSONKeyConfigured(resolveGlobalConfigPath(), "mcpServers"),
|
|
8200
8346
|
install(cfg, global) {
|
|
8201
|
-
const configPath = global ? resolveGlobalConfigPath() :
|
|
8347
|
+
const configPath = global ? resolveGlobalConfigPath() : join18(process.cwd(), "config", "mcporter.json");
|
|
8202
8348
|
const server = {
|
|
8203
8349
|
type: "http",
|
|
8204
8350
|
url: mcpEndpoint4(cfg),
|
|
@@ -8207,7 +8353,7 @@ var MCPorterProvider = () => ({
|
|
|
8207
8353
|
installJSONServer(configPath, "mcpServers", server);
|
|
8208
8354
|
},
|
|
8209
8355
|
remove(global) {
|
|
8210
|
-
const configPath = global ? resolveGlobalConfigPath() :
|
|
8356
|
+
const configPath = global ? resolveGlobalConfigPath() : join18(process.cwd(), "config", "mcporter.json");
|
|
8211
8357
|
removeJSONServer(configPath, "mcpServers");
|
|
8212
8358
|
}
|
|
8213
8359
|
});
|
|
@@ -8218,7 +8364,7 @@ var init_mcporter = __esm(() => {
|
|
|
8218
8364
|
});
|
|
8219
8365
|
|
|
8220
8366
|
// src/mcp/providers/opencode.ts
|
|
8221
|
-
import { join as
|
|
8367
|
+
import { join as join19 } from "node:path";
|
|
8222
8368
|
var OpenCodeProvider = () => createJSONProvider({
|
|
8223
8369
|
providerName: "OpenCode",
|
|
8224
8370
|
providerID: "opencode",
|
|
@@ -8233,7 +8379,7 @@ var OpenCodeProvider = () => createJSONProvider({
|
|
|
8233
8379
|
enabled: true,
|
|
8234
8380
|
headers: mcpHeaders(cfg.api_key)
|
|
8235
8381
|
}),
|
|
8236
|
-
localConfigPath: (cwd) =>
|
|
8382
|
+
localConfigPath: (cwd) => join19(cwd, "opencode.json")
|
|
8237
8383
|
});
|
|
8238
8384
|
var init_opencode = __esm(() => {
|
|
8239
8385
|
init_config_helpers();
|
|
@@ -8241,16 +8387,16 @@ var init_opencode = __esm(() => {
|
|
|
8241
8387
|
});
|
|
8242
8388
|
|
|
8243
8389
|
// src/mcp/providers/vscode.ts
|
|
8244
|
-
import { join as
|
|
8390
|
+
import { join as join20 } from "node:path";
|
|
8245
8391
|
var VSCodeProvider = () => createJSONProvider({
|
|
8246
8392
|
providerName: "VS Code",
|
|
8247
8393
|
providerID: "vscode",
|
|
8248
8394
|
local: true,
|
|
8249
8395
|
priorityValue: 6,
|
|
8250
|
-
paths: [
|
|
8251
|
-
globalPath:
|
|
8396
|
+
paths: [join20(appSupportDir(), "Code")],
|
|
8397
|
+
globalPath: join20(appSupportDir(), "Code", "User", "mcp.json"),
|
|
8252
8398
|
topKey: "servers",
|
|
8253
|
-
localConfigPath: (cwd) =>
|
|
8399
|
+
localConfigPath: (cwd) => join20(cwd, ".vscode", "mcp.json")
|
|
8254
8400
|
});
|
|
8255
8401
|
var init_vscode = __esm(() => {
|
|
8256
8402
|
init_detect();
|
|
@@ -8259,14 +8405,14 @@ var init_vscode = __esm(() => {
|
|
|
8259
8405
|
|
|
8260
8406
|
// src/mcp/providers/windsurf.ts
|
|
8261
8407
|
import { homedir as homedir2 } from "node:os";
|
|
8262
|
-
import { join as
|
|
8408
|
+
import { join as join21 } from "node:path";
|
|
8263
8409
|
var WindsurfProvider = () => createJSONProvider({
|
|
8264
8410
|
providerName: "Windsurf",
|
|
8265
8411
|
providerID: "windsurf",
|
|
8266
8412
|
local: false,
|
|
8267
8413
|
priorityValue: 9,
|
|
8268
|
-
paths: [
|
|
8269
|
-
globalPath:
|
|
8414
|
+
paths: [join21(homedir2(), ".codeium", "windsurf")],
|
|
8415
|
+
globalPath: join21(homedir2(), ".codeium", "windsurf", "mcp_config.json"),
|
|
8270
8416
|
topKey: "mcpServers"
|
|
8271
8417
|
});
|
|
8272
8418
|
var init_windsurf = __esm(() => {
|
|
@@ -8275,12 +8421,12 @@ var init_windsurf = __esm(() => {
|
|
|
8275
8421
|
|
|
8276
8422
|
// src/mcp/providers/zed.ts
|
|
8277
8423
|
import { platform as platform2 } from "node:os";
|
|
8278
|
-
import { join as
|
|
8424
|
+
import { join as join22 } from "node:path";
|
|
8279
8425
|
function zedConfigDir() {
|
|
8280
8426
|
const os = platform2();
|
|
8281
8427
|
if (os === "darwin" || os === "win32")
|
|
8282
|
-
return
|
|
8283
|
-
return
|
|
8428
|
+
return join22(appSupportDir(), "Zed");
|
|
8429
|
+
return join22(appSupportDir(), "zed");
|
|
8284
8430
|
}
|
|
8285
8431
|
var ZedProvider = () => createJSONProvider({
|
|
8286
8432
|
providerName: "Zed",
|
|
@@ -8288,7 +8434,7 @@ var ZedProvider = () => createJSONProvider({
|
|
|
8288
8434
|
local: true,
|
|
8289
8435
|
priorityValue: 10,
|
|
8290
8436
|
paths: [zedConfigDir()],
|
|
8291
|
-
globalPath:
|
|
8437
|
+
globalPath: join22(zedConfigDir(), "settings.json"),
|
|
8292
8438
|
topKey: "context_servers",
|
|
8293
8439
|
buildServer: (cfg) => ({
|
|
8294
8440
|
source: "custom",
|
|
@@ -8296,7 +8442,7 @@ var ZedProvider = () => createJSONProvider({
|
|
|
8296
8442
|
url: mcpURL(cfg.deployment_id),
|
|
8297
8443
|
headers: mcpHeaders(cfg.api_key)
|
|
8298
8444
|
}),
|
|
8299
|
-
localConfigPath: (cwd) =>
|
|
8445
|
+
localConfigPath: (cwd) => join22(cwd, ".zed", "settings.json")
|
|
8300
8446
|
});
|
|
8301
8447
|
var init_zed = __esm(() => {
|
|
8302
8448
|
init_config_helpers();
|
|
@@ -8321,6 +8467,7 @@ function allProviders() {
|
|
|
8321
8467
|
OpenCodeProvider(),
|
|
8322
8468
|
AntigravityProvider(),
|
|
8323
8469
|
MCPorterProvider(),
|
|
8470
|
+
FactoryProvider(),
|
|
8324
8471
|
ManualProvider()
|
|
8325
8472
|
];
|
|
8326
8473
|
}
|
|
@@ -8343,6 +8490,7 @@ var init_providers = __esm(() => {
|
|
|
8343
8490
|
init_codex2();
|
|
8344
8491
|
init_copilot();
|
|
8345
8492
|
init_cursor();
|
|
8493
|
+
init_factory2();
|
|
8346
8494
|
init_gemini();
|
|
8347
8495
|
init_manual();
|
|
8348
8496
|
init_mcporter();
|
|
@@ -10889,8 +11037,8 @@ __export(exports_flow2, {
|
|
|
10889
11037
|
isStdioOnly: () => isStdioOnly
|
|
10890
11038
|
});
|
|
10891
11039
|
import { randomUUID } from "node:crypto";
|
|
10892
|
-
import { existsSync as
|
|
10893
|
-
import { join as
|
|
11040
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
11041
|
+
import { join as join23 } from "node:path";
|
|
10894
11042
|
async function runSetup(opts = {}) {
|
|
10895
11043
|
const onboardingRunID = randomUUID();
|
|
10896
11044
|
logger.info("setup", `Setup flow started${opts.deploymentID ? ` deployment=${opts.deploymentID}` : ""}${opts.mode ? ` mode=${opts.mode}` : ""}`);
|
|
@@ -11062,7 +11210,7 @@ async function runSetup(opts = {}) {
|
|
|
11062
11210
|
showTryItOutPrompt({
|
|
11063
11211
|
mode: cfg.mode,
|
|
11064
11212
|
docsImported: choices.connectGitHub && githubOnboardingDone,
|
|
11065
|
-
hasAgentsMd:
|
|
11213
|
+
hasAgentsMd: existsSync12(join23(process.cwd(), "AGENTS.md"))
|
|
11066
11214
|
});
|
|
11067
11215
|
}
|
|
11068
11216
|
if (mcpCompleted || skillCompleted || docsImported) {
|
|
@@ -11556,8 +11704,8 @@ var init_flow2 = __esm(() => {
|
|
|
11556
11704
|
});
|
|
11557
11705
|
|
|
11558
11706
|
// src/commands/insights.ts
|
|
11559
|
-
import { existsSync as
|
|
11560
|
-
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";
|
|
11561
11709
|
function shuffled(arr) {
|
|
11562
11710
|
const copy2 = [...arr];
|
|
11563
11711
|
for (let i = copy2.length - 1;i > 0; i--) {
|
|
@@ -11661,17 +11809,17 @@ function makeAskFn(cfg) {
|
|
|
11661
11809
|
};
|
|
11662
11810
|
}
|
|
11663
11811
|
function insightsDir() {
|
|
11664
|
-
return
|
|
11812
|
+
return join24(getConfigDir(), "insights");
|
|
11665
11813
|
}
|
|
11666
11814
|
function reportPath(timestamp) {
|
|
11667
11815
|
const dir = insightsDir();
|
|
11668
11816
|
if (!timestamp)
|
|
11669
|
-
return
|
|
11817
|
+
return join24(dir, "latest.html");
|
|
11670
11818
|
const iso = timestamp.toISOString().slice(0, 19).replace(/:/g, "-");
|
|
11671
|
-
return
|
|
11819
|
+
return join24(dir, `report-${iso}Z.html`);
|
|
11672
11820
|
}
|
|
11673
11821
|
function pruneOldReports(dir, keepN) {
|
|
11674
|
-
if (!
|
|
11822
|
+
if (!existsSync13(dir))
|
|
11675
11823
|
return;
|
|
11676
11824
|
let entries;
|
|
11677
11825
|
try {
|
|
@@ -11683,7 +11831,7 @@ function pruneOldReports(dir, keepN) {
|
|
|
11683
11831
|
const reports = entries.filter((f) => REPORT_FILE_PATTERN.test(f)).sort().reverse();
|
|
11684
11832
|
for (const f of reports.slice(keepN)) {
|
|
11685
11833
|
try {
|
|
11686
|
-
unlinkSync(
|
|
11834
|
+
unlinkSync(join24(dir, f));
|
|
11687
11835
|
} catch (err) {
|
|
11688
11836
|
logger.debug("insights", `failed to prune ${f}: ${err instanceof Error ? err.message : err}`);
|
|
11689
11837
|
}
|
|
@@ -11756,7 +11904,7 @@ function defaultRunner(cfg) {
|
|
|
11756
11904
|
render: renderHTML,
|
|
11757
11905
|
writeFile: (path2, content) => {
|
|
11758
11906
|
const dir = dirname3(path2);
|
|
11759
|
-
if (!
|
|
11907
|
+
if (!existsSync13(dir))
|
|
11760
11908
|
mkdirSync6(dir, { recursive: true, mode: 448 });
|
|
11761
11909
|
writeFileSync5(path2, content, { mode: 384 });
|
|
11762
11910
|
},
|
|
@@ -12421,7 +12569,7 @@ var init_flow3 = __esm(() => {
|
|
|
12421
12569
|
// src/cli/cli.ts
|
|
12422
12570
|
init_esm();
|
|
12423
12571
|
init_client();
|
|
12424
|
-
import { readFileSync as
|
|
12572
|
+
import { readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
|
|
12425
12573
|
|
|
12426
12574
|
// src/commands/analytics.ts
|
|
12427
12575
|
init_esm();
|
|
@@ -13107,7 +13255,7 @@ init_esm();
|
|
|
13107
13255
|
init_config();
|
|
13108
13256
|
init_logger();
|
|
13109
13257
|
init_prompts();
|
|
13110
|
-
import { readFileSync as
|
|
13258
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
13111
13259
|
import { basename } from "node:path";
|
|
13112
13260
|
|
|
13113
13261
|
// src/hooks/state.ts
|
|
@@ -13146,7 +13294,7 @@ var COOLDOWN_DEFAULT_MS = 3000;
|
|
|
13146
13294
|
var TTL_DEFAULT_MS = 10 * 60 * 1000;
|
|
13147
13295
|
var STOP_WAIT_DEFAULT_MS = 8000;
|
|
13148
13296
|
var STOP_POLL_DEFAULT_MS = 1000;
|
|
13149
|
-
var SUPPORTED_AGENTS = ["claude-code", "codex"];
|
|
13297
|
+
var SUPPORTED_AGENTS = ["claude-code", "codex", "factory"];
|
|
13150
13298
|
var DEFAULT_AGENT = "claude-code";
|
|
13151
13299
|
function cooldownMs() {
|
|
13152
13300
|
const n = Number.parseInt(process.env.DOSU_HOOK_CHECK_COOLDOWN_MS ?? "", 10);
|
|
@@ -13376,7 +13524,7 @@ async function runHookEntrypoint(event, raw, now = Date.now(), agent = DEFAULT_A
|
|
|
13376
13524
|
}
|
|
13377
13525
|
function readStdinRaw() {
|
|
13378
13526
|
try {
|
|
13379
|
-
return
|
|
13527
|
+
return readFileSync9(0, "utf8");
|
|
13380
13528
|
} catch {
|
|
13381
13529
|
return "";
|
|
13382
13530
|
}
|
|
@@ -13424,6 +13572,20 @@ async function runInstall(agent, opts) {
|
|
|
13424
13572
|
}
|
|
13425
13573
|
return;
|
|
13426
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
|
+
}
|
|
13427
13589
|
const { installClaudeHooks: installClaudeHooks2, claudeLocalSettingsPath: claudeLocalSettingsPath2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
|
|
13428
13590
|
const configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
|
|
13429
13591
|
const { events } = installClaudeHooks2(configPath, { stop: opts.stop });
|
|
@@ -13461,6 +13623,10 @@ async function runUninstall(agent, opts) {
|
|
|
13461
13623
|
const { removeCodexHooks: removeCodexHooks2, codexHooksPath: codexHooksPath2 } = await Promise.resolve().then(() => (init_codex(), exports_codex));
|
|
13462
13624
|
configPath = codexHooksPath2(resolveDir(opts.dir));
|
|
13463
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));
|
|
13464
13630
|
} else {
|
|
13465
13631
|
const { removeClaudeHooks: removeClaudeHooks2, claudeLocalSettingsPath: claudeLocalSettingsPath2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
|
|
13466
13632
|
configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
|
|
@@ -13479,15 +13645,20 @@ async function collectDoctorChecks(opts) {
|
|
|
13479
13645
|
const checks = [];
|
|
13480
13646
|
const { claudeLocalSettingsPath: claudeLocalSettingsPath2, inspectClaudeHooks: inspectClaudeHooks2 } = await Promise.resolve().then(() => (init_claude_code(), exports_claude_code));
|
|
13481
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));
|
|
13482
13649
|
const configPath = claudeLocalSettingsPath2(resolveDir(opts.dir));
|
|
13483
13650
|
const inspection = inspectClaudeHooks2(configPath);
|
|
13484
13651
|
const codexPath = codexHooksPath2(resolveDir(opts.dir));
|
|
13485
13652
|
const codex = inspectCodexHooks2(codexPath);
|
|
13653
|
+
const factoryPath = factoryHooksPath2(resolveDir(opts.dir));
|
|
13654
|
+
const factory = inspectFactoryHooks2(factoryPath);
|
|
13486
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;
|
|
13487
13658
|
if (!inspection.fileExists) {
|
|
13488
13659
|
checks.push({
|
|
13489
13660
|
name: "config",
|
|
13490
|
-
status:
|
|
13661
|
+
status: alternativeInstalled ? "warn" : "fail",
|
|
13491
13662
|
detail: `not found: ${configPath} (run 'dosu hooks install claude-code')`
|
|
13492
13663
|
});
|
|
13493
13664
|
} else if (inspection.parseError) {
|
|
@@ -13506,7 +13677,7 @@ async function collectDoctorChecks(opts) {
|
|
|
13506
13677
|
} else {
|
|
13507
13678
|
checks.push({
|
|
13508
13679
|
name: "hooks",
|
|
13509
|
-
status:
|
|
13680
|
+
status: alternativeInstalled ? "warn" : "fail",
|
|
13510
13681
|
detail: "UserPromptSubmit + PostToolUse not both installed"
|
|
13511
13682
|
});
|
|
13512
13683
|
}
|
|
@@ -13532,6 +13703,27 @@ async function collectDoctorChecks(opts) {
|
|
|
13532
13703
|
});
|
|
13533
13704
|
}
|
|
13534
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
|
+
}
|
|
13535
13727
|
const cfg = loadConfig();
|
|
13536
13728
|
if (isAuthenticated(cfg)) {
|
|
13537
13729
|
checks.push({ name: "auth", status: "ok", detail: "logged in" });
|
|
@@ -13586,7 +13778,7 @@ async function runDoctor(opts) {
|
|
|
13586
13778
|
}
|
|
13587
13779
|
}
|
|
13588
13780
|
function hooksCommand() {
|
|
13589
|
-
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)");
|
|
13590
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) => {
|
|
13591
13783
|
await runHookEntrypoint("user-prompt-submit", readStdinRaw(), Date.now(), opts.agent);
|
|
13592
13784
|
});
|
|
@@ -13613,6 +13805,7 @@ function hooksCommand() {
|
|
|
13613
13805
|
"Examples:",
|
|
13614
13806
|
" $ dosu hooks install claude-code",
|
|
13615
13807
|
" $ dosu hooks install codex",
|
|
13808
|
+
" $ dosu hooks install factory",
|
|
13616
13809
|
" $ dosu hooks install claude-code --no-stop",
|
|
13617
13810
|
" $ dosu hooks install codex --dir ./my-project",
|
|
13618
13811
|
"",
|
|
@@ -13626,7 +13819,8 @@ function hooksCommand() {
|
|
|
13626
13819
|
"",
|
|
13627
13820
|
"Examples:",
|
|
13628
13821
|
" $ dosu hooks uninstall claude-code",
|
|
13629
|
-
" $ dosu hooks uninstall codex"
|
|
13822
|
+
" $ dosu hooks uninstall codex",
|
|
13823
|
+
" $ dosu hooks uninstall factory"
|
|
13630
13824
|
].join(`
|
|
13631
13825
|
`)).action((agent, opts) => runUninstall(agent, opts));
|
|
13632
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));
|
|
@@ -14462,8 +14656,8 @@ init_skill_update_check();
|
|
|
14462
14656
|
init_config();
|
|
14463
14657
|
init_logger();
|
|
14464
14658
|
var import_picocolors24 = __toESM(require_picocolors(), 1);
|
|
14465
|
-
import { existsSync as
|
|
14466
|
-
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";
|
|
14467
14661
|
var CACHE_FILENAME2 = "update-check.json";
|
|
14468
14662
|
var CHECK_INTERVAL_MS2 = 24 * 60 * 60 * 1000;
|
|
14469
14663
|
var FETCH_TIMEOUT_MS2 = 5000;
|
|
@@ -14486,14 +14680,14 @@ function isNewerVersion(latest, current) {
|
|
|
14486
14680
|
return false;
|
|
14487
14681
|
}
|
|
14488
14682
|
function getCachePath2() {
|
|
14489
|
-
return
|
|
14683
|
+
return join25(getConfigDir(), CACHE_FILENAME2);
|
|
14490
14684
|
}
|
|
14491
14685
|
function readCache() {
|
|
14492
14686
|
try {
|
|
14493
14687
|
const path2 = getCachePath2();
|
|
14494
|
-
if (!
|
|
14688
|
+
if (!existsSync14(path2))
|
|
14495
14689
|
return null;
|
|
14496
|
-
const data = JSON.parse(
|
|
14690
|
+
const data = JSON.parse(readFileSync12(path2, "utf-8"));
|
|
14497
14691
|
if (typeof data.lastCheck === "number" && typeof data.latestVersion === "string") {
|
|
14498
14692
|
return data;
|
|
14499
14693
|
}
|
|
@@ -14505,7 +14699,7 @@ function readCache() {
|
|
|
14505
14699
|
function writeCache(cache) {
|
|
14506
14700
|
try {
|
|
14507
14701
|
const dir = getConfigDir();
|
|
14508
|
-
if (!
|
|
14702
|
+
if (!existsSync14(dir)) {
|
|
14509
14703
|
mkdirSync7(dir, { recursive: true, mode: 448 });
|
|
14510
14704
|
}
|
|
14511
14705
|
writeFileSync6(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
@@ -14795,7 +14989,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
|
|
|
14795
14989
|
if (opts.tail !== undefined) {
|
|
14796
14990
|
const n = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
|
|
14797
14991
|
try {
|
|
14798
|
-
const content =
|
|
14992
|
+
const content = readFileSync13(logPath, "utf-8");
|
|
14799
14993
|
const lines = content.split(`
|
|
14800
14994
|
`);
|
|
14801
14995
|
console.log(lines.slice(-n).join(`
|