@dosu/cli 0.67.0 → 0.67.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/dosu.js +776 -526
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -47,6 +47,111 @@ var __esm = (fn, res, err) => () => {
|
|
|
47
47
|
};
|
|
48
48
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
49
49
|
|
|
50
|
+
// node_modules/picocolors/picocolors.js
|
|
51
|
+
var require_picocolors = __commonJS(function(exports, module) {
|
|
52
|
+
var p = process || {};
|
|
53
|
+
var argv = p.argv || [];
|
|
54
|
+
var env = p.env || {};
|
|
55
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
56
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
57
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
58
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
59
|
+
};
|
|
60
|
+
var replaceClose = (string, close, replace, index) => {
|
|
61
|
+
let result = "", cursor = 0;
|
|
62
|
+
do {
|
|
63
|
+
result += string.substring(cursor, index) + replace;
|
|
64
|
+
cursor = index + close.length;
|
|
65
|
+
index = string.indexOf(close, cursor);
|
|
66
|
+
} while (~index);
|
|
67
|
+
return result + string.substring(cursor);
|
|
68
|
+
};
|
|
69
|
+
var createColors = (enabled = isColorSupported) => {
|
|
70
|
+
let f = enabled ? formatter : () => String;
|
|
71
|
+
return {
|
|
72
|
+
isColorSupported: enabled,
|
|
73
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
74
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
75
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
76
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
77
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
78
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
79
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
80
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
81
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
82
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
83
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
84
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
85
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
86
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
87
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
88
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
89
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
90
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
91
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
92
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
93
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
94
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
95
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
96
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
97
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
98
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
99
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
100
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
101
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
102
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
103
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
104
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
105
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
106
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
107
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
108
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
109
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
110
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
111
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
112
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
113
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
module.exports = createColors();
|
|
117
|
+
module.exports.createColors = createColors;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// src/cli/command-error.ts
|
|
121
|
+
function isCommandError(error) {
|
|
122
|
+
return error instanceof CommandError;
|
|
123
|
+
}
|
|
124
|
+
var COMMAND_ERROR_CODES, CommandError;
|
|
125
|
+
var init_command_error = __esm(() => {
|
|
126
|
+
COMMAND_ERROR_CODES = [
|
|
127
|
+
"NOT_LOGGED_IN",
|
|
128
|
+
"NO_ORG_SELECTED",
|
|
129
|
+
"NO_API_KEY",
|
|
130
|
+
"NO_LIBRARY_SELECTED",
|
|
131
|
+
"NO_DEPLOYMENT_SELECTED",
|
|
132
|
+
"ORG_UNAVAILABLE",
|
|
133
|
+
"LIBRARY_UNAVAILABLE",
|
|
134
|
+
"DEPLOYMENT_UNAVAILABLE",
|
|
135
|
+
"SCOPE_MISMATCH",
|
|
136
|
+
"DEPLOYMENT_NOT_FOUND",
|
|
137
|
+
"DEPLOYMENT_AMBIGUOUS",
|
|
138
|
+
"NOT_MCP_DEPLOYMENT",
|
|
139
|
+
"REVIEW_ITEM_NOT_FOUND",
|
|
140
|
+
"INVALID_ARGUMENT"
|
|
141
|
+
];
|
|
142
|
+
CommandError = class CommandError extends Error {
|
|
143
|
+
code;
|
|
144
|
+
details;
|
|
145
|
+
exitCode = 1;
|
|
146
|
+
constructor(code, message, details = []) {
|
|
147
|
+
super(message);
|
|
148
|
+
this.code = code;
|
|
149
|
+
this.details = details;
|
|
150
|
+
this.name = "CommandError";
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
|
|
50
155
|
// src/statusline/argv.ts
|
|
51
156
|
function agentFromArgv(argv) {
|
|
52
157
|
for (let i = 0;i < argv.length; i++) {
|
|
@@ -856,6 +961,10 @@ function mcpHeaders(apiKey) {
|
|
|
856
961
|
}
|
|
857
962
|
return { "X-Dosu-API-Key": apiKey };
|
|
858
963
|
}
|
|
964
|
+
function npxRemoteEntry(url, apiKey, npx, path) {
|
|
965
|
+
const remote = mcpRemoteServer(url, apiKey);
|
|
966
|
+
return { command: npx, args: remote.args, env: { PATH: path, ...remote.env } };
|
|
967
|
+
}
|
|
859
968
|
function mcpRemoteServer(url, apiKey) {
|
|
860
969
|
const env = {};
|
|
861
970
|
const headerArgs = Object.entries(mcpHeaders(apiKey)).flatMap(([key, value]) => {
|
|
@@ -976,6 +1085,12 @@ function isJSONKeyConfigured(configPath, topLevelKey) {
|
|
|
976
1085
|
return false;
|
|
977
1086
|
return "dosu" in section;
|
|
978
1087
|
}
|
|
1088
|
+
function readJSONServer(configPath, topLevelKey) {
|
|
1089
|
+
const section = loadJSONConfig(configPath)[topLevelKey];
|
|
1090
|
+
if (typeof section !== "object" || section === null)
|
|
1091
|
+
return;
|
|
1092
|
+
return section.dosu;
|
|
1093
|
+
}
|
|
979
1094
|
function installJSONServer(configPath, topKey, server) {
|
|
980
1095
|
const jsonCfg = readJSONConfig(configPath);
|
|
981
1096
|
let section = jsonCfg[topKey];
|
|
@@ -1006,76 +1121,6 @@ var init_config_helpers = __esm(() => {
|
|
|
1006
1121
|
writeFileAtomic = import_write_file_atomic.default;
|
|
1007
1122
|
});
|
|
1008
1123
|
|
|
1009
|
-
// node_modules/picocolors/picocolors.js
|
|
1010
|
-
var require_picocolors = __commonJS(function(exports, module) {
|
|
1011
|
-
var p = process || {};
|
|
1012
|
-
var argv = p.argv || [];
|
|
1013
|
-
var env = p.env || {};
|
|
1014
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
1015
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
1016
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
1017
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
1018
|
-
};
|
|
1019
|
-
var replaceClose = (string, close, replace, index) => {
|
|
1020
|
-
let result = "", cursor = 0;
|
|
1021
|
-
do {
|
|
1022
|
-
result += string.substring(cursor, index) + replace;
|
|
1023
|
-
cursor = index + close.length;
|
|
1024
|
-
index = string.indexOf(close, cursor);
|
|
1025
|
-
} while (~index);
|
|
1026
|
-
return result + string.substring(cursor);
|
|
1027
|
-
};
|
|
1028
|
-
var createColors = (enabled = isColorSupported) => {
|
|
1029
|
-
let f = enabled ? formatter : () => String;
|
|
1030
|
-
return {
|
|
1031
|
-
isColorSupported: enabled,
|
|
1032
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
1033
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
1034
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
1035
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
1036
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
1037
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
1038
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
1039
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
1040
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
1041
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
1042
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
1043
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
1044
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
1045
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
1046
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
1047
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
1048
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
1049
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
1050
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
1051
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
1052
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
1053
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
1054
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
1055
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
1056
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
1057
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
1058
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
1059
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
1060
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
1061
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
1062
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
1063
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
1064
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
1065
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
1066
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
1067
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
1068
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
1069
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
1070
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
1071
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
1072
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
1073
|
-
};
|
|
1074
|
-
};
|
|
1075
|
-
module.exports = createColors();
|
|
1076
|
-
module.exports.createColors = createColors;
|
|
1077
|
-
});
|
|
1078
|
-
|
|
1079
1124
|
// src/version/version.ts
|
|
1080
1125
|
function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
1081
1126
|
return channel === "npm" && (env.npm_lifecycle_event === "npx" || env.npm_command === "exec");
|
|
@@ -1083,7 +1128,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
1083
1128
|
function getVersionString() {
|
|
1084
1129
|
return `v${VERSION}`;
|
|
1085
1130
|
}
|
|
1086
|
-
var VERSION = "0.67.
|
|
1131
|
+
var VERSION = "0.67.2", INSTALL_CHANNEL = "npm";
|
|
1087
1132
|
|
|
1088
1133
|
// src/debug/logger.ts
|
|
1089
1134
|
import {
|
|
@@ -1173,18 +1218,18 @@ function writeEntry(level, mod, message) {
|
|
|
1173
1218
|
} catch {}
|
|
1174
1219
|
if (debugToConsole) {
|
|
1175
1220
|
const colorize = {
|
|
1176
|
-
DEBUG:
|
|
1177
|
-
INFO:
|
|
1178
|
-
WARN:
|
|
1179
|
-
ERROR:
|
|
1221
|
+
DEBUG: import_picocolors2.default.dim,
|
|
1222
|
+
INFO: import_picocolors2.default.cyan,
|
|
1223
|
+
WARN: import_picocolors2.default.yellow,
|
|
1224
|
+
ERROR: import_picocolors2.default.red
|
|
1180
1225
|
}[level];
|
|
1181
1226
|
console.error(colorize(line.trimEnd()));
|
|
1182
1227
|
}
|
|
1183
1228
|
}
|
|
1184
|
-
var
|
|
1229
|
+
var import_picocolors2, MAX_LOG_SIZE = 1048576, TRUNCATE_KEEP = 524288, LOG_FILENAME = "debug.log", REDACTED = "[REDACTED]", SECRET_QUERY_KEYS, initialized = false, debugToConsole = false, logFilePath = null, ANSI_PATTERN, logger;
|
|
1185
1230
|
var init_logger = __esm(() => {
|
|
1186
1231
|
init_config();
|
|
1187
|
-
|
|
1232
|
+
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
1188
1233
|
SECRET_QUERY_KEYS = [
|
|
1189
1234
|
"access_token",
|
|
1190
1235
|
"refresh_token",
|
|
@@ -7187,8 +7232,7 @@ var init_arguments = __esm(() => {
|
|
|
7187
7232
|
function requireLoginConfig() {
|
|
7188
7233
|
const cfg = loadConfig();
|
|
7189
7234
|
if (!cfg.active_account?.session.access_token) {
|
|
7190
|
-
|
|
7191
|
-
process.exit(1);
|
|
7235
|
+
throw new CommandError("NOT_LOGGED_IN", "Not logged in. Run 'dosu login' first.");
|
|
7192
7236
|
}
|
|
7193
7237
|
return cfg;
|
|
7194
7238
|
}
|
|
@@ -7196,22 +7240,20 @@ function requireOrgConfig() {
|
|
|
7196
7240
|
const cfg = requireLoginConfig();
|
|
7197
7241
|
const orgId = cfg.active_account?.target?.org_id;
|
|
7198
7242
|
if (!orgId) {
|
|
7199
|
-
|
|
7200
|
-
process.exit(1);
|
|
7243
|
+
throw new CommandError("NO_ORG_SELECTED", "Missing org config. Run 'dosu setup' to reconfigure.");
|
|
7201
7244
|
}
|
|
7202
7245
|
return { cfg, orgId };
|
|
7203
7246
|
}
|
|
7204
7247
|
function requireAPIKey(cfg) {
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7248
|
+
const apiKey = cfg.active_account?.target?.api_key;
|
|
7249
|
+
if (!apiKey) {
|
|
7250
|
+
throw new CommandError("NO_API_KEY", "API key not configured. Run 'dosu setup' first.");
|
|
7208
7251
|
}
|
|
7209
|
-
return
|
|
7252
|
+
return apiKey;
|
|
7210
7253
|
}
|
|
7211
|
-
var import_picocolors2;
|
|
7212
7254
|
var init_auth = __esm(() => {
|
|
7255
|
+
init_command_error();
|
|
7213
7256
|
init_config();
|
|
7214
|
-
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
7215
7257
|
});
|
|
7216
7258
|
|
|
7217
7259
|
// node_modules/fast-string-truncated-width/dist/utils.js
|
|
@@ -11430,8 +11472,16 @@ function requireConfig4() {
|
|
|
11430
11472
|
return requireLoginConfig();
|
|
11431
11473
|
}
|
|
11432
11474
|
async function listAccessibleDeployments(client, activeOrgId) {
|
|
11433
|
-
if (activeOrgId)
|
|
11434
|
-
|
|
11475
|
+
if (activeOrgId) {
|
|
11476
|
+
const deployments = await client.workspaces.listForOrg.query(activeOrgId);
|
|
11477
|
+
if (deployments.length > 0)
|
|
11478
|
+
return deployments;
|
|
11479
|
+
const orgs = await client.organization.getOrganizations.query({});
|
|
11480
|
+
if (!orgs.some((org) => org.org_id === activeOrgId)) {
|
|
11481
|
+
throw new CommandError("ORG_UNAVAILABLE", "The saved organization is not available to this account.", ["Run 'dosu setup' to choose an organization and MCP deployment."]);
|
|
11482
|
+
}
|
|
11483
|
+
return deployments;
|
|
11484
|
+
}
|
|
11435
11485
|
const orgs = await client.organization.getOrganizations.query({});
|
|
11436
11486
|
const deployments = await Promise.all(orgs.map((org) => client.workspaces.listForOrg.query(org.org_id)));
|
|
11437
11487
|
return deployments.flat();
|
|
@@ -11445,15 +11495,11 @@ async function resolveDeploymentId(client, activeOrgId, id) {
|
|
|
11445
11495
|
if (matches.length === 1)
|
|
11446
11496
|
return matches[0].deployment_id;
|
|
11447
11497
|
if (matches.length === 0) {
|
|
11448
|
-
|
|
11449
|
-
|
|
11450
|
-
|
|
11451
|
-
}
|
|
11452
|
-
console.error(import_picocolors15.default.red(`Ambiguous deployment ID prefix: ${id} matches ${matches.length}:`));
|
|
11453
|
-
for (const d of matches) {
|
|
11454
|
-
console.error(import_picocolors15.default.dim(` ${d.deployment_id} ${d.name}`));
|
|
11498
|
+
throw new CommandError("DEPLOYMENT_NOT_FOUND", `Deployment not found: ${id}`, [
|
|
11499
|
+
"Expected a full deployment ID (UUID). Run 'dosu deployments list --json' to see full IDs."
|
|
11500
|
+
]);
|
|
11455
11501
|
}
|
|
11456
|
-
|
|
11502
|
+
throw new CommandError("DEPLOYMENT_AMBIGUOUS", `Ambiguous deployment ID prefix: ${id} matches ${matches.length}:`, matches.map((d) => ` ${d.deployment_id} ${d.name}`));
|
|
11457
11503
|
}
|
|
11458
11504
|
function deploymentsCommand() {
|
|
11459
11505
|
const cmd = new Command("deployments").description("Select the MCP deployment (and its Library) this CLI uses; not for Agents");
|
|
@@ -11484,14 +11530,12 @@ ${import_picocolors15.default.dim(`Current: ${cfg.active_account?.target?.deploy
|
|
|
11484
11530
|
cmd.command("info").description("Show the selected MCP deployment").option("--json", "Output as JSON").action(async (opts) => {
|
|
11485
11531
|
const cfg = requireConfig4();
|
|
11486
11532
|
if (!cfg.active_account?.target?.deployment_id) {
|
|
11487
|
-
|
|
11488
|
-
process.exit(1);
|
|
11533
|
+
throw new CommandError("NO_DEPLOYMENT_SELECTED", "No deployment selected. Run 'dosu setup' or 'dosu deployments switch'.");
|
|
11489
11534
|
}
|
|
11490
11535
|
const client = createTypedClient(cfg);
|
|
11491
11536
|
const deployment = await client.workspaces.get.query(cfg.active_account?.target?.deployment_id);
|
|
11492
11537
|
if (!deployment) {
|
|
11493
|
-
|
|
11494
|
-
process.exit(1);
|
|
11538
|
+
throw new CommandError("DEPLOYMENT_UNAVAILABLE", `Deployment not found: ${cfg.active_account?.target?.deployment_id}`);
|
|
11495
11539
|
}
|
|
11496
11540
|
if (opts.json) {
|
|
11497
11541
|
printResult(deployment, opts);
|
|
@@ -11514,12 +11558,10 @@ ${import_picocolors15.default.dim(`Current: ${cfg.active_account?.target?.deploy
|
|
|
11514
11558
|
const id = await resolveDeploymentId(client, cfg.active_account?.target?.org_id, rawId);
|
|
11515
11559
|
const deployment = await client.workspaces.get.query(id);
|
|
11516
11560
|
if (!deployment) {
|
|
11517
|
-
|
|
11518
|
-
process.exit(1);
|
|
11561
|
+
throw new CommandError("DEPLOYMENT_NOT_FOUND", `Deployment not found: ${id}`);
|
|
11519
11562
|
}
|
|
11520
11563
|
if (deployment.provider_slug !== MCP_PROVIDER_SLUG) {
|
|
11521
|
-
|
|
11522
|
-
process.exit(1);
|
|
11564
|
+
throw new CommandError("NOT_MCP_DEPLOYMENT", `Not a Dosu MCP deployment: ${id}`);
|
|
11523
11565
|
}
|
|
11524
11566
|
const apiKey = await new Client(cfg).createAPIKey(deployment.deployment_id, "dosu-cli");
|
|
11525
11567
|
updateTarget(cfg, {
|
|
@@ -11542,6 +11584,7 @@ ${import_picocolors15.default.dim(`Current: ${cfg.active_account?.target?.deploy
|
|
|
11542
11584
|
var import_picocolors15, MCP_PROVIDER_SLUG = "dosu_mcp";
|
|
11543
11585
|
var init_deployments = __esm(() => {
|
|
11544
11586
|
init_commander();
|
|
11587
|
+
init_command_error();
|
|
11545
11588
|
init_client();
|
|
11546
11589
|
init_trpc();
|
|
11547
11590
|
init_config();
|
|
@@ -14290,7 +14333,7 @@ var init_conflicts = __esm(() => {
|
|
|
14290
14333
|
});
|
|
14291
14334
|
|
|
14292
14335
|
// src/telemetry/debug-id.ts
|
|
14293
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
14336
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "fa693edb-14f4-abcb-6475-6e2164756e21";
|
|
14294
14337
|
|
|
14295
14338
|
// src/telemetry/telemetry.ts
|
|
14296
14339
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -15089,10 +15132,11 @@ function createCommandTelemetry(settings, dependencies = {}) {
|
|
|
15089
15132
|
};
|
|
15090
15133
|
}
|
|
15091
15134
|
function shouldSendToSentry(error) {
|
|
15092
|
-
return !
|
|
15135
|
+
return !EXPECTED_STATE_ERROR_CODES.has(error.code ?? "");
|
|
15093
15136
|
}
|
|
15094
|
-
var REQUEST_TIMEOUT_MS = 500, MAX_RESPONSE_BYTES, MAX_STACK_FRAMES = 20, UNKNOWN_COMMAND = "unknown", FALLBACK_INSTALL_ID = "00000000-0000-4000-8000-000000000000", BUNDLE_CODE_FILE = "app:///bin/dosu.js", CLI_PACKAGE_ROOT, SAFE_ERROR_TYPES, SAFE_ERROR_CODES, SYNC_TRIGGERS, SYNC_STATUSES, LEARNER_OUTCOMES, GATEWAY_REASONS, CLAUDE_CODE_SOURCES, SETTINGS_CONFLICT_KEYS, SETTINGS_CONFLICT_FAMILIES, MAX_CONFLICT_KEYS_LENGTH = 200, CLAUDE_CODE_VERSION_PATTERN, LEARNER_MODEL_PATTERN, BACKFILL_OFFERS, SENTRY_FACET_TAGS, pendingFacets;
|
|
15137
|
+
var REQUEST_TIMEOUT_MS = 500, MAX_RESPONSE_BYTES, MAX_STACK_FRAMES = 20, UNKNOWN_COMMAND = "unknown", FALLBACK_INSTALL_ID = "00000000-0000-4000-8000-000000000000", BUNDLE_CODE_FILE = "app:///bin/dosu.js", CLI_PACKAGE_ROOT, SAFE_ERROR_TYPES, SAFE_ERROR_CODES, EXPECTED_STATE_ERROR_CODES, SYNC_TRIGGERS, SYNC_STATUSES, LEARNER_OUTCOMES, GATEWAY_REASONS, CLAUDE_CODE_SOURCES, SETTINGS_CONFLICT_KEYS, SETTINGS_CONFLICT_FAMILIES, MAX_CONFLICT_KEYS_LENGTH = 200, CLAUDE_CODE_VERSION_PATTERN, LEARNER_MODEL_PATTERN, BACKFILL_OFFERS, SENTRY_FACET_TAGS, pendingFacets;
|
|
15095
15138
|
var init_telemetry = __esm(() => {
|
|
15139
|
+
init_command_error();
|
|
15096
15140
|
init_conflicts();
|
|
15097
15141
|
MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
15098
15142
|
CLI_PACKAGE_ROOT = detectCliPackageRoot();
|
|
@@ -15173,7 +15217,13 @@ var init_telemetry = __esm(() => {
|
|
|
15173
15217
|
"commander.missingMandatoryOptionValue",
|
|
15174
15218
|
"commander.optionMissingArgument",
|
|
15175
15219
|
"commander.unknownCommand",
|
|
15176
|
-
"commander.unknownOption"
|
|
15220
|
+
"commander.unknownOption",
|
|
15221
|
+
...COMMAND_ERROR_CODES
|
|
15222
|
+
]);
|
|
15223
|
+
EXPECTED_STATE_ERROR_CODES = new Set([
|
|
15224
|
+
"SESSION_EXPIRED",
|
|
15225
|
+
"SESSION_PERSISTENCE_ERROR",
|
|
15226
|
+
...COMMAND_ERROR_CODES
|
|
15177
15227
|
]);
|
|
15178
15228
|
SYNC_TRIGGERS = new Set(["hook", "manual", "bootstrap"]);
|
|
15179
15229
|
SYNC_STATUSES = new Set([
|
|
@@ -60317,25 +60367,27 @@ function bareMessageId(id) {
|
|
|
60317
60367
|
function truncateId(id) {
|
|
60318
60368
|
return (isDraftId(id) ? bareMessageId(id) : id).slice(0, 8);
|
|
60319
60369
|
}
|
|
60370
|
+
function reviewItemNotFound(id) {
|
|
60371
|
+
return new CommandError("REVIEW_ITEM_NOT_FOUND", `No review item found for '${id}'. Run 'dosu review list' to see pending items.`);
|
|
60372
|
+
}
|
|
60320
60373
|
async function requireChange(client, id) {
|
|
60321
60374
|
try {
|
|
60322
60375
|
return await client.review.getChange.query({ id });
|
|
60323
60376
|
} catch (err) {
|
|
60324
|
-
if (isNotFound(err) || isInvalidId(err))
|
|
60325
|
-
|
|
60326
|
-
process.exit(1);
|
|
60327
|
-
}
|
|
60377
|
+
if (isNotFound(err) || isInvalidId(err))
|
|
60378
|
+
throw reviewItemNotFound(id);
|
|
60328
60379
|
throw err;
|
|
60329
60380
|
}
|
|
60330
60381
|
}
|
|
60331
60382
|
async function requireDraft(client, id) {
|
|
60332
60383
|
const draft = await client.messages.getMessage.query(bareMessageId(id));
|
|
60333
|
-
if (!draft)
|
|
60334
|
-
|
|
60335
|
-
process.exit(1);
|
|
60336
|
-
}
|
|
60384
|
+
if (!draft)
|
|
60385
|
+
throw reviewItemNotFound(id);
|
|
60337
60386
|
return draft;
|
|
60338
60387
|
}
|
|
60388
|
+
function invalidArgument(message) {
|
|
60389
|
+
return new CommandError("INVALID_ARGUMENT", message);
|
|
60390
|
+
}
|
|
60339
60391
|
function humanizeSource(origin, version) {
|
|
60340
60392
|
switch (origin) {
|
|
60341
60393
|
case "manual_update":
|
|
@@ -60387,10 +60439,8 @@ function printDraftPreview(draft) {
|
|
|
60387
60439
|
console.log();
|
|
60388
60440
|
console.log(draft.body ?? "");
|
|
60389
60441
|
}
|
|
60390
|
-
function failScope(message, hint = SELECT_LIBRARY_HINT) {
|
|
60391
|
-
|
|
60392
|
-
console.error(import_picocolors27.default.dim(hint));
|
|
60393
|
-
process.exit(1);
|
|
60442
|
+
function failScope(code, message, hint = SELECT_LIBRARY_HINT) {
|
|
60443
|
+
throw new CommandError(code, message, [hint]);
|
|
60394
60444
|
}
|
|
60395
60445
|
async function lookupLibrary(client, spaceId) {
|
|
60396
60446
|
try {
|
|
@@ -60409,13 +60459,13 @@ async function resolveReviewScope(client, spaceId, deploymentId) {
|
|
|
60409
60459
|
deploymentId ? client.workspaces.get.query(deploymentId) : Promise.resolve(undefined)
|
|
60410
60460
|
]);
|
|
60411
60461
|
if (deploymentId && !deployment) {
|
|
60412
|
-
failScope(`The selected MCP deployment (${deploymentId}) is unavailable: it was deleted, or the ` + "signed-in account cannot access it.");
|
|
60462
|
+
failScope("DEPLOYMENT_UNAVAILABLE", `The selected MCP deployment (${deploymentId}) is unavailable: it was deleted, or the ` + "signed-in account cannot access it.");
|
|
60413
60463
|
}
|
|
60414
60464
|
if (deployment && deployment.space_id !== spaceId) {
|
|
60415
|
-
failScope(`The saved Library (${spaceId}) does not match the Library of the selected MCP ` + `deployment (${deployment.space_id}).`, `Run 'dosu deployments switch ${deployment.deployment_id}' to save that deployment's ` + "Library again, or choose another MCP deployment with 'dosu deployments list'.");
|
|
60465
|
+
failScope("SCOPE_MISMATCH", `The saved Library (${spaceId}) does not match the Library of the selected MCP ` + `deployment (${deployment.space_id}).`, `Run 'dosu deployments switch ${deployment.deployment_id}' to save that deployment's ` + "Library again, or choose another MCP deployment with 'dosu deployments list'.");
|
|
60416
60466
|
}
|
|
60417
60467
|
if (!library.found || !store) {
|
|
60418
|
-
failScope(`The selected Library (${spaceId}) is unavailable: it was deleted, or the signed-in ` + "account cannot access it.");
|
|
60468
|
+
failScope("LIBRARY_UNAVAILABLE", `The selected Library (${spaceId}) is unavailable: it was deleted, or the signed-in ` + "account cannot access it.");
|
|
60419
60469
|
}
|
|
60420
60470
|
return {
|
|
60421
60471
|
knowledgeStoreId: store.id,
|
|
@@ -60443,15 +60493,14 @@ function reviewCommand() {
|
|
|
60443
60493
|
try {
|
|
60444
60494
|
range = resolveTimeRange(opts.since, opts.until);
|
|
60445
60495
|
} catch (err) {
|
|
60446
|
-
|
|
60447
|
-
process.exit(1);
|
|
60496
|
+
throw invalidArgument(`${err.message}.`);
|
|
60448
60497
|
}
|
|
60449
60498
|
const rangeLabel = describeTimeRange(range);
|
|
60450
60499
|
const inRange = rangeLabel ? ` ${rangeLabel}` : "";
|
|
60451
60500
|
const cfg = requireConfig10();
|
|
60452
60501
|
const target = cfg.active_account?.target;
|
|
60453
60502
|
if (!target?.space_id) {
|
|
60454
|
-
failScope("No Library selected. The review list reads the Library of the selected MCP deployment.");
|
|
60503
|
+
failScope("NO_LIBRARY_SELECTED", "No Library selected. The review list reads the Library of the selected MCP deployment.");
|
|
60455
60504
|
}
|
|
60456
60505
|
const client = createTypedClient(cfg);
|
|
60457
60506
|
const scope = await resolveReviewScope(client, target.space_id, target.deployment_id);
|
|
@@ -60532,30 +60581,22 @@ function reviewCommand() {
|
|
|
60532
60581
|
const cfg = requireConfig10();
|
|
60533
60582
|
const client = createTypedClient(cfg);
|
|
60534
60583
|
if (opts.body !== undefined && opts.bodyFile !== undefined) {
|
|
60535
|
-
|
|
60536
|
-
process.exit(1);
|
|
60584
|
+
throw invalidArgument("Pass only one of --body or --body-file.");
|
|
60537
60585
|
}
|
|
60538
60586
|
let body = opts.body;
|
|
60539
60587
|
if (opts.bodyFile) {
|
|
60540
60588
|
try {
|
|
60541
60589
|
body = readFileSync19(opts.bodyFile, "utf-8");
|
|
60542
60590
|
} catch (err) {
|
|
60543
|
-
|
|
60544
|
-
process.exit(1);
|
|
60591
|
+
throw invalidArgument(`Failed to read --body-file: ${err.message}`);
|
|
60545
60592
|
}
|
|
60546
60593
|
}
|
|
60547
60594
|
if (body === undefined && opts.title === undefined) {
|
|
60548
|
-
|
|
60549
|
-
process.exit(1);
|
|
60595
|
+
throw invalidArgument("Nothing to edit. Pass --title and/or --body/--body-file.");
|
|
60550
60596
|
}
|
|
60551
60597
|
if (isDraftId(id)) {
|
|
60552
|
-
if (opts.title !== undefined) {
|
|
60553
|
-
|
|
60554
|
-
process.exit(1);
|
|
60555
|
-
}
|
|
60556
|
-
if (body === undefined) {
|
|
60557
|
-
console.error(import_picocolors27.default.red("Draft replies require --body or --body-file."));
|
|
60558
|
-
process.exit(1);
|
|
60598
|
+
if (opts.title !== undefined || body === undefined) {
|
|
60599
|
+
throw invalidArgument("Draft replies support --body only (no --title).");
|
|
60559
60600
|
}
|
|
60560
60601
|
await requireDraft(client, id);
|
|
60561
60602
|
await client.messages.saveDraft.mutate({
|
|
@@ -60571,8 +60612,7 @@ function reviewCommand() {
|
|
|
60571
60612
|
});
|
|
60572
60613
|
} catch (err) {
|
|
60573
60614
|
if (isNotFound(err)) {
|
|
60574
|
-
|
|
60575
|
-
process.exit(1);
|
|
60615
|
+
throw new CommandError("REVIEW_ITEM_NOT_FOUND", `No pending review item found for '${id}'. Run 'dosu review list' to see editable items.`);
|
|
60576
60616
|
}
|
|
60577
60617
|
throw err;
|
|
60578
60618
|
}
|
|
@@ -60653,8 +60693,7 @@ function reviewCommand() {
|
|
|
60653
60693
|
const client = createTypedClient(cfg);
|
|
60654
60694
|
if (isDraftId(id)) {
|
|
60655
60695
|
await requireDraft(client, id);
|
|
60656
|
-
|
|
60657
|
-
process.exit(1);
|
|
60696
|
+
throw invalidArgument("Revert is not supported for draft replies. A rejected draft is regenerated on the next agent run.");
|
|
60658
60697
|
}
|
|
60659
60698
|
await requireChange(client, id);
|
|
60660
60699
|
await client.page.updatePublicationStatus.mutate({
|
|
@@ -60674,6 +60713,7 @@ var import_picocolors27, DRAFT_MESSAGE_ID_PREFIX = "draft_message:", SELECT_LIBR
|
|
|
60674
60713
|
var init_review = __esm(() => {
|
|
60675
60714
|
init_dist();
|
|
60676
60715
|
init_commander();
|
|
60716
|
+
init_command_error();
|
|
60677
60717
|
init_trpc();
|
|
60678
60718
|
init_auth();
|
|
60679
60719
|
init_confirmation();
|
|
@@ -60767,7 +60807,7 @@ Use [commands.md](references/commands.md) as the sole detailed command and flag
|
|
|
60767
60807
|
## Handle failures literally
|
|
60768
60808
|
|
|
60769
60809
|
- \`Not logged in\` or an unrecoverable expired session: run \`dosu login\` (agent setup may instead return a ticket flow).
|
|
60770
|
-
- Missing organization, Library, deployment, or API-key context:
|
|
60810
|
+
- Missing or unavailable organization, Library, deployment, or API-key context: tell the user which \`dosu setup\` flow fixes it. Plain \`dosu setup\` is interactive, so don't start it for them unless they ask.
|
|
60771
60811
|
- Wrong or unexpected Library context: read \`dosu status --json\` and \`dosu deployments info --json\` before changing anything. Switch only to an MCP deployment the user named or confirmed; never pick the first one listed, and never switch just because a list came back empty.
|
|
60772
60812
|
- Skill guidance out of date: \`dosu skill update\` rewrites the installed skill from the running CLI version. Some agents read skills only when a session starts, so start a new session if the change does not appear. Installed files show the skill is on disk, not that the agent loaded it.
|
|
60773
60813
|
- \`confirmRequired\`: no write occurred.
|
|
@@ -62452,6 +62492,65 @@ var init_topics = __esm(() => {
|
|
|
62452
62492
|
import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
62453
62493
|
});
|
|
62454
62494
|
|
|
62495
|
+
// src/mcp/shape.ts
|
|
62496
|
+
function shapeEndpoint(cfg) {
|
|
62497
|
+
const url = cfg?.mode === MODE_OSS ? mcpEndpoint(cfg) : mcpURL(ANY);
|
|
62498
|
+
return ANY + url.slice(getBackendURL().length);
|
|
62499
|
+
}
|
|
62500
|
+
function escapeRegExp(text) {
|
|
62501
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
62502
|
+
}
|
|
62503
|
+
function hasShape(expected, actual) {
|
|
62504
|
+
if (typeof expected === "string") {
|
|
62505
|
+
if (typeof actual !== "string")
|
|
62506
|
+
return false;
|
|
62507
|
+
if (!expected.includes(ANY))
|
|
62508
|
+
return expected === actual;
|
|
62509
|
+
const pattern = expected.split(ANY).map(escapeRegExp).join("[\\s\\S]*");
|
|
62510
|
+
return new RegExp(`^${pattern}$`).test(actual);
|
|
62511
|
+
}
|
|
62512
|
+
if (Array.isArray(expected)) {
|
|
62513
|
+
return Array.isArray(actual) && actual.length === expected.length && expected.every((item, i) => hasShape(item, actual[i]));
|
|
62514
|
+
}
|
|
62515
|
+
if (typeof expected === "object" && expected !== null) {
|
|
62516
|
+
if (typeof actual !== "object" || actual === null || Array.isArray(actual))
|
|
62517
|
+
return false;
|
|
62518
|
+
const expectedKeys = Object.keys(expected);
|
|
62519
|
+
const actualRecord = actual;
|
|
62520
|
+
return expectedKeys.length === Object.keys(actualRecord).length && expectedKeys.every((key) => (key in actualRecord) && hasShape(expected[key], actualRecord[key]));
|
|
62521
|
+
}
|
|
62522
|
+
return expected === actual;
|
|
62523
|
+
}
|
|
62524
|
+
function withoutUserChoices(entry) {
|
|
62525
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
62526
|
+
return entry;
|
|
62527
|
+
return Object.fromEntries(Object.entries(entry).filter(([key]) => !USER_CHOICE_KEYS.has(key)));
|
|
62528
|
+
}
|
|
62529
|
+
function entryHasShape(expected, actual) {
|
|
62530
|
+
return hasShape(withoutUserChoices(expected), withoutUserChoices(actual));
|
|
62531
|
+
}
|
|
62532
|
+
var ANY = "\x00any\x00", USER_CHOICE_KEYS;
|
|
62533
|
+
var init_shape = __esm(() => {
|
|
62534
|
+
init_config();
|
|
62535
|
+
init_config_helpers();
|
|
62536
|
+
USER_CHOICE_KEYS = new Set([
|
|
62537
|
+
"disabled",
|
|
62538
|
+
"enabled",
|
|
62539
|
+
"autoApprove",
|
|
62540
|
+
"disabledTools",
|
|
62541
|
+
"timeout",
|
|
62542
|
+
"trust",
|
|
62543
|
+
"includeTools",
|
|
62544
|
+
"excludeTools",
|
|
62545
|
+
"enabled_tools",
|
|
62546
|
+
"disabled_tools",
|
|
62547
|
+
"default_tools_approval_mode",
|
|
62548
|
+
"required",
|
|
62549
|
+
"startup_timeout_sec",
|
|
62550
|
+
"tool_timeout_sec"
|
|
62551
|
+
]);
|
|
62552
|
+
});
|
|
62553
|
+
|
|
62455
62554
|
// src/mcp/providers/base.ts
|
|
62456
62555
|
function createJSONProvider(opts) {
|
|
62457
62556
|
const buildServer = opts.buildServer ?? defaultBuildServer;
|
|
@@ -62464,6 +62563,7 @@ function createJSONProvider(opts) {
|
|
|
62464
62563
|
isInstalled: () => isInstalled(opts.paths),
|
|
62465
62564
|
globalConfigPath: () => expandHome(opts.globalPath),
|
|
62466
62565
|
isConfigured: () => isJSONKeyConfigured(expandHome(opts.globalPath), opts.topKey),
|
|
62566
|
+
isCurrent: (cfg) => entryHasShape(buildServer({ url: shapeEndpoint(cfg), headers: mcpHeaders(ANY) }), readJSONServer(expandHome(opts.globalPath), opts.topKey)),
|
|
62467
62567
|
install(cfg, global2) {
|
|
62468
62568
|
const endpoint = {
|
|
62469
62569
|
url: mcpEndpoint(cfg),
|
|
@@ -62477,7 +62577,7 @@ function createJSONProvider(opts) {
|
|
|
62477
62577
|
} else {
|
|
62478
62578
|
throw new Error(`${opts.providerName} does not support local installation`);
|
|
62479
62579
|
}
|
|
62480
|
-
installJSONServer(configPath, opts.topKey, buildServer(endpoint
|
|
62580
|
+
installJSONServer(configPath, opts.topKey, buildServer(endpoint));
|
|
62481
62581
|
},
|
|
62482
62582
|
remove(global2) {
|
|
62483
62583
|
let configPath;
|
|
@@ -62500,6 +62600,7 @@ var defaultBuildServer = ({ url, headers }) => ({
|
|
|
62500
62600
|
var init_base = __esm(() => {
|
|
62501
62601
|
init_config_helpers();
|
|
62502
62602
|
init_detect();
|
|
62603
|
+
init_shape();
|
|
62503
62604
|
});
|
|
62504
62605
|
|
|
62505
62606
|
// src/mcp/providers/antigravity.ts
|
|
@@ -62551,17 +62652,13 @@ var ClaudeDesktopProvider = () => ({
|
|
|
62551
62652
|
isInstalled: () => isInstalled([join26(appSupportDir(), "Claude")]),
|
|
62552
62653
|
globalConfigPath: () => configPath(),
|
|
62553
62654
|
isConfigured: () => isJSONKeyConfigured(configPath(), "mcpServers"),
|
|
62655
|
+
isCurrent: (cfg) => entryHasShape(npxRemoteEntry(shapeEndpoint(cfg), ANY, ANY, npxPathEnv(join26(ANY, "npx"))), readJSONServer(configPath(), "mcpServers")),
|
|
62554
62656
|
install(cfg, global2) {
|
|
62555
62657
|
if (!global2)
|
|
62556
62658
|
throw new Error("Claude Desktop does not support local installation");
|
|
62557
62659
|
const url = mcpEndpoint(cfg);
|
|
62558
62660
|
const npx = findNpx();
|
|
62559
|
-
|
|
62560
|
-
installJSONServer(configPath(), "mcpServers", {
|
|
62561
|
-
command: npx,
|
|
62562
|
-
args: remote.args,
|
|
62563
|
-
env: { PATH: npxPathEnv(npx), ...remote.env }
|
|
62564
|
-
});
|
|
62661
|
+
installJSONServer(configPath(), "mcpServers", npxRemoteEntry(url, cfg.active_account?.target?.api_key, npx, npxPathEnv(npx)));
|
|
62565
62662
|
},
|
|
62566
62663
|
remove(global2) {
|
|
62567
62664
|
if (!global2)
|
|
@@ -62572,6 +62669,7 @@ var ClaudeDesktopProvider = () => ({
|
|
|
62572
62669
|
var init_claude_desktop = __esm(() => {
|
|
62573
62670
|
init_config_helpers();
|
|
62574
62671
|
init_detect();
|
|
62672
|
+
init_shape();
|
|
62575
62673
|
});
|
|
62576
62674
|
|
|
62577
62675
|
// src/mcp/providers/cline.ts
|
|
@@ -62643,25 +62741,70 @@ function writeTOML(path, content) {
|
|
|
62643
62741
|
function tomlString(value) {
|
|
62644
62742
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
62645
62743
|
}
|
|
62744
|
+
function tomlValue(value) {
|
|
62745
|
+
return Array.isArray(value) ? `[${value.map(tomlString).join(", ")}]` : tomlString(value);
|
|
62746
|
+
}
|
|
62747
|
+
function dosuEntry(url, apiKey, npx, path) {
|
|
62748
|
+
return npxRemoteEntry(url, apiKey, npx, path);
|
|
62749
|
+
}
|
|
62750
|
+
function renderDosuEntry(entry) {
|
|
62751
|
+
const tables = [["mcp_servers.dosu", {}]];
|
|
62752
|
+
for (const [key, value] of Object.entries(entry)) {
|
|
62753
|
+
if (typeof value === "string" || Array.isArray(value))
|
|
62754
|
+
tables[0][1][key] = value;
|
|
62755
|
+
else
|
|
62756
|
+
tables.push([`mcp_servers.dosu.${key}`, value]);
|
|
62757
|
+
}
|
|
62758
|
+
return tables.map(([name, keys]) => {
|
|
62759
|
+
const lines = Object.entries(keys).map(([key, value]) => `${key} = ${tomlValue(value)}`);
|
|
62760
|
+
return `
|
|
62761
|
+
[${name}]
|
|
62762
|
+
${lines.join(`
|
|
62763
|
+
`)}
|
|
62764
|
+
`;
|
|
62765
|
+
}).join("");
|
|
62766
|
+
}
|
|
62767
|
+
function isToolApproval(name) {
|
|
62768
|
+
return name.startsWith("mcp_servers.dosu.tools.");
|
|
62769
|
+
}
|
|
62770
|
+
function readDosuEntry(content) {
|
|
62771
|
+
let entry;
|
|
62772
|
+
let table;
|
|
62773
|
+
for (const line of content.split(`
|
|
62774
|
+
`)) {
|
|
62775
|
+
const name = sectionName(line);
|
|
62776
|
+
if (name !== null) {
|
|
62777
|
+
table = undefined;
|
|
62778
|
+
if (!isDosuSection(name) || isToolApproval(name))
|
|
62779
|
+
continue;
|
|
62780
|
+
entry ??= {};
|
|
62781
|
+
if (name === "mcp_servers.dosu") {
|
|
62782
|
+
table = entry;
|
|
62783
|
+
} else {
|
|
62784
|
+
table = {};
|
|
62785
|
+
entry[name.slice("mcp_servers.dosu.".length)] = table;
|
|
62786
|
+
}
|
|
62787
|
+
continue;
|
|
62788
|
+
}
|
|
62789
|
+
const text = line.trim();
|
|
62790
|
+
if (!table || !text || text.startsWith("#"))
|
|
62791
|
+
continue;
|
|
62792
|
+
const eq = text.indexOf("=");
|
|
62793
|
+
const key = eq === -1 ? text : text.slice(0, eq).trim();
|
|
62794
|
+
const raw = eq === -1 ? "" : text.slice(eq + 1).trim();
|
|
62795
|
+
try {
|
|
62796
|
+
table[key] = JSON.parse(raw);
|
|
62797
|
+
} catch {
|
|
62798
|
+
table[key] = raw;
|
|
62799
|
+
}
|
|
62800
|
+
}
|
|
62801
|
+
return entry;
|
|
62802
|
+
}
|
|
62646
62803
|
function installDosuToTOML(path, cfg) {
|
|
62647
|
-
|
|
62648
|
-
content = removeDosuFromTOML(content);
|
|
62804
|
+
const content = removeDosuFromTOML(readTOML(path));
|
|
62649
62805
|
const npx = findNpx();
|
|
62650
|
-
const
|
|
62651
|
-
|
|
62652
|
-
const envEntries = Object.entries(env).map(([key, value]) => `${key} = ${tomlString(value)}`).join(`
|
|
62653
|
-
`);
|
|
62654
|
-
const args = remote.args.map(tomlString).join(", ");
|
|
62655
|
-
const section = `
|
|
62656
|
-
[mcp_servers.dosu]
|
|
62657
|
-
command = ${tomlString(npx)}
|
|
62658
|
-
args = [${args}]
|
|
62659
|
-
` + `
|
|
62660
|
-
[mcp_servers.dosu.env]
|
|
62661
|
-
${envEntries}
|
|
62662
|
-
`;
|
|
62663
|
-
content += section;
|
|
62664
|
-
writeTOML(path, content);
|
|
62806
|
+
const entry = dosuEntry(mcpEndpoint(cfg), cfg.active_account?.target?.api_key, npx, npxPathEnv(npx));
|
|
62807
|
+
writeTOML(path, content + renderDosuEntry(entry));
|
|
62665
62808
|
}
|
|
62666
62809
|
function sectionName(line) {
|
|
62667
62810
|
const header = line.trim();
|
|
@@ -62739,6 +62882,7 @@ var REMOTE_HTTP_KEY, CodexProvider = () => ({
|
|
|
62739
62882
|
const content = readTOML(join29(codexHome3(), "config.toml"));
|
|
62740
62883
|
return content.includes("[mcp_servers.dosu]");
|
|
62741
62884
|
},
|
|
62885
|
+
isCurrent: (cfg) => entryHasShape(dosuEntry(shapeEndpoint(cfg), ANY, ANY, npxPathEnv(join29(ANY, "npx"))), readDosuEntry(readTOML(join29(codexHome3(), "config.toml")))),
|
|
62742
62886
|
install(cfg, global2) {
|
|
62743
62887
|
if (cfg.mode !== MODE_OSS && !cfg.active_account?.target?.deployment_id)
|
|
62744
62888
|
throw new Error("deployment ID is required");
|
|
@@ -62763,11 +62907,15 @@ var init_codex = __esm(() => {
|
|
|
62763
62907
|
init_config();
|
|
62764
62908
|
init_config_helpers();
|
|
62765
62909
|
init_detect();
|
|
62910
|
+
init_shape();
|
|
62766
62911
|
REMOTE_HTTP_KEY = /^(url|type|bearer_token_env_var)\s*=/;
|
|
62767
62912
|
});
|
|
62768
62913
|
|
|
62769
62914
|
// src/mcp/providers/copilot.ts
|
|
62770
62915
|
import { join as join30 } from "node:path";
|
|
62916
|
+
function globalServer(url, apiKey) {
|
|
62917
|
+
return { type: "http", url, tools: ["*"], headers: mcpHeaders(apiKey) };
|
|
62918
|
+
}
|
|
62771
62919
|
function globalPath() {
|
|
62772
62920
|
if (process.env.XDG_CONFIG_HOME) {
|
|
62773
62921
|
return join30(process.env.XDG_CONFIG_HOME, "mcp-config.json");
|
|
@@ -62783,16 +62931,11 @@ var CopilotProvider = () => ({
|
|
|
62783
62931
|
isInstalled: () => isInstalled([expandHome("~/.copilot")]),
|
|
62784
62932
|
globalConfigPath: () => globalPath(),
|
|
62785
62933
|
isConfigured: () => isJSONKeyConfigured(globalPath(), "mcpServers"),
|
|
62934
|
+
isCurrent: (cfg) => entryHasShape(globalServer(shapeEndpoint(cfg), ANY), readJSONServer(globalPath(), "mcpServers")),
|
|
62786
62935
|
install(cfg, global2) {
|
|
62787
62936
|
const url = mcpEndpoint(cfg);
|
|
62788
62937
|
if (global2) {
|
|
62789
|
-
|
|
62790
|
-
type: "http",
|
|
62791
|
-
url,
|
|
62792
|
-
tools: ["*"],
|
|
62793
|
-
headers: mcpHeaders(cfg.active_account.target.api_key)
|
|
62794
|
-
};
|
|
62795
|
-
installJSONServer(globalPath(), "mcpServers", server);
|
|
62938
|
+
installJSONServer(globalPath(), "mcpServers", globalServer(url, cfg.active_account?.target?.api_key));
|
|
62796
62939
|
} else {
|
|
62797
62940
|
const configPath = join30(process.cwd(), ".vscode", "mcp.json");
|
|
62798
62941
|
const server = {
|
|
@@ -62815,6 +62958,7 @@ var CopilotProvider = () => ({
|
|
|
62815
62958
|
var init_copilot = __esm(() => {
|
|
62816
62959
|
init_config_helpers();
|
|
62817
62960
|
init_detect();
|
|
62961
|
+
init_shape();
|
|
62818
62962
|
});
|
|
62819
62963
|
|
|
62820
62964
|
// src/mcp/providers/cursor.ts
|
|
@@ -62907,6 +63051,9 @@ var init_manual = __esm(() => {
|
|
|
62907
63051
|
// src/mcp/providers/mcporter.ts
|
|
62908
63052
|
import { existsSync as existsSync23 } from "node:fs";
|
|
62909
63053
|
import { join as join34 } from "node:path";
|
|
63054
|
+
function server(url, apiKey) {
|
|
63055
|
+
return { type: "http", url, headers: mcpHeaders(apiKey) };
|
|
63056
|
+
}
|
|
62910
63057
|
function resolveGlobalConfigPath() {
|
|
62911
63058
|
const jsonPath = expandHome("~/.mcporter/mcporter.json");
|
|
62912
63059
|
if (existsSync23(jsonPath))
|
|
@@ -62925,14 +63072,10 @@ var MCPorterProvider = () => ({
|
|
|
62925
63072
|
isInstalled: () => isInstalled(["~/.mcporter"]),
|
|
62926
63073
|
globalConfigPath: () => resolveGlobalConfigPath(),
|
|
62927
63074
|
isConfigured: () => isJSONKeyConfigured(resolveGlobalConfigPath(), "mcpServers"),
|
|
63075
|
+
isCurrent: (cfg) => entryHasShape(server(shapeEndpoint(cfg), ANY), readJSONServer(resolveGlobalConfigPath(), "mcpServers")),
|
|
62928
63076
|
install(cfg, global2) {
|
|
62929
63077
|
const configPath = global2 ? resolveGlobalConfigPath() : join34(process.cwd(), "config", "mcporter.json");
|
|
62930
|
-
|
|
62931
|
-
type: "http",
|
|
62932
|
-
url: mcpEndpoint(cfg),
|
|
62933
|
-
headers: mcpHeaders(cfg.active_account.target.api_key)
|
|
62934
|
-
};
|
|
62935
|
-
installJSONServer(configPath, "mcpServers", server);
|
|
63078
|
+
installJSONServer(configPath, "mcpServers", server(mcpEndpoint(cfg), cfg.active_account?.target?.api_key));
|
|
62936
63079
|
},
|
|
62937
63080
|
remove(global2) {
|
|
62938
63081
|
const configPath = global2 ? resolveGlobalConfigPath() : join34(process.cwd(), "config", "mcporter.json");
|
|
@@ -62942,6 +63085,7 @@ var MCPorterProvider = () => ({
|
|
|
62942
63085
|
var init_mcporter = __esm(() => {
|
|
62943
63086
|
init_config_helpers();
|
|
62944
63087
|
init_detect();
|
|
63088
|
+
init_shape();
|
|
62945
63089
|
});
|
|
62946
63090
|
|
|
62947
63091
|
// src/mcp/providers/opencode.ts
|
|
@@ -63055,6 +63199,7 @@ var ZedProvider = (legacyPath = legacyDarwinSettingsPath()) => {
|
|
|
63055
63199
|
return provider;
|
|
63056
63200
|
return {
|
|
63057
63201
|
...provider,
|
|
63202
|
+
isCurrent: (cfg) => provider.isCurrent(cfg) && readJSONServer(legacyPath, "context_servers") === undefined,
|
|
63058
63203
|
install(cfg, global2) {
|
|
63059
63204
|
provider.install(cfg, global2);
|
|
63060
63205
|
if (global2)
|
|
@@ -63133,9 +63278,21 @@ function configuredProviders() {
|
|
|
63133
63278
|
}
|
|
63134
63279
|
});
|
|
63135
63280
|
}
|
|
63281
|
+
function staleProviders(cfg) {
|
|
63282
|
+
return configuredProviders().filter((provider) => {
|
|
63283
|
+
try {
|
|
63284
|
+
return !provider.isCurrent(cfg);
|
|
63285
|
+
} catch {
|
|
63286
|
+
return true;
|
|
63287
|
+
}
|
|
63288
|
+
});
|
|
63289
|
+
}
|
|
63136
63290
|
function refreshConfiguredProviders(cfg) {
|
|
63291
|
+
return refreshProviders(cfg, configuredProviders());
|
|
63292
|
+
}
|
|
63293
|
+
function refreshProviders(cfg, providers) {
|
|
63137
63294
|
const result = { updated: [], failed: [] };
|
|
63138
|
-
for (const provider of
|
|
63295
|
+
for (const provider of providers) {
|
|
63139
63296
|
try {
|
|
63140
63297
|
provider.install(cfg, true);
|
|
63141
63298
|
logger.info("mcp", `Refreshed ${provider.name()} MCP entry`);
|
|
@@ -63347,199 +63504,18 @@ var init_auto_update = __esm(() => {
|
|
|
63347
63504
|
VERSION_PATTERN = /^[0-9A-Za-z.+-]{1,64}$/;
|
|
63348
63505
|
});
|
|
63349
63506
|
|
|
63350
|
-
// src/version/
|
|
63507
|
+
// src/version/mcp-refresh-check.ts
|
|
63351
63508
|
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync24, writeFileSync as writeFileSync16 } from "node:fs";
|
|
63352
63509
|
import { join as join40 } from "node:path";
|
|
63353
|
-
function isValidVersion2(value) {
|
|
63354
|
-
return typeof value === "string" && SEMVER_PATTERN.test(value);
|
|
63355
|
-
}
|
|
63356
|
-
function stripPrerelease(version) {
|
|
63357
|
-
return version.replace(/[-+].*$/, "");
|
|
63358
|
-
}
|
|
63359
|
-
function isNewerVersion(latest, current) {
|
|
63360
|
-
const a = stripPrerelease(latest).split(".").map(Number);
|
|
63361
|
-
const b = stripPrerelease(current).split(".").map(Number);
|
|
63362
|
-
const len = Math.max(a.length, b.length);
|
|
63363
|
-
for (let i = 0;i < len; i++) {
|
|
63364
|
-
const av = a[i] ?? 0;
|
|
63365
|
-
const bv = b[i] ?? 0;
|
|
63366
|
-
if (av > bv)
|
|
63367
|
-
return true;
|
|
63368
|
-
if (av < bv)
|
|
63369
|
-
return false;
|
|
63370
|
-
}
|
|
63371
|
-
return false;
|
|
63372
|
-
}
|
|
63373
63510
|
function getCachePath2() {
|
|
63374
63511
|
return join40(getConfigDir(), CACHE_FILENAME3);
|
|
63375
63512
|
}
|
|
63376
|
-
function
|
|
63513
|
+
function readMcpRefreshCache() {
|
|
63377
63514
|
try {
|
|
63378
63515
|
const path = getCachePath2();
|
|
63379
63516
|
if (!existsSync25(path))
|
|
63380
63517
|
return null;
|
|
63381
63518
|
const data = JSON.parse(readFileSync24(path, "utf-8"));
|
|
63382
|
-
if (typeof data.lastCheck === "number" && isValidVersion2(data.latestVersion)) {
|
|
63383
|
-
return data;
|
|
63384
|
-
}
|
|
63385
|
-
return null;
|
|
63386
|
-
} catch {
|
|
63387
|
-
return null;
|
|
63388
|
-
}
|
|
63389
|
-
}
|
|
63390
|
-
function writeCache(cache) {
|
|
63391
|
-
try {
|
|
63392
|
-
const dir = getConfigDir();
|
|
63393
|
-
if (!existsSync25(dir)) {
|
|
63394
|
-
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
63395
|
-
}
|
|
63396
|
-
writeFileSync16(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
63397
|
-
} catch {}
|
|
63398
|
-
}
|
|
63399
|
-
async function fetchLatestVersion() {
|
|
63400
|
-
const controller = new AbortController;
|
|
63401
|
-
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS2);
|
|
63402
|
-
try {
|
|
63403
|
-
const resp = await fetch(REGISTRY_URL, { signal: controller.signal });
|
|
63404
|
-
if (!resp.ok)
|
|
63405
|
-
return null;
|
|
63406
|
-
const data = await resp.json();
|
|
63407
|
-
const latest = data.latest;
|
|
63408
|
-
return isValidVersion2(latest) ? latest : null;
|
|
63409
|
-
} catch {
|
|
63410
|
-
return null;
|
|
63411
|
-
} finally {
|
|
63412
|
-
clearTimeout(timeout);
|
|
63413
|
-
}
|
|
63414
|
-
}
|
|
63415
|
-
function buildUpdateHint(channel, npx = false) {
|
|
63416
|
-
if (channel === "npm" && npx) {
|
|
63417
|
-
return 'Use "npx -y @dosu/cli@latest" for the next Dosu command';
|
|
63418
|
-
}
|
|
63419
|
-
return 'Run "dosu upgrade"';
|
|
63420
|
-
}
|
|
63421
|
-
function styleHint(hint) {
|
|
63422
|
-
const match = hint.match(/^(.*)("[^"]+")(.*)$/);
|
|
63423
|
-
if (!match)
|
|
63424
|
-
return import_picocolors32.default.dim(hint);
|
|
63425
|
-
const [, before, command, after] = match;
|
|
63426
|
-
return [before && import_picocolors32.default.dim(before), import_picocolors32.default.cyan(command), after && import_picocolors32.default.dim(after)].filter(Boolean).join("");
|
|
63427
|
-
}
|
|
63428
|
-
function framedNotice(content, width) {
|
|
63429
|
-
const innerWidth = Math.max(...content.map(visibleWidth2)) + BOX_PADDING * 2;
|
|
63430
|
-
const framed = (line) => {
|
|
63431
|
-
const pad = innerWidth - visibleWidth2(line);
|
|
63432
|
-
const left = Math.floor(pad / 2);
|
|
63433
|
-
return `${import_picocolors32.default.yellow("│")}${" ".repeat(left)}${line}${" ".repeat(pad - left)}${import_picocolors32.default.yellow("│")}`;
|
|
63434
|
-
};
|
|
63435
|
-
const box = [
|
|
63436
|
-
import_picocolors32.default.yellow(`╭${"─".repeat(innerWidth)}╮`),
|
|
63437
|
-
framed(""),
|
|
63438
|
-
...content.map(framed),
|
|
63439
|
-
framed(""),
|
|
63440
|
-
import_picocolors32.default.yellow(`╰${"─".repeat(innerWidth)}╯`)
|
|
63441
|
-
];
|
|
63442
|
-
return `
|
|
63443
|
-
${centerBlock(box, width).join(`
|
|
63444
|
-
`)}
|
|
63445
|
-
`;
|
|
63446
|
-
}
|
|
63447
|
-
function versionArrow(current, latest) {
|
|
63448
|
-
return `${import_picocolors32.default.dim(current)} ${import_picocolors32.default.dim("→")} ${import_picocolors32.default.bold(brand(latest))}`;
|
|
63449
|
-
}
|
|
63450
|
-
function buildAutoUpdateNotice(current, latest, interactive, width = process.stderr.columns ?? 80) {
|
|
63451
|
-
if (interactive) {
|
|
63452
|
-
return framedNotice([
|
|
63453
|
-
`Updating Dosu: ${versionArrow(current, latest)}`,
|
|
63454
|
-
import_picocolors32.default.dim("Installing in the background; your next command uses it")
|
|
63455
|
-
], width);
|
|
63456
|
-
}
|
|
63457
|
-
return `
|
|
63458
|
-
[dosu:update] Installing Dosu ${latest} in the background (running ${current}). ` + `The next Dosu command uses it; no action needed.
|
|
63459
|
-
`;
|
|
63460
|
-
}
|
|
63461
|
-
function buildUpdateNotice(current, latest, channel, interactive, npx = false, width = process.stderr.columns ?? 80) {
|
|
63462
|
-
const hint = buildUpdateHint(channel, npx);
|
|
63463
|
-
if (interactive) {
|
|
63464
|
-
return framedNotice([`Update available: ${versionArrow(current, latest)}`, styleHint(hint)], width);
|
|
63465
|
-
}
|
|
63466
|
-
const agentAction = hint[0].toLowerCase() + hint.slice(1);
|
|
63467
|
-
const verifyCommand = npx ? "npx -y @dosu/cli@latest --version" : "dosu --version";
|
|
63468
|
-
return `
|
|
63469
|
-
[dosu:update] Update available: ${current} → ${latest}
|
|
63470
|
-
` + `Tell the user Dosu CLI is outdated. After they approve, ${agentAction}, ` + `then verify with "${verifyCommand}".
|
|
63471
|
-
`;
|
|
63472
|
-
}
|
|
63473
|
-
function getAvailableUpdate() {
|
|
63474
|
-
const cache = readCache();
|
|
63475
|
-
return cache && isNewerVersion(cache.latestVersion, VERSION) ? cache.latestVersion : null;
|
|
63476
|
-
}
|
|
63477
|
-
function handleNewerVersion(latest, notify) {
|
|
63478
|
-
const autoUpdate = startAutoUpdate(latest);
|
|
63479
|
-
if (!notify)
|
|
63480
|
-
return;
|
|
63481
|
-
const interactive = process.stderr.isTTY === true;
|
|
63482
|
-
console.error(autoUpdate === "unavailable" ? buildUpdateNotice(VERSION, latest, INSTALL_CHANNEL, interactive, isNpxInvocation()) : buildAutoUpdateNotice(VERSION, latest, interactive));
|
|
63483
|
-
}
|
|
63484
|
-
async function checkForUpdates(options = {}) {
|
|
63485
|
-
const notify = options.notify ?? true;
|
|
63486
|
-
try {
|
|
63487
|
-
const cache = readCache();
|
|
63488
|
-
const isStale = !cache || Date.now() - cache.lastCheck > CHECK_INTERVAL_MS2;
|
|
63489
|
-
if (!isStale) {
|
|
63490
|
-
if (isNewerVersion(cache.latestVersion, VERSION)) {
|
|
63491
|
-
handleNewerVersion(cache.latestVersion, notify);
|
|
63492
|
-
}
|
|
63493
|
-
return;
|
|
63494
|
-
}
|
|
63495
|
-
const latest = await fetchLatestVersion();
|
|
63496
|
-
const latestKnownVersion = latest ?? cache?.latestVersion ?? VERSION;
|
|
63497
|
-
writeCache({
|
|
63498
|
-
lastCheck: Date.now(),
|
|
63499
|
-
latestVersion: latestKnownVersion
|
|
63500
|
-
});
|
|
63501
|
-
if (latest) {
|
|
63502
|
-
logger.debug("update-check", `Cached latest version: ${latest}`);
|
|
63503
|
-
}
|
|
63504
|
-
if (isNewerVersion(latestKnownVersion, VERSION)) {
|
|
63505
|
-
handleNewerVersion(latestKnownVersion, notify);
|
|
63506
|
-
}
|
|
63507
|
-
} catch (err) {
|
|
63508
|
-
logger.error("update-check", `Update check failed: ${err}`);
|
|
63509
|
-
}
|
|
63510
|
-
}
|
|
63511
|
-
var import_picocolors32, CACHE_FILENAME3 = "update-check.json", CHECK_INTERVAL_MS2, FETCH_TIMEOUT_MS2 = 1000, REGISTRY_URL = "https://registry.npmjs.org/-/package/@dosu/cli/dist-tags", SEMVER_PATTERN, BOX_PADDING = 3;
|
|
63512
|
-
var init_update_check = __esm(() => {
|
|
63513
|
-
init_config();
|
|
63514
|
-
init_logger();
|
|
63515
|
-
init_styles();
|
|
63516
|
-
init_layout();
|
|
63517
|
-
init_auto_update();
|
|
63518
|
-
import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
63519
|
-
CHECK_INTERVAL_MS2 = 6 * 60 * 60 * 1000;
|
|
63520
|
-
SEMVER_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
63521
|
-
});
|
|
63522
|
-
|
|
63523
|
-
// src/version/mcp-refresh-check.ts
|
|
63524
|
-
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync25, writeFileSync as writeFileSync17 } from "node:fs";
|
|
63525
|
-
import { join as join41 } from "node:path";
|
|
63526
|
-
function needsMcpRefresh(previous, current) {
|
|
63527
|
-
if (previous === null)
|
|
63528
|
-
return true;
|
|
63529
|
-
if (previous === current)
|
|
63530
|
-
return false;
|
|
63531
|
-
const [older, newer] = isNewerVersion(current, previous) ? [previous, current] : [current, previous];
|
|
63532
|
-
return MCP_FORMAT_CHANGES.some((change) => isNewerVersion(change, older) && !isNewerVersion(change, newer));
|
|
63533
|
-
}
|
|
63534
|
-
function getCachePath3() {
|
|
63535
|
-
return join41(getConfigDir(), CACHE_FILENAME4);
|
|
63536
|
-
}
|
|
63537
|
-
function readMcpRefreshCache() {
|
|
63538
|
-
try {
|
|
63539
|
-
const path = getCachePath3();
|
|
63540
|
-
if (!existsSync26(path))
|
|
63541
|
-
return null;
|
|
63542
|
-
const data = JSON.parse(readFileSync25(path, "utf-8"));
|
|
63543
63519
|
if (typeof data?.version === "string")
|
|
63544
63520
|
return { version: data.version };
|
|
63545
63521
|
return null;
|
|
@@ -63550,10 +63526,10 @@ function readMcpRefreshCache() {
|
|
|
63550
63526
|
function writeMcpRefreshCache(cache) {
|
|
63551
63527
|
try {
|
|
63552
63528
|
const dir = getConfigDir();
|
|
63553
|
-
if (!
|
|
63554
|
-
|
|
63529
|
+
if (!existsSync25(dir)) {
|
|
63530
|
+
mkdirSync15(dir, { recursive: true, mode: 448 });
|
|
63555
63531
|
}
|
|
63556
|
-
|
|
63532
|
+
writeFileSync16(getCachePath2(), JSON.stringify(cache), { mode: 384 });
|
|
63557
63533
|
} catch {}
|
|
63558
63534
|
}
|
|
63559
63535
|
function canRefreshMcp(cfg) {
|
|
@@ -63564,26 +63540,21 @@ function canRefreshMcp(cfg) {
|
|
|
63564
63540
|
}
|
|
63565
63541
|
function displayNotice(names) {
|
|
63566
63542
|
console.error(`
|
|
63567
|
-
${
|
|
63568
|
-
` + `${
|
|
63543
|
+
${import_picocolors32.default.green(`✓ Dosu ${VERSION}: refreshed MCP config for ${names.join(", ")}`)}
|
|
63544
|
+
` + `${import_picocolors32.default.dim(` Run ${import_picocolors32.default.cyan('"dosu setup"')} to also update hooks and rules, then restart your AI agents.`)}
|
|
63569
63545
|
`);
|
|
63570
63546
|
}
|
|
63571
63547
|
function checkForMcpRefresh(options = {}) {
|
|
63572
63548
|
const notify = options.notify ?? true;
|
|
63573
63549
|
try {
|
|
63574
|
-
|
|
63575
|
-
if (previous === VERSION)
|
|
63576
|
-
return;
|
|
63577
|
-
if (!needsMcpRefresh(previous, VERSION)) {
|
|
63578
|
-
writeMcpRefreshCache({ version: VERSION });
|
|
63550
|
+
if (readMcpRefreshCache()?.version === VERSION)
|
|
63579
63551
|
return;
|
|
63580
|
-
}
|
|
63581
63552
|
const cfg = loadConfigNonBlocking();
|
|
63582
63553
|
if (!cfg || !canRefreshMcp(cfg)) {
|
|
63583
63554
|
logger.debug("mcp-refresh", "Skipping MCP refresh: no API key or deployment configured");
|
|
63584
63555
|
return;
|
|
63585
63556
|
}
|
|
63586
|
-
const result =
|
|
63557
|
+
const result = refreshProviders(cfg, staleProviders(cfg));
|
|
63587
63558
|
writeMcpRefreshCache({ version: VERSION });
|
|
63588
63559
|
logger.info("mcp-refresh", `Version ${VERSION}: refreshed ${result.updated.length}, failed ${result.failed.length}`);
|
|
63589
63560
|
if (notify && result.updated.length > 0) {
|
|
@@ -63593,24 +63564,19 @@ function checkForMcpRefresh(options = {}) {
|
|
|
63593
63564
|
logger.error("mcp-refresh", `MCP refresh check failed: ${err}`);
|
|
63594
63565
|
}
|
|
63595
63566
|
}
|
|
63596
|
-
var
|
|
63567
|
+
var import_picocolors32, CACHE_FILENAME3 = "mcp-refresh.json";
|
|
63597
63568
|
var init_mcp_refresh_check = __esm(() => {
|
|
63598
63569
|
init_config();
|
|
63599
63570
|
init_logger();
|
|
63600
63571
|
init_refresh();
|
|
63601
|
-
|
|
63602
|
-
import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
63603
|
-
MCP_FORMAT_CHANGES = [
|
|
63604
|
-
"0.53.0",
|
|
63605
|
-
"0.62.0"
|
|
63606
|
-
];
|
|
63572
|
+
import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
63607
63573
|
});
|
|
63608
63574
|
|
|
63609
63575
|
// src/version/skill-update-check.ts
|
|
63610
63576
|
function displayNotice2() {
|
|
63611
63577
|
console.error(`
|
|
63612
|
-
${
|
|
63613
|
-
` + `${
|
|
63578
|
+
${import_picocolors33.default.green(`✓ Dosu ${VERSION}: refreshed the bundled agent skills`)}
|
|
63579
|
+
` + `${import_picocolors33.default.dim(" Restart your AI agents to pick up the new skill content.")}
|
|
63614
63580
|
`);
|
|
63615
63581
|
}
|
|
63616
63582
|
function checkForSkillUpdates(options = {}) {
|
|
@@ -63631,11 +63597,11 @@ function checkForSkillUpdates(options = {}) {
|
|
|
63631
63597
|
logger.error("skill-update-check", `Skill update check failed: ${err}`);
|
|
63632
63598
|
}
|
|
63633
63599
|
}
|
|
63634
|
-
var
|
|
63600
|
+
var import_picocolors33;
|
|
63635
63601
|
var init_skill_update_check = __esm(() => {
|
|
63636
63602
|
init_skill();
|
|
63637
63603
|
init_logger();
|
|
63638
|
-
|
|
63604
|
+
import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
63639
63605
|
});
|
|
63640
63606
|
|
|
63641
63607
|
// src/auth/errors.ts
|
|
@@ -63701,15 +63667,15 @@ function createLogFollower(path, emit) {
|
|
|
63701
63667
|
var init_follow = () => {};
|
|
63702
63668
|
|
|
63703
63669
|
// src/sessions/session-title.ts
|
|
63704
|
-
import { existsSync as
|
|
63670
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync16, readFileSync as readFileSync25, renameSync as renameSync7, statSync as statSync10, writeFileSync as writeFileSync17 } from "node:fs";
|
|
63705
63671
|
import { homedir as homedir11 } from "node:os";
|
|
63706
|
-
import { join as
|
|
63672
|
+
import { join as join41 } from "node:path";
|
|
63707
63673
|
function cachePath2(configDir) {
|
|
63708
|
-
return
|
|
63674
|
+
return join41(configDir, CACHE_FILENAME4);
|
|
63709
63675
|
}
|
|
63710
63676
|
function loadCacheFile2(configDir) {
|
|
63711
63677
|
try {
|
|
63712
|
-
const raw = JSON.parse(
|
|
63678
|
+
const raw = JSON.parse(readFileSync25(cachePath2(configDir), "utf-8"));
|
|
63713
63679
|
if (raw.schema_version !== CACHE_SCHEMA_VERSION2 || typeof raw.entries !== "object")
|
|
63714
63680
|
return {};
|
|
63715
63681
|
return raw.entries;
|
|
@@ -63719,12 +63685,12 @@ function loadCacheFile2(configDir) {
|
|
|
63719
63685
|
}
|
|
63720
63686
|
function saveCacheFile2(configDir, entries) {
|
|
63721
63687
|
try {
|
|
63722
|
-
if (!
|
|
63723
|
-
|
|
63688
|
+
if (!existsSync26(configDir))
|
|
63689
|
+
mkdirSync16(configDir, { recursive: true, mode: 448 });
|
|
63724
63690
|
const path = cachePath2(configDir);
|
|
63725
63691
|
const tmp = `${path}.${process.pid}.tmp`;
|
|
63726
63692
|
const file = { schema_version: CACHE_SCHEMA_VERSION2, entries };
|
|
63727
|
-
|
|
63693
|
+
writeFileSync17(tmp, JSON.stringify(file), { mode: 384 });
|
|
63728
63694
|
renameSync7(tmp, path);
|
|
63729
63695
|
} catch {}
|
|
63730
63696
|
}
|
|
@@ -63757,15 +63723,15 @@ function claudeSummaryFromHead(text) {
|
|
|
63757
63723
|
}
|
|
63758
63724
|
return null;
|
|
63759
63725
|
}
|
|
63760
|
-
function reconstructSession(harness, id, slug, home = homedir11(), exists =
|
|
63726
|
+
function reconstructSession(harness, id, slug, home = homedir11(), exists = existsSync26) {
|
|
63761
63727
|
if (!slug)
|
|
63762
63728
|
return null;
|
|
63763
63729
|
const candidates = [];
|
|
63764
63730
|
if (harness === "claude") {
|
|
63765
|
-
candidates.push(
|
|
63731
|
+
candidates.push(join41(home, ".claude", "projects", slug, `${id}.jsonl`));
|
|
63766
63732
|
} else if (harness === "cursor") {
|
|
63767
|
-
const project =
|
|
63768
|
-
candidates.push(
|
|
63733
|
+
const project = join41(home, ".cursor", "projects", slug);
|
|
63734
|
+
candidates.push(join41(project, "agent-transcripts", id, `${id}.jsonl`), join41(project, "agent-transcripts", `${id}.jsonl`));
|
|
63769
63735
|
} else {
|
|
63770
63736
|
return null;
|
|
63771
63737
|
}
|
|
@@ -63777,7 +63743,7 @@ function reconstructSession(harness, id, slug, home = homedir11(), exists = exis
|
|
|
63777
63743
|
}
|
|
63778
63744
|
function readHead2(path) {
|
|
63779
63745
|
try {
|
|
63780
|
-
return
|
|
63746
|
+
return readFileSync25(path, "utf-8").slice(0, 128 * 1024);
|
|
63781
63747
|
} catch {
|
|
63782
63748
|
return null;
|
|
63783
63749
|
}
|
|
@@ -63828,7 +63794,7 @@ function createSessionTitleResolver(configDir = getConfigDir(), deps = {}) {
|
|
|
63828
63794
|
}
|
|
63829
63795
|
};
|
|
63830
63796
|
}
|
|
63831
|
-
var
|
|
63797
|
+
var CACHE_FILENAME4 = "session-titles.json", CACHE_SCHEMA_VERSION2 = 3, HEAD_LINES2 = 50, SESSION_NAME_MAX = 80;
|
|
63832
63798
|
var init_session_title = __esm(() => {
|
|
63833
63799
|
init_config();
|
|
63834
63800
|
init_read();
|
|
@@ -63857,7 +63823,7 @@ var init_alt_screen = __esm(() => {
|
|
|
63857
63823
|
});
|
|
63858
63824
|
|
|
63859
63825
|
// src/tui/activity-view.ts
|
|
63860
|
-
import { existsSync as
|
|
63826
|
+
import { existsSync as existsSync27, readFileSync as readFileSync26 } from "node:fs";
|
|
63861
63827
|
import { basename as basename6 } from "node:path";
|
|
63862
63828
|
function reduceActivityViewKey(key) {
|
|
63863
63829
|
if (key === "q" || key === ESC7 || key === CTRL_C4)
|
|
@@ -63998,15 +63964,15 @@ function statusLine(status) {
|
|
|
63998
63964
|
if (status.running) {
|
|
63999
63965
|
const since = status.startedAt ? ` · since ${localTime(status.startedAt)}` : "";
|
|
64000
63966
|
const pid = status.pid !== undefined ? ` (pid ${status.pid})` : "";
|
|
64001
|
-
return `\uD83D\uDCDA ${
|
|
63967
|
+
return `\uD83D\uDCDA ${import_picocolors34.default.bold(brand("Studying sessions..."))}${import_picocolors34.default.dim(`${pid}${since}`)}`;
|
|
64002
63968
|
}
|
|
64003
63969
|
if (status.state.paused) {
|
|
64004
|
-
return `${
|
|
63970
|
+
return `${import_picocolors34.default.yellow("○")} ${import_picocolors34.default.bold("Paused")} ${import_picocolors34.default.dim("· studying stays off until you resume")}`;
|
|
64005
63971
|
}
|
|
64006
63972
|
if (status.staleLock) {
|
|
64007
|
-
return `${
|
|
63973
|
+
return `${import_picocolors34.default.yellow("○")} ${import_picocolors34.default.bold("Not running")} ${import_picocolors34.default.dim("· a previous run exited without cleaning up")}`;
|
|
64008
63974
|
}
|
|
64009
|
-
return `${
|
|
63975
|
+
return `${import_picocolors34.default.dim("○")} ${import_picocolors34.default.bold("Idle")} ${import_picocolors34.default.dim("· hooks study new sessions automatically")}`;
|
|
64010
63976
|
}
|
|
64011
63977
|
function progressLine(done, ready, width, notes = 0) {
|
|
64012
63978
|
const total = done + ready;
|
|
@@ -64015,7 +63981,7 @@ function progressLine(done, ready, width, notes = 0) {
|
|
|
64015
63981
|
const cells = Math.max(10, Math.min(30, width - 44));
|
|
64016
63982
|
const ratio = Math.max(0, Math.min(1, done / total));
|
|
64017
63983
|
const filled = Math.min(cells, Math.round(ratio * cells));
|
|
64018
|
-
const bar = brand("█".repeat(filled)) +
|
|
63984
|
+
const bar = brand("█".repeat(filled)) + import_picocolors34.default.dim("░".repeat(cells - filled));
|
|
64019
63985
|
const pct = Math.floor(ratio * 100);
|
|
64020
63986
|
const suffix = notes > 0 ? ` · ${notes} suggested page${notes === 1 ? "" : "s"}` : "";
|
|
64021
63987
|
return `${bar} ${done}/${total} studied · ${pct}%${suffix}`;
|
|
@@ -64054,17 +64020,17 @@ function confirmBox(queuedCount, backlog, width, mode = "start") {
|
|
|
64054
64020
|
const verb = mode === "clear" ? "clear" : mode === "stop" ? "stop" : mode === "resume" ? "resume" : "start";
|
|
64055
64021
|
const maxInner = Math.max(20, Math.min(width, contentWidth()) - 4);
|
|
64056
64022
|
const rows = [
|
|
64057
|
-
|
|
64058
|
-
...wrapLine(scope, maxInner, "").map((line) =>
|
|
64023
|
+
import_picocolors34.default.bold(brand(title)),
|
|
64024
|
+
...wrapLine(scope, maxInner, "").map((line) => import_picocolors34.default.dim(line)),
|
|
64059
64025
|
"",
|
|
64060
|
-
`${
|
|
64026
|
+
`${import_picocolors34.default.bold("enter")} ${verb} · ${import_picocolors34.default.bold("esc")} cancel`
|
|
64061
64027
|
];
|
|
64062
64028
|
const inner = Math.min(maxInner, Math.max(...rows.map(visibleWidth2)));
|
|
64063
64029
|
const pad = (row) => row + " ".repeat(Math.max(0, inner - visibleWidth2(row)));
|
|
64064
64030
|
return [
|
|
64065
|
-
|
|
64066
|
-
...rows.map((row) => `${
|
|
64067
|
-
|
|
64031
|
+
import_picocolors34.default.dim(`╭${"─".repeat(inner + 2)}╮`),
|
|
64032
|
+
...rows.map((row) => `${import_picocolors34.default.dim("│")} ${pad(row)} ${import_picocolors34.default.dim("│")}`),
|
|
64033
|
+
import_picocolors34.default.dim(`╰${"─".repeat(inner + 2)}╯`)
|
|
64068
64034
|
];
|
|
64069
64035
|
}
|
|
64070
64036
|
function buildActivityFrame(status, activity, width, backlog = null, pane = DEFAULT_PANE, queued = [], studiedBeforeRun = 0, open = [], runProgress = null, projectNames = {}, sessionNames = {}, frameLines) {
|
|
@@ -64080,7 +64046,7 @@ function buildActivityFrame(status, activity, width, backlog = null, pane = DEFA
|
|
|
64080
64046
|
progress = progressLine(studiedDelta + stepDone, Math.max(0, backlog.ready - stepDone), width, runProgress?.notes ?? 0);
|
|
64081
64047
|
}
|
|
64082
64048
|
const refusal = !status.running && status.state.last_refusal;
|
|
64083
|
-
const refusalLines = refusal ? wrapLine(`! Studying paused: ${refusal.message} (${localTime(refusal.at)})`, width).map((line) =>
|
|
64049
|
+
const refusalLines = refusal ? wrapLine(`! Studying paused: ${refusal.message} (${localTime(refusal.at)})`, width).map((line) => import_picocolors34.default.yellow(line)) : [];
|
|
64084
64050
|
const fullRows = Boolean(pane.fullRows);
|
|
64085
64051
|
const withName = (item, key) => projectNames[key] ? { ...item, project: projectNames[key] } : item;
|
|
64086
64052
|
const latestPass = new Map;
|
|
@@ -64106,8 +64072,8 @@ function buildActivityFrame(status, activity, width, backlog = null, pane = DEFA
|
|
|
64106
64072
|
breadcrumb(["home", "activity"], width),
|
|
64107
64073
|
"",
|
|
64108
64074
|
statusLine(status),
|
|
64109
|
-
|
|
64110
|
-
...queueDetail.length > 0 ? wrapLine(queueDetail.join(" · "), width).map((line) =>
|
|
64075
|
+
import_picocolors34.default.dim(studied),
|
|
64076
|
+
...queueDetail.length > 0 ? wrapLine(queueDetail.join(" · "), width).map((line) => import_picocolors34.default.dim(line)) : [],
|
|
64111
64077
|
...progress ? [progress] : [],
|
|
64112
64078
|
...refusalLines,
|
|
64113
64079
|
"",
|
|
@@ -64123,7 +64089,7 @@ function buildActivityFrame(status, activity, width, backlog = null, pane = DEFA
|
|
|
64123
64089
|
status.running ? "s stop" : status.state.paused ? "s resume" : "s sync now",
|
|
64124
64090
|
...!status.running && status.state.watermark ? ["c clear"] : [],
|
|
64125
64091
|
"esc back"
|
|
64126
|
-
].join(" · "), width, "").map((line) =>
|
|
64092
|
+
].join(" · "), width, "").map((line) => import_picocolors34.default.dim(line))
|
|
64127
64093
|
]
|
|
64128
64094
|
];
|
|
64129
64095
|
const defaultHeight = fullRows ? ACTIVITY_VIEW_FULL_LIST_ROWS : ACTIVITY_VIEW_LIST_LINES;
|
|
@@ -64136,7 +64102,7 @@ function buildActivityFrame(status, activity, width, backlog = null, pane = DEFA
|
|
|
64136
64102
|
({ visible, above, below } = windowList(source, pane.scroll, height));
|
|
64137
64103
|
display = visible.flatMap((row) => wrapRow(row, width));
|
|
64138
64104
|
}
|
|
64139
|
-
const listRows = display.length > 0 ? display.map((row) =>
|
|
64105
|
+
const listRows = display.length > 0 ? display.map((row) => import_picocolors34.default.dim(row)) : [import_picocolors34.default.dim(empty)];
|
|
64140
64106
|
const scrollParts = [];
|
|
64141
64107
|
if (above > 0)
|
|
64142
64108
|
scrollParts.push(`↑ ${above} earlier`);
|
|
@@ -64145,7 +64111,7 @@ function buildActivityFrame(status, activity, width, backlog = null, pane = DEFA
|
|
|
64145
64111
|
const lines = [
|
|
64146
64112
|
...header,
|
|
64147
64113
|
...listRows,
|
|
64148
|
-
...scrollParts.length > 0 ? [
|
|
64114
|
+
...scrollParts.length > 0 ? [import_picocolors34.default.dim(clip(scrollParts.join(" · "), width))] : [],
|
|
64149
64115
|
...footer
|
|
64150
64116
|
];
|
|
64151
64117
|
return { lines, listHeight: height };
|
|
@@ -64178,7 +64144,7 @@ function createRowNamer() {
|
|
|
64178
64144
|
names.titles[key] = t;
|
|
64179
64145
|
};
|
|
64180
64146
|
for (const s of [...backlog.queued, ...backlog.open]) {
|
|
64181
|
-
if (!
|
|
64147
|
+
if (!existsSync27(s.path))
|
|
64182
64148
|
continue;
|
|
64183
64149
|
const key = `${s.harness}/${s.id}`;
|
|
64184
64150
|
const dir = dirs.resolve(s);
|
|
@@ -64215,7 +64181,7 @@ function createRowNamer() {
|
|
|
64215
64181
|
}
|
|
64216
64182
|
function defaultReadLog2() {
|
|
64217
64183
|
try {
|
|
64218
|
-
return
|
|
64184
|
+
return readFileSync26(logger.getLogPath(), "utf-8");
|
|
64219
64185
|
} catch {
|
|
64220
64186
|
return "";
|
|
64221
64187
|
}
|
|
@@ -64400,7 +64366,7 @@ ${CLEAR_BELOW}`);
|
|
|
64400
64366
|
input.on("data", onData);
|
|
64401
64367
|
});
|
|
64402
64368
|
}
|
|
64403
|
-
var
|
|
64369
|
+
var import_picocolors34, ESC7, HIDE_CURSOR3, SHOW_CURSOR3, CTRL_C4, KEY_UP4, KEY_DOWN4, KEY_RIGHT3, KEY_LEFT3, CURSOR_HOME, CLEAR_BELOW, CLEAR_EOL, ACTIVITY_VIEW_POLL_MS = 500, ACTIVITY_VIEW_LIST_LINES = 10, ACTIVITY_VIEW_FULL_LIST_ROWS = 5, ACTIVITY_VIEW_BUFFER_LINES = 200, ACTIVITY_VIEW_TABS, DEFAULT_PANE, TITLE_READS_PER_DRAW = 25;
|
|
64404
64370
|
var init_activity_view = __esm(() => {
|
|
64405
64371
|
init_follow();
|
|
64406
64372
|
init_logger();
|
|
@@ -64415,7 +64381,7 @@ var init_activity_view = __esm(() => {
|
|
|
64415
64381
|
init_alt_screen();
|
|
64416
64382
|
init_layout();
|
|
64417
64383
|
init_menu();
|
|
64418
|
-
|
|
64384
|
+
import_picocolors34 = __toESM(require_picocolors(), 1);
|
|
64419
64385
|
ESC7 = String.fromCharCode(27);
|
|
64420
64386
|
HIDE_CURSOR3 = `${ESC7}[?25l`;
|
|
64421
64387
|
SHOW_CURSOR3 = `${ESC7}[?25h`;
|
|
@@ -64432,14 +64398,14 @@ var init_activity_view = __esm(() => {
|
|
|
64432
64398
|
});
|
|
64433
64399
|
|
|
64434
64400
|
// src/rules/installer.ts
|
|
64435
|
-
import { existsSync as
|
|
64401
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readFileSync as readFileSync27, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
|
|
64436
64402
|
import { homedir as homedir12 } from "node:os";
|
|
64437
|
-
import { dirname as dirname12, join as
|
|
64403
|
+
import { dirname as dirname12, join as join42 } from "node:path";
|
|
64438
64404
|
function claudeConfigDir4() {
|
|
64439
|
-
return process.env.CLAUDE_CONFIG_DIR ||
|
|
64405
|
+
return process.env.CLAUDE_CONFIG_DIR || join42(homedir12(), ".claude");
|
|
64440
64406
|
}
|
|
64441
64407
|
function codexHome4() {
|
|
64442
|
-
return process.env.CODEX_HOME ||
|
|
64408
|
+
return process.env.CODEX_HOME || join42(homedir12(), ".codex");
|
|
64443
64409
|
}
|
|
64444
64410
|
function isRuleAgent(agent) {
|
|
64445
64411
|
return Object.hasOwn(RULE_TARGETS, agent);
|
|
@@ -64465,17 +64431,17 @@ async function fetchDosuRule(fetchImpl = globalThis.fetch) {
|
|
|
64465
64431
|
return normalizeRule(FALLBACK_DOSU_RULE);
|
|
64466
64432
|
}
|
|
64467
64433
|
function ensureParent(path) {
|
|
64468
|
-
|
|
64434
|
+
mkdirSync17(dirname12(path), { recursive: true });
|
|
64469
64435
|
}
|
|
64470
64436
|
function writeIfChanged(path, content) {
|
|
64471
|
-
if (!
|
|
64437
|
+
if (!existsSync28(path)) {
|
|
64472
64438
|
ensureParent(path);
|
|
64473
|
-
|
|
64439
|
+
writeFileSync18(path, content, "utf-8");
|
|
64474
64440
|
return "created";
|
|
64475
64441
|
}
|
|
64476
|
-
if (
|
|
64442
|
+
if (readFileSync27(path, "utf-8") === content)
|
|
64477
64443
|
return "unchanged";
|
|
64478
|
-
|
|
64444
|
+
writeFileSync18(path, content, "utf-8");
|
|
64479
64445
|
return "updated";
|
|
64480
64446
|
}
|
|
64481
64447
|
function findSection(content) {
|
|
@@ -64501,14 +64467,14 @@ function buildSection(content, lineEnding = `
|
|
|
64501
64467
|
return `${DOSU_RULE_SECTION_START}${lineEnding}${body}${lineEnding}${DOSU_RULE_SECTION_END}`;
|
|
64502
64468
|
}
|
|
64503
64469
|
function upsertSection(path, content) {
|
|
64504
|
-
if (!
|
|
64470
|
+
if (!existsSync28(path)) {
|
|
64505
64471
|
const section = buildSection(content);
|
|
64506
64472
|
ensureParent(path);
|
|
64507
|
-
|
|
64473
|
+
writeFileSync18(path, `${section}
|
|
64508
64474
|
`, "utf-8");
|
|
64509
64475
|
return "created";
|
|
64510
64476
|
}
|
|
64511
|
-
const existing =
|
|
64477
|
+
const existing = readFileSync27(path, "utf-8");
|
|
64512
64478
|
const lineEnding = lineEndingFor(existing);
|
|
64513
64479
|
const section = buildSection(content, lineEnding);
|
|
64514
64480
|
const location = findSection(existing);
|
|
@@ -64521,7 +64487,7 @@ function upsertSection(path, content) {
|
|
|
64521
64487
|
}
|
|
64522
64488
|
if (next === existing)
|
|
64523
64489
|
return "unchanged";
|
|
64524
|
-
|
|
64490
|
+
writeFileSync18(path, next, "utf-8");
|
|
64525
64491
|
return "updated";
|
|
64526
64492
|
}
|
|
64527
64493
|
function installRuleForAgent(agent, content) {
|
|
@@ -64538,13 +64504,13 @@ function removeRuleForAgent(agent) {
|
|
|
64538
64504
|
return null;
|
|
64539
64505
|
const target = RULE_TARGETS[agent];
|
|
64540
64506
|
const path = target.path();
|
|
64541
|
-
if (!
|
|
64507
|
+
if (!existsSync28(path))
|
|
64542
64508
|
return { agent, path, action: "not_found" };
|
|
64543
64509
|
if (target.kind === "file") {
|
|
64544
64510
|
unlinkSync5(path);
|
|
64545
64511
|
return { agent, path, action: "removed" };
|
|
64546
64512
|
}
|
|
64547
|
-
const existing =
|
|
64513
|
+
const existing = readFileSync27(path, "utf-8");
|
|
64548
64514
|
const lineEnding = lineEndingFor(existing);
|
|
64549
64515
|
const location = findSection(existing);
|
|
64550
64516
|
if (!location)
|
|
@@ -64553,7 +64519,7 @@ function removeRuleForAgent(agent) {
|
|
|
64553
64519
|
if (!next) {
|
|
64554
64520
|
unlinkSync5(path);
|
|
64555
64521
|
} else {
|
|
64556
|
-
|
|
64522
|
+
writeFileSync18(path, `${next}${lineEnding}`, "utf-8");
|
|
64557
64523
|
}
|
|
64558
64524
|
return { agent, path, action: "removed" };
|
|
64559
64525
|
}
|
|
@@ -64581,36 +64547,36 @@ var init_installer = __esm(() => {
|
|
|
64581
64547
|
RULE_TARGETS = {
|
|
64582
64548
|
claude: {
|
|
64583
64549
|
kind: "file",
|
|
64584
|
-
path: () =>
|
|
64550
|
+
path: () => join42(claudeConfigDir4(), "rules", "dosu.md")
|
|
64585
64551
|
},
|
|
64586
64552
|
cursor: {
|
|
64587
64553
|
kind: "file",
|
|
64588
|
-
path: () =>
|
|
64554
|
+
path: () => join42(homedir12(), ".cursor", "rules", "dosu.mdc"),
|
|
64589
64555
|
cursorFrontmatter: true
|
|
64590
64556
|
},
|
|
64591
64557
|
codex: {
|
|
64592
64558
|
kind: "section",
|
|
64593
|
-
path: () =>
|
|
64559
|
+
path: () => join42(codexHome4(), "AGENTS.md")
|
|
64594
64560
|
},
|
|
64595
64561
|
opencode: {
|
|
64596
64562
|
kind: "section",
|
|
64597
|
-
path: () =>
|
|
64563
|
+
path: () => join42(homedir12(), ".config", "opencode", "AGENTS.md")
|
|
64598
64564
|
},
|
|
64599
64565
|
gemini: {
|
|
64600
64566
|
kind: "section",
|
|
64601
|
-
path: () =>
|
|
64567
|
+
path: () => join42(homedir12(), ".gemini", "GEMINI.md")
|
|
64602
64568
|
},
|
|
64603
64569
|
antigravity: {
|
|
64604
64570
|
kind: "section",
|
|
64605
|
-
path: () =>
|
|
64571
|
+
path: () => join42(homedir12(), ".gemini", "GEMINI.md")
|
|
64606
64572
|
}
|
|
64607
64573
|
};
|
|
64608
64574
|
});
|
|
64609
64575
|
|
|
64610
64576
|
// src/setup/agents-md-step.ts
|
|
64611
64577
|
import { execSync as execSync2 } from "node:child_process";
|
|
64612
|
-
import { existsSync as
|
|
64613
|
-
import { join as
|
|
64578
|
+
import { existsSync as existsSync29, readFileSync as readFileSync28, writeFileSync as writeFileSync19 } from "node:fs";
|
|
64579
|
+
import { join as join43 } from "node:path";
|
|
64614
64580
|
function inGitWorkTree(cwd = process.cwd()) {
|
|
64615
64581
|
try {
|
|
64616
64582
|
const stdout = execSync2("git rev-parse --is-inside-work-tree", {
|
|
@@ -64624,10 +64590,10 @@ function inGitWorkTree(cwd = process.cwd()) {
|
|
|
64624
64590
|
}
|
|
64625
64591
|
function dosuAgentsSectionState(cwd = process.cwd()) {
|
|
64626
64592
|
try {
|
|
64627
|
-
const path =
|
|
64628
|
-
if (!
|
|
64593
|
+
const path = join43(cwd, "AGENTS.md");
|
|
64594
|
+
if (!existsSync29(path))
|
|
64629
64595
|
return "missing";
|
|
64630
|
-
const content =
|
|
64596
|
+
const content = readFileSync28(path, "utf-8");
|
|
64631
64597
|
const startMatch = content.match(SECTION_START_RE);
|
|
64632
64598
|
if (!startMatch || !content.includes(DOSU_SECTION_END))
|
|
64633
64599
|
return "missing";
|
|
@@ -64662,14 +64628,14 @@ function findSection2(content) {
|
|
|
64662
64628
|
return { start, end };
|
|
64663
64629
|
}
|
|
64664
64630
|
function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RULE) {
|
|
64665
|
-
const path =
|
|
64666
|
-
if (!
|
|
64631
|
+
const path = join43(cwd, "AGENTS.md");
|
|
64632
|
+
if (!existsSync29(path)) {
|
|
64667
64633
|
const section = buildDosuAgentsSection(content);
|
|
64668
|
-
|
|
64634
|
+
writeFileSync19(path, `${section}
|
|
64669
64635
|
`);
|
|
64670
64636
|
return { path, action: "created" };
|
|
64671
64637
|
}
|
|
64672
|
-
const existing =
|
|
64638
|
+
const existing = readFileSync28(path, "utf-8");
|
|
64673
64639
|
const lineEnding = lineEndingFor2(existing);
|
|
64674
64640
|
const section = renderDosuAgentsSection(content, lineEnding);
|
|
64675
64641
|
const location = findSection2(existing);
|
|
@@ -64681,7 +64647,7 @@ function upsertDosuAgentsSection(cwd = process.cwd(), content = FALLBACK_DOSU_RU
|
|
|
64681
64647
|
}
|
|
64682
64648
|
if (next === existing)
|
|
64683
64649
|
return { path, action: "unchanged" };
|
|
64684
|
-
|
|
64650
|
+
writeFileSync19(path, next);
|
|
64685
64651
|
return { path, action: "updated" };
|
|
64686
64652
|
}
|
|
64687
64653
|
async function stepUpdateAgentsMd(cwd = process.cwd(), content) {
|
|
@@ -66133,7 +66099,7 @@ async function stepSelectTools(detected) {
|
|
|
66133
66099
|
initialValues: preselected,
|
|
66134
66100
|
statusFor: (id, picked) => {
|
|
66135
66101
|
if (configuredMap.get(id))
|
|
66136
|
-
return picked ? dim("configured") :
|
|
66102
|
+
return picked ? dim("configured") : import_picocolors35.default.yellow("will remove");
|
|
66137
66103
|
return picked ? brand("will configure") : undefined;
|
|
66138
66104
|
},
|
|
66139
66105
|
summary: (picked) => {
|
|
@@ -66308,7 +66274,7 @@ ${dim(wrapLog("Type it in a chat to keep that chat out of Dosu. To keep a whole
|
|
|
66308
66274
|
log2.success("All agents already configured. No changes needed.");
|
|
66309
66275
|
}
|
|
66310
66276
|
}
|
|
66311
|
-
var
|
|
66277
|
+
var import_picocolors35, OAUTH_ANALYTICS_REASONS, SETUP_HANDSHAKE_TIMEOUT_MS = 1800000, LIBRARY_SELECT_CANCELLED;
|
|
66312
66278
|
var init_flow2 = __esm(() => {
|
|
66313
66279
|
init_errors4();
|
|
66314
66280
|
init_client();
|
|
@@ -66331,7 +66297,7 @@ var init_flow2 = __esm(() => {
|
|
|
66331
66297
|
init_analytics2();
|
|
66332
66298
|
init_rules_step();
|
|
66333
66299
|
init_styles();
|
|
66334
|
-
|
|
66300
|
+
import_picocolors35 = __toESM(require_picocolors(), 1);
|
|
66335
66301
|
OAUTH_ANALYTICS_REASONS = new Set([
|
|
66336
66302
|
"access_denied",
|
|
66337
66303
|
"bad_oauth_state",
|
|
@@ -66495,7 +66461,7 @@ Could not update Dosu automatically.`);
|
|
|
66495
66461
|
${plan.manualCommand}`);
|
|
66496
66462
|
return result.status && result.status > 0 ? result.status : 1;
|
|
66497
66463
|
}
|
|
66498
|
-
console.log(
|
|
66464
|
+
console.log(import_picocolors36.default.green(`
|
|
66499
66465
|
✓ Update command completed.`));
|
|
66500
66466
|
console.log('Run "dosu --version" to verify.');
|
|
66501
66467
|
return 0;
|
|
@@ -66537,12 +66503,13 @@ async function completeUpgrade(channel = INSTALL_CHANNEL, options = {}) {
|
|
|
66537
66503
|
finishWithNewBinary(channel, options);
|
|
66538
66504
|
return 0;
|
|
66539
66505
|
}
|
|
66540
|
-
async function finishUpgrade(
|
|
66541
|
-
const
|
|
66542
|
-
|
|
66506
|
+
async function finishUpgrade(_from, options = {}) {
|
|
66507
|
+
const cfg = loadConfigNonBlocking();
|
|
66508
|
+
const stale = staleProviders(cfg);
|
|
66509
|
+
if (stale.length === 0) {
|
|
66543
66510
|
checkForSkillUpdates();
|
|
66544
66511
|
writeMcpRefreshCache({ version: VERSION });
|
|
66545
|
-
console.log(
|
|
66512
|
+
console.log(import_picocolors36.default.green(`✓ Dosu ${VERSION} is ready. Your AI agents need no changes.`));
|
|
66546
66513
|
return 0;
|
|
66547
66514
|
}
|
|
66548
66515
|
if (options.interactive ?? isInteractiveTerminal()) {
|
|
@@ -66554,14 +66521,13 @@ This update changes how agents connect to Dosu. Running setup...
|
|
|
66554
66521
|
return 0;
|
|
66555
66522
|
}
|
|
66556
66523
|
checkForSkillUpdates();
|
|
66557
|
-
const cfg = loadConfigNonBlocking();
|
|
66558
66524
|
if (!cfg || !canRefreshMcp(cfg)) {
|
|
66559
66525
|
console.error(SETUP_FALLBACK);
|
|
66560
66526
|
return 0;
|
|
66561
66527
|
}
|
|
66562
66528
|
console.log(`
|
|
66563
66529
|
Refreshing agent MCP configs with the new version...`);
|
|
66564
|
-
const result =
|
|
66530
|
+
const result = refreshProviders(cfg, stale);
|
|
66565
66531
|
writeMcpRefreshCache({ version: VERSION });
|
|
66566
66532
|
for (const provider of result.updated)
|
|
66567
66533
|
console.log(` ✓ ${provider.name()}`);
|
|
@@ -66607,7 +66573,7 @@ function upgradeCommand() {
|
|
|
66607
66573
|
process.exitCode = status;
|
|
66608
66574
|
});
|
|
66609
66575
|
}
|
|
66610
|
-
var
|
|
66576
|
+
var import_picocolors36, PACKAGE_NAME = "@dosu/cli", LATEST_PACKAGE, BREW_MANUAL_COMMAND = "brew upgrade dosu-ai/dosu/dosu", NPX_COMMAND = "npx -y @dosu/cli@latest", PROBE_TIMEOUT_MS = 5000, RELEASES_URL = "https://github.com/dosu-ai/dosu-cli/releases/latest", PACKAGE_MANAGERS, SETUP_FALLBACK = 'Run "dosu setup" to finish updating your AI agents.';
|
|
66611
66577
|
var init_upgrade = __esm(() => {
|
|
66612
66578
|
init_commander();
|
|
66613
66579
|
init_config();
|
|
@@ -66615,7 +66581,7 @@ var init_upgrade = __esm(() => {
|
|
|
66615
66581
|
init_auto_update();
|
|
66616
66582
|
init_mcp_refresh_check();
|
|
66617
66583
|
init_skill_update_check();
|
|
66618
|
-
|
|
66584
|
+
import_picocolors36 = __toESM(require_picocolors(), 1);
|
|
66619
66585
|
LATEST_PACKAGE = `${PACKAGE_NAME}@latest`;
|
|
66620
66586
|
PACKAGE_MANAGERS = {
|
|
66621
66587
|
npm: {
|
|
@@ -66634,31 +66600,30 @@ var init_upgrade = __esm(() => {
|
|
|
66634
66600
|
installArgs: ["global", "add", LATEST_PACKAGE]
|
|
66635
66601
|
}
|
|
66636
66602
|
};
|
|
66637
|
-
SEMVER = /^\d+\.\d+\.\d+/;
|
|
66638
66603
|
});
|
|
66639
66604
|
|
|
66640
66605
|
// src/version/incognito-backfill-check.ts
|
|
66641
|
-
import { existsSync as
|
|
66642
|
-
import { join as
|
|
66606
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync18, writeFileSync as writeFileSync20 } from "node:fs";
|
|
66607
|
+
import { join as join44 } from "node:path";
|
|
66643
66608
|
function markerPath() {
|
|
66644
|
-
return
|
|
66609
|
+
return join44(getConfigDir(), MARKER_FILENAME);
|
|
66645
66610
|
}
|
|
66646
66611
|
function writeMarker() {
|
|
66647
66612
|
const dir = getConfigDir();
|
|
66648
|
-
if (!
|
|
66649
|
-
|
|
66650
|
-
|
|
66613
|
+
if (!existsSync30(dir))
|
|
66614
|
+
mkdirSync18(dir, { recursive: true, mode: 448 });
|
|
66615
|
+
writeFileSync20(markerPath(), JSON.stringify({ done: true }), { mode: 384 });
|
|
66651
66616
|
}
|
|
66652
66617
|
function displayNotice3(names) {
|
|
66653
66618
|
console.error(`
|
|
66654
|
-
${
|
|
66655
|
-
` + `${
|
|
66619
|
+
${import_picocolors37.default.green(`✓ Dosu: added the /${INCOGNITO_COMMAND_NAME} command to ${names.join(", ")}`)}
|
|
66620
|
+
` + `${import_picocolors37.default.dim(` Type /${INCOGNITO_COMMAND_NAME} in a chat to keep that chat out of Dosu.`)}
|
|
66656
66621
|
`);
|
|
66657
66622
|
}
|
|
66658
66623
|
function checkForIncognitoBackfill(options = {}) {
|
|
66659
66624
|
const notify = options.notify ?? true;
|
|
66660
66625
|
try {
|
|
66661
|
-
if (
|
|
66626
|
+
if (existsSync30(markerPath()))
|
|
66662
66627
|
return;
|
|
66663
66628
|
const added = [];
|
|
66664
66629
|
let failed = false;
|
|
@@ -66685,14 +66650,244 @@ function checkForIncognitoBackfill(options = {}) {
|
|
|
66685
66650
|
logger.error("incognito-backfill", `Incognito backfill failed: ${err}`);
|
|
66686
66651
|
}
|
|
66687
66652
|
}
|
|
66688
|
-
var
|
|
66653
|
+
var import_picocolors37, MARKER_FILENAME = "incognito-backfill.json";
|
|
66689
66654
|
var init_incognito_backfill_check = __esm(() => {
|
|
66690
66655
|
init_config();
|
|
66691
66656
|
init_logger();
|
|
66692
66657
|
init_agents();
|
|
66693
66658
|
init_agents3();
|
|
66694
66659
|
init_incognito();
|
|
66660
|
+
import_picocolors37 = __toESM(require_picocolors(), 1);
|
|
66661
|
+
});
|
|
66662
|
+
|
|
66663
|
+
// src/version/update-check.ts
|
|
66664
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync19, readFileSync as readFileSync29, writeFileSync as writeFileSync21 } from "node:fs";
|
|
66665
|
+
import { join as join45 } from "node:path";
|
|
66666
|
+
function isValidVersion2(value) {
|
|
66667
|
+
return typeof value === "string" && SEMVER_PATTERN.test(value);
|
|
66668
|
+
}
|
|
66669
|
+
function stripPrerelease(version) {
|
|
66670
|
+
return version.replace(/[-+].*$/, "");
|
|
66671
|
+
}
|
|
66672
|
+
function isNewerVersion(latest, current) {
|
|
66673
|
+
const a = stripPrerelease(latest).split(".").map(Number);
|
|
66674
|
+
const b = stripPrerelease(current).split(".").map(Number);
|
|
66675
|
+
const len = Math.max(a.length, b.length);
|
|
66676
|
+
for (let i = 0;i < len; i++) {
|
|
66677
|
+
const av = a[i] ?? 0;
|
|
66678
|
+
const bv = b[i] ?? 0;
|
|
66679
|
+
if (av > bv)
|
|
66680
|
+
return true;
|
|
66681
|
+
if (av < bv)
|
|
66682
|
+
return false;
|
|
66683
|
+
}
|
|
66684
|
+
return false;
|
|
66685
|
+
}
|
|
66686
|
+
function getCachePath3() {
|
|
66687
|
+
return join45(getConfigDir(), CACHE_FILENAME5);
|
|
66688
|
+
}
|
|
66689
|
+
function readCache() {
|
|
66690
|
+
try {
|
|
66691
|
+
const path = getCachePath3();
|
|
66692
|
+
if (!existsSync31(path))
|
|
66693
|
+
return null;
|
|
66694
|
+
const data = JSON.parse(readFileSync29(path, "utf-8"));
|
|
66695
|
+
if (typeof data.lastCheck === "number" && isValidVersion2(data.latestVersion)) {
|
|
66696
|
+
return data;
|
|
66697
|
+
}
|
|
66698
|
+
return null;
|
|
66699
|
+
} catch {
|
|
66700
|
+
return null;
|
|
66701
|
+
}
|
|
66702
|
+
}
|
|
66703
|
+
function writeCache(cache) {
|
|
66704
|
+
try {
|
|
66705
|
+
const dir = getConfigDir();
|
|
66706
|
+
if (!existsSync31(dir)) {
|
|
66707
|
+
mkdirSync19(dir, { recursive: true, mode: 448 });
|
|
66708
|
+
}
|
|
66709
|
+
writeFileSync21(getCachePath3(), JSON.stringify(cache), { mode: 384 });
|
|
66710
|
+
} catch {}
|
|
66711
|
+
}
|
|
66712
|
+
async function fetchLatestVersion() {
|
|
66713
|
+
const controller = new AbortController;
|
|
66714
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS2);
|
|
66715
|
+
try {
|
|
66716
|
+
const resp = await fetch(REGISTRY_URL, { signal: controller.signal });
|
|
66717
|
+
if (!resp.ok)
|
|
66718
|
+
return null;
|
|
66719
|
+
const data = await resp.json();
|
|
66720
|
+
const latest = data.latest;
|
|
66721
|
+
return isValidVersion2(latest) ? latest : null;
|
|
66722
|
+
} catch {
|
|
66723
|
+
return null;
|
|
66724
|
+
} finally {
|
|
66725
|
+
clearTimeout(timeout);
|
|
66726
|
+
}
|
|
66727
|
+
}
|
|
66728
|
+
function buildUpdateHint(channel, npx = false) {
|
|
66729
|
+
if (channel === "npm" && npx) {
|
|
66730
|
+
return 'Use "npx -y @dosu/cli@latest" for the next Dosu command';
|
|
66731
|
+
}
|
|
66732
|
+
return 'Run "dosu upgrade"';
|
|
66733
|
+
}
|
|
66734
|
+
function styleHint(hint) {
|
|
66735
|
+
const match = hint.match(/^(.*)("[^"]+")(.*)$/);
|
|
66736
|
+
if (!match)
|
|
66737
|
+
return import_picocolors38.default.dim(hint);
|
|
66738
|
+
const [, before, command, after] = match;
|
|
66739
|
+
return [before && import_picocolors38.default.dim(before), import_picocolors38.default.cyan(command), after && import_picocolors38.default.dim(after)].filter(Boolean).join("");
|
|
66740
|
+
}
|
|
66741
|
+
function framedNotice(content, width) {
|
|
66742
|
+
const innerWidth = Math.max(...content.map(visibleWidth2)) + BOX_PADDING * 2;
|
|
66743
|
+
const framed = (line) => {
|
|
66744
|
+
const pad = innerWidth - visibleWidth2(line);
|
|
66745
|
+
const left = Math.floor(pad / 2);
|
|
66746
|
+
return `${import_picocolors38.default.yellow("│")}${" ".repeat(left)}${line}${" ".repeat(pad - left)}${import_picocolors38.default.yellow("│")}`;
|
|
66747
|
+
};
|
|
66748
|
+
const box = [
|
|
66749
|
+
import_picocolors38.default.yellow(`╭${"─".repeat(innerWidth)}╮`),
|
|
66750
|
+
framed(""),
|
|
66751
|
+
...content.map(framed),
|
|
66752
|
+
framed(""),
|
|
66753
|
+
import_picocolors38.default.yellow(`╰${"─".repeat(innerWidth)}╯`)
|
|
66754
|
+
];
|
|
66755
|
+
return `
|
|
66756
|
+
${centerBlock(box, width).join(`
|
|
66757
|
+
`)}
|
|
66758
|
+
`;
|
|
66759
|
+
}
|
|
66760
|
+
function versionArrow(current, latest) {
|
|
66761
|
+
return `${import_picocolors38.default.dim(current)} ${import_picocolors38.default.dim("→")} ${import_picocolors38.default.bold(brand(latest))}`;
|
|
66762
|
+
}
|
|
66763
|
+
function buildAutoUpdateNotice(current, latest, interactive, width = process.stderr.columns ?? 80) {
|
|
66764
|
+
if (interactive) {
|
|
66765
|
+
return framedNotice([
|
|
66766
|
+
`Updating Dosu: ${versionArrow(current, latest)}`,
|
|
66767
|
+
import_picocolors38.default.dim("Installing in the background; your next command uses it")
|
|
66768
|
+
], width);
|
|
66769
|
+
}
|
|
66770
|
+
return `
|
|
66771
|
+
[dosu:update] Installing Dosu ${latest} in the background (running ${current}). ` + `The next Dosu command uses it; no action needed.
|
|
66772
|
+
`;
|
|
66773
|
+
}
|
|
66774
|
+
function buildUpdateNotice(current, latest, channel, interactive, npx = false, width = process.stderr.columns ?? 80) {
|
|
66775
|
+
const hint = buildUpdateHint(channel, npx);
|
|
66776
|
+
if (interactive) {
|
|
66777
|
+
return framedNotice([`Update available: ${versionArrow(current, latest)}`, styleHint(hint)], width);
|
|
66778
|
+
}
|
|
66779
|
+
const agentAction = hint[0].toLowerCase() + hint.slice(1);
|
|
66780
|
+
const verifyCommand = npx ? "npx -y @dosu/cli@latest --version" : "dosu --version";
|
|
66781
|
+
return `
|
|
66782
|
+
[dosu:update] Update available: ${current} → ${latest}
|
|
66783
|
+
` + `Tell the user Dosu CLI is outdated. After they approve, ${agentAction}, ` + `then verify with "${verifyCommand}".
|
|
66784
|
+
`;
|
|
66785
|
+
}
|
|
66786
|
+
function getAvailableUpdate() {
|
|
66787
|
+
const cache = readCache();
|
|
66788
|
+
return cache && isNewerVersion(cache.latestVersion, VERSION) ? cache.latestVersion : null;
|
|
66789
|
+
}
|
|
66790
|
+
function handleNewerVersion(latest, notify) {
|
|
66791
|
+
const autoUpdate = startAutoUpdate(latest);
|
|
66792
|
+
if (!notify)
|
|
66793
|
+
return;
|
|
66794
|
+
const interactive = process.stderr.isTTY === true;
|
|
66795
|
+
console.error(autoUpdate === "unavailable" ? buildUpdateNotice(VERSION, latest, INSTALL_CHANNEL, interactive, isNpxInvocation()) : buildAutoUpdateNotice(VERSION, latest, interactive));
|
|
66796
|
+
}
|
|
66797
|
+
async function checkForUpdates(options = {}) {
|
|
66798
|
+
const notify = options.notify ?? true;
|
|
66799
|
+
try {
|
|
66800
|
+
const cache = readCache();
|
|
66801
|
+
const isStale = !cache || Date.now() - cache.lastCheck > CHECK_INTERVAL_MS2;
|
|
66802
|
+
if (!isStale) {
|
|
66803
|
+
if (isNewerVersion(cache.latestVersion, VERSION)) {
|
|
66804
|
+
handleNewerVersion(cache.latestVersion, notify);
|
|
66805
|
+
}
|
|
66806
|
+
return;
|
|
66807
|
+
}
|
|
66808
|
+
const latest = await fetchLatestVersion();
|
|
66809
|
+
const latestKnownVersion = latest ?? cache?.latestVersion ?? VERSION;
|
|
66810
|
+
writeCache({
|
|
66811
|
+
lastCheck: Date.now(),
|
|
66812
|
+
latestVersion: latestKnownVersion
|
|
66813
|
+
});
|
|
66814
|
+
if (latest) {
|
|
66815
|
+
logger.debug("update-check", `Cached latest version: ${latest}`);
|
|
66816
|
+
}
|
|
66817
|
+
if (isNewerVersion(latestKnownVersion, VERSION)) {
|
|
66818
|
+
handleNewerVersion(latestKnownVersion, notify);
|
|
66819
|
+
}
|
|
66820
|
+
} catch (err) {
|
|
66821
|
+
logger.error("update-check", `Update check failed: ${err}`);
|
|
66822
|
+
}
|
|
66823
|
+
}
|
|
66824
|
+
var import_picocolors38, CACHE_FILENAME5 = "update-check.json", CHECK_INTERVAL_MS2, FETCH_TIMEOUT_MS2 = 1000, REGISTRY_URL = "https://registry.npmjs.org/-/package/@dosu/cli/dist-tags", SEMVER_PATTERN, BOX_PADDING = 3;
|
|
66825
|
+
var init_update_check = __esm(() => {
|
|
66826
|
+
init_config();
|
|
66827
|
+
init_logger();
|
|
66828
|
+
init_styles();
|
|
66829
|
+
init_layout();
|
|
66830
|
+
init_auto_update();
|
|
66695
66831
|
import_picocolors38 = __toESM(require_picocolors(), 1);
|
|
66832
|
+
CHECK_INTERVAL_MS2 = 6 * 60 * 60 * 1000;
|
|
66833
|
+
SEMVER_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
66834
|
+
});
|
|
66835
|
+
|
|
66836
|
+
// src/cli/fatal-error.ts
|
|
66837
|
+
function read2(value, key) {
|
|
66838
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
66839
|
+
return;
|
|
66840
|
+
}
|
|
66841
|
+
try {
|
|
66842
|
+
return Reflect.get(value, key);
|
|
66843
|
+
} catch {
|
|
66844
|
+
return;
|
|
66845
|
+
}
|
|
66846
|
+
}
|
|
66847
|
+
function tokenOf2(data, key) {
|
|
66848
|
+
const value = read2(data, key);
|
|
66849
|
+
if (typeof value !== "string")
|
|
66850
|
+
return;
|
|
66851
|
+
const trimmed = value.trim();
|
|
66852
|
+
return REQUEST_ID_PATTERN2.test(trimmed) ? trimmed : undefined;
|
|
66853
|
+
}
|
|
66854
|
+
function statusOf2(data) {
|
|
66855
|
+
const value = read2(data, "httpStatus");
|
|
66856
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599 ? value : undefined;
|
|
66857
|
+
}
|
|
66858
|
+
function fatalErrorDiagnostics2(err) {
|
|
66859
|
+
const data = read2(err, "data");
|
|
66860
|
+
if (!data)
|
|
66861
|
+
return;
|
|
66862
|
+
const code = tokenOf2(data, "code");
|
|
66863
|
+
const path = tokenOf2(data, "path");
|
|
66864
|
+
const status = statusOf2(data);
|
|
66865
|
+
const requestId = tokenOf2(data, "requestId");
|
|
66866
|
+
const parts = [
|
|
66867
|
+
code && `code=${code}`,
|
|
66868
|
+
path && `path=${path}`,
|
|
66869
|
+
status && `status=${status}`,
|
|
66870
|
+
requestId && `request_id=${requestId}`
|
|
66871
|
+
].filter(Boolean);
|
|
66872
|
+
return parts.length > 0 ? parts.join(" ") : undefined;
|
|
66873
|
+
}
|
|
66874
|
+
function printFatalError2(err) {
|
|
66875
|
+
if (isCommandError(err)) {
|
|
66876
|
+
console.error(import_picocolors39.default.red(err.message));
|
|
66877
|
+
for (const line of err.details)
|
|
66878
|
+
console.error(import_picocolors39.default.dim(line));
|
|
66879
|
+
return;
|
|
66880
|
+
}
|
|
66881
|
+
console.error(read2(err, "message") ?? err);
|
|
66882
|
+
const diagnostics = fatalErrorDiagnostics2(err);
|
|
66883
|
+
if (diagnostics)
|
|
66884
|
+
console.error(diagnostics);
|
|
66885
|
+
}
|
|
66886
|
+
var import_picocolors39, REQUEST_ID_PATTERN2;
|
|
66887
|
+
var init_fatal_error = __esm(() => {
|
|
66888
|
+
init_command_error();
|
|
66889
|
+
import_picocolors39 = __toESM(require_picocolors(), 1);
|
|
66890
|
+
REQUEST_ID_PATTERN2 = /^[A-Za-z0-9][A-Za-z0-9:._-]{0,127}$/;
|
|
66696
66891
|
});
|
|
66697
66892
|
|
|
66698
66893
|
// src/tui/analytics-view.ts
|
|
@@ -66813,7 +67008,7 @@ function renderAnalyticsFrame(state, tab, scroll, pageStats = null, pagesPending
|
|
|
66813
67008
|
const rows = analyticsTabRows(tab, state, pageStats);
|
|
66814
67009
|
const { visible, above, below } = windowReport(rows, scroll, height);
|
|
66815
67010
|
const empty = tab === "overview" ? "No analytics yet. They appear after the first study run." : tab === "projects" ? "No per-project history yet. It fills in as sessions are studied." : pagesPending ? "Loading page analytics..." : "No page analytics yet.";
|
|
66816
|
-
const listRows = visible.length > 0 ? visible.map((row) =>
|
|
67011
|
+
const listRows = visible.length > 0 ? visible.map((row) => import_picocolors40.default.dim(row)) : [import_picocolors40.default.dim(empty)];
|
|
66817
67012
|
const scrollParts = [];
|
|
66818
67013
|
if (above > 0)
|
|
66819
67014
|
scrollParts.push(`↑ ${above} earlier`);
|
|
@@ -66829,9 +67024,9 @@ function renderAnalyticsFrame(state, tab, scroll, pageStats = null, pagesPending
|
|
|
66829
67024
|
], tab, width, { spread: false }),
|
|
66830
67025
|
"",
|
|
66831
67026
|
...listRows,
|
|
66832
|
-
...scrollParts.length > 0 ? [
|
|
67027
|
+
...scrollParts.length > 0 ? [import_picocolors40.default.dim(scrollParts.join(" · "))] : [],
|
|
66833
67028
|
"",
|
|
66834
|
-
|
|
67029
|
+
import_picocolors40.default.dim("tab switch · ↑↓ scroll · esc back")
|
|
66835
67030
|
];
|
|
66836
67031
|
return lines.join(`
|
|
66837
67032
|
`);
|
|
@@ -66928,7 +67123,7 @@ ${CLEAR_BELOW2}`);
|
|
|
66928
67123
|
input.on("data", onData);
|
|
66929
67124
|
});
|
|
66930
67125
|
}
|
|
66931
|
-
var
|
|
67126
|
+
var import_picocolors40, ESC8, HIDE_CURSOR4, SHOW_CURSOR4, CTRL_C5, KEY_UP5, KEY_DOWN5, KEY_RIGHT4, KEY_LEFT4, CURSOR_HOME2, CLEAR_BELOW2, CLEAR_EOL2, ANALYTICS_VIEW_POLL_MS = 1000, ANALYTICS_VIEW_LINES = 14, ANALYTICS_VIEW_CHROME_LINES = 8, ANALYTICS_VIEW_TABS, TOP_PAGES_LIMIT = 5, TOP_CITED_DAYS = 30, label = (text) => text.padEnd(26);
|
|
66932
67127
|
var init_analytics_view = __esm(() => {
|
|
66933
67128
|
init_trpc();
|
|
66934
67129
|
init_config();
|
|
@@ -66936,7 +67131,7 @@ var init_analytics_view = __esm(() => {
|
|
|
66936
67131
|
init_alt_screen();
|
|
66937
67132
|
init_layout();
|
|
66938
67133
|
init_menu();
|
|
66939
|
-
|
|
67134
|
+
import_picocolors40 = __toESM(require_picocolors(), 1);
|
|
66940
67135
|
ESC8 = String.fromCharCode(27);
|
|
66941
67136
|
HIDE_CURSOR4 = `${ESC8}[?25l`;
|
|
66942
67137
|
SHOW_CURSOR4 = `${ESC8}[?25h`;
|
|
@@ -66954,7 +67149,7 @@ var init_analytics_view = __esm(() => {
|
|
|
66954
67149
|
// src/tui/banner.ts
|
|
66955
67150
|
function paintLogoRow(row) {
|
|
66956
67151
|
return row.map(([tone, art]) => {
|
|
66957
|
-
if (!
|
|
67152
|
+
if (!import_picocolors41.default.isColorSupported)
|
|
66958
67153
|
return art;
|
|
66959
67154
|
const { fg, fallback } = LOGO_TONES[tone];
|
|
66960
67155
|
return hasTruecolor() ? `${fg}${art}\x1B[39m` : fallback(art);
|
|
@@ -66985,14 +67180,14 @@ function wrapValue(text, room) {
|
|
|
66985
67180
|
}
|
|
66986
67181
|
function checklistRows(ctx, width) {
|
|
66987
67182
|
const on = brand(CHECK2);
|
|
66988
|
-
const off =
|
|
67183
|
+
const off = import_picocolors41.default.dim(CIRCLE);
|
|
66989
67184
|
const rows = [["workspace", ctx.directory]];
|
|
66990
67185
|
rows.push([
|
|
66991
67186
|
"account",
|
|
66992
|
-
ctx.sessionExpired ? `${off} ${
|
|
67187
|
+
ctx.sessionExpired ? `${off} ${import_picocolors41.default.yellow("session expired")} ${import_picocolors41.default.dim(`${DOT3} run Log in`)}` : ctx.signedIn ? `${on} signed in` : `${off} ${import_picocolors41.default.dim(`not signed in ${DOT3} run Setup`)}`
|
|
66993
67188
|
]);
|
|
66994
67189
|
const missing = new Set(ctx.setupMissing ?? []);
|
|
66995
|
-
const warnRow = `${off} ${
|
|
67190
|
+
const warnRow = `${off} ${import_picocolors41.default.yellow("not configured")} ${import_picocolors41.default.dim(`${DOT3} run Setup`)}`;
|
|
66996
67191
|
if (missing.has("MCP"))
|
|
66997
67192
|
rows.push(["mcp", warnRow]);
|
|
66998
67193
|
else if (ctx.deploymentName)
|
|
@@ -67004,7 +67199,7 @@ function checklistRows(ctx, width) {
|
|
|
67004
67199
|
if (ctx.repoAgentsMd) {
|
|
67005
67200
|
rows.push([
|
|
67006
67201
|
"repo",
|
|
67007
|
-
ctx.repoAgentsMd === "current" ? `${on} AGENTS.md has the Dosu section` : `${off} ${
|
|
67202
|
+
ctx.repoAgentsMd === "current" ? `${on} AGENTS.md has the Dosu section` : `${off} ${import_picocolors41.default.yellow(ctx.repoAgentsMd === "outdated" ? "AGENTS.md Dosu section outdated" : "AGENTS.md missing the Dosu section")} ${import_picocolors41.default.dim(`${DOT3} run Setup`)}`
|
|
67008
67203
|
]);
|
|
67009
67204
|
}
|
|
67010
67205
|
if (missing.has("agents"))
|
|
@@ -67016,20 +67211,20 @@ function checklistRows(ctx, width) {
|
|
|
67016
67211
|
if (ctx.studying) {
|
|
67017
67212
|
rows.push([
|
|
67018
67213
|
"sync",
|
|
67019
|
-
`\uD83D\uDCDA ${brand("studying sessions...")} ${
|
|
67214
|
+
`\uD83D\uDCDA ${brand("studying sessions...")} ${import_picocolors41.default.dim(`${DOT3} see activity`)}`
|
|
67020
67215
|
]);
|
|
67021
67216
|
}
|
|
67022
67217
|
if (ctx.update) {
|
|
67023
67218
|
rows.push([
|
|
67024
67219
|
"update",
|
|
67025
|
-
`${
|
|
67220
|
+
`${import_picocolors41.default.yellow(`↑ ${ctx.update.version} available`)} ${import_picocolors41.default.dim(`${DOT3} ${ctx.update.hint}`)}`
|
|
67026
67221
|
]);
|
|
67027
67222
|
}
|
|
67028
67223
|
const labelWidth = Math.max(...rows.map(([label]) => label.length));
|
|
67029
67224
|
const valueColumn = LOGO_WIDTH + COLUMN_GAP.length + labelWidth + LABEL_GAP.length;
|
|
67030
67225
|
const room = Math.max(1, width - valueColumn);
|
|
67031
67226
|
const indent = " ".repeat(labelWidth + LABEL_GAP.length);
|
|
67032
|
-
return rows.flatMap(([label, value]) => wrapValue(value, room).map((line, i) => i === 0 ? `${
|
|
67227
|
+
return rows.flatMap(([label, value]) => wrapValue(value, room).map((line, i) => i === 0 ? `${import_picocolors41.default.dim(label.padEnd(labelWidth))}${LABEL_GAP}${line}` : `${indent}${line}`));
|
|
67033
67228
|
}
|
|
67034
67229
|
function bannerWidth(columns = process.stdout.columns ?? 80) {
|
|
67035
67230
|
return columns - layoutMargin(columns) - 1;
|
|
@@ -67039,7 +67234,7 @@ function renderBanner(ctx, width = bannerWidth()) {
|
|
|
67039
67234
|
const text = [
|
|
67040
67235
|
...checklistRows(ctx, width),
|
|
67041
67236
|
"",
|
|
67042
|
-
`${brandBadge("dosu-cli")} ${
|
|
67237
|
+
`${brandBadge("dosu-cli")} ${import_picocolors41.default.dim(`${ctx.version} ${DOT3} ${ctx.webAppHost}`)}`
|
|
67043
67238
|
];
|
|
67044
67239
|
const height = Math.max(logo.length, text.length);
|
|
67045
67240
|
const combined = [];
|
|
@@ -67052,11 +67247,11 @@ function renderBanner(ctx, width = bannerWidth()) {
|
|
|
67052
67247
|
return ["", ...combined, ""].join(`
|
|
67053
67248
|
`);
|
|
67054
67249
|
}
|
|
67055
|
-
var
|
|
67250
|
+
var import_picocolors41, CHECK2 = "✔", CIRCLE = "○", DOT3 = "·", LOGO_ROWS, LOGO_MARK, LOGO_WIDTH, LOGO_TONES, COLUMN_GAP = " ", LABEL_GAP = " ", LIST_SEP;
|
|
67056
67251
|
var init_banner = __esm(() => {
|
|
67057
67252
|
init_styles();
|
|
67058
67253
|
init_layout();
|
|
67059
|
-
|
|
67254
|
+
import_picocolors41 = __toESM(require_picocolors(), 1);
|
|
67060
67255
|
LOGO_ROWS = [
|
|
67061
67256
|
[["sage", "▄▄▄▄▄▄"]],
|
|
67062
67257
|
[["sage", "██ ▀▄"]],
|
|
@@ -67067,8 +67262,8 @@ var init_banner = __esm(() => {
|
|
|
67067
67262
|
LOGO_MARK = LOGO_ROWS.map((row) => row.map(([, art]) => art).join(""));
|
|
67068
67263
|
LOGO_WIDTH = Math.max(...LOGO_MARK.map((row) => row.length));
|
|
67069
67264
|
LOGO_TONES = {
|
|
67070
|
-
sage: { fg: "\x1B[38;2;180;187;145m", fallback:
|
|
67071
|
-
moss: { fg: "\x1B[38;2;119;133;97m", fallback: (art) =>
|
|
67265
|
+
sage: { fg: "\x1B[38;2;180;187;145m", fallback: import_picocolors41.default.green },
|
|
67266
|
+
moss: { fg: "\x1B[38;2;119;133;97m", fallback: (art) => import_picocolors41.default.dim(import_picocolors41.default.green(art)) }
|
|
67072
67267
|
};
|
|
67073
67268
|
LIST_SEP = ` ${DOT3} `;
|
|
67074
67269
|
});
|
|
@@ -67181,16 +67376,16 @@ function renderPagesFrame(model, width, selected) {
|
|
|
67181
67376
|
const body = [];
|
|
67182
67377
|
let scrollHint = "";
|
|
67183
67378
|
if (model.phase === "loading") {
|
|
67184
|
-
body.push(
|
|
67379
|
+
body.push(import_picocolors42.default.dim("Loading pages…"));
|
|
67185
67380
|
} else if (model.phase === "error") {
|
|
67186
|
-
body.push(
|
|
67381
|
+
body.push(import_picocolors42.default.yellow(clip3(model.message, width)));
|
|
67187
67382
|
} else if (model.pages.length === 0) {
|
|
67188
|
-
body.push(
|
|
67383
|
+
body.push(import_picocolors42.default.dim("No pages in this Library yet."));
|
|
67189
67384
|
} else {
|
|
67190
67385
|
const rows = pageRows2(model.pages, width - 2);
|
|
67191
67386
|
const { start, above } = windowSelection(rows.length, selected);
|
|
67192
67387
|
const visible = rows.slice(start, start + PAGES_VIEW_LINES);
|
|
67193
|
-
body.push(...visible.map((row, i) => start + i === selected ? `${brand("▸")} ${
|
|
67388
|
+
body.push(...visible.map((row, i) => start + i === selected ? `${brand("▸")} ${import_picocolors42.default.bold(row)}` : ` ${import_picocolors42.default.dim(row)}`));
|
|
67194
67389
|
const below = Math.max(0, Math.max(model.total, rows.length) - start - PAGES_VIEW_LINES);
|
|
67195
67390
|
const parts = [];
|
|
67196
67391
|
if (above > 0)
|
|
@@ -67199,14 +67394,14 @@ function renderPagesFrame(model, width, selected) {
|
|
|
67199
67394
|
parts.push(`↓ ${below} more`);
|
|
67200
67395
|
scrollHint = parts.join(" · ");
|
|
67201
67396
|
}
|
|
67202
|
-
const count = model.phase === "ready" ? ` ${
|
|
67397
|
+
const count = model.phase === "ready" ? ` ${import_picocolors42.default.dim(model.pages.length < model.total ? `(${model.pages.length} of ${model.total})` : `(${model.pages.length})`)}` : "";
|
|
67203
67398
|
const lines = [
|
|
67204
67399
|
`${breadcrumb(["home", "pages"], width)}${count}`,
|
|
67205
67400
|
"",
|
|
67206
67401
|
...body,
|
|
67207
|
-
...scrollHint ? [
|
|
67402
|
+
...scrollHint ? [import_picocolors42.default.dim(scrollHint)] : [],
|
|
67208
67403
|
"",
|
|
67209
|
-
|
|
67404
|
+
import_picocolors42.default.dim("↑↓ move · enter open · esc back")
|
|
67210
67405
|
];
|
|
67211
67406
|
return lines.join(`
|
|
67212
67407
|
`);
|
|
@@ -67215,9 +67410,9 @@ function renderPageFrame(page, content, width, scroll) {
|
|
|
67215
67410
|
const body = [];
|
|
67216
67411
|
let scrollHint = "";
|
|
67217
67412
|
if (content.phase === "loading") {
|
|
67218
|
-
body.push(
|
|
67413
|
+
body.push(import_picocolors42.default.dim("Loading page…"));
|
|
67219
67414
|
} else if (content.phase === "error") {
|
|
67220
|
-
body.push(
|
|
67415
|
+
body.push(import_picocolors42.default.yellow(clip3(content.message, width)));
|
|
67221
67416
|
} else {
|
|
67222
67417
|
const rows = wrapBody(content.body, width);
|
|
67223
67418
|
const { visible, above, below } = windowReport(rows, scroll, PAGE_BODY_LINES);
|
|
@@ -67232,12 +67427,12 @@ function renderPageFrame(page, content, width, scroll) {
|
|
|
67232
67427
|
const meta = `${page.type} · ${page.published ? "published" : "draft"} · updated ${page.updated_at.slice(0, 10)}`;
|
|
67233
67428
|
const lines = [
|
|
67234
67429
|
breadcrumb(["home", "pages", page.title], width),
|
|
67235
|
-
|
|
67430
|
+
import_picocolors42.default.dim(clip3(meta, width)),
|
|
67236
67431
|
"",
|
|
67237
67432
|
...body,
|
|
67238
|
-
...scrollHint ? [
|
|
67433
|
+
...scrollHint ? [import_picocolors42.default.dim(scrollHint)] : [],
|
|
67239
67434
|
"",
|
|
67240
|
-
|
|
67435
|
+
import_picocolors42.default.dim("↑↓ scroll · esc back to pages")
|
|
67241
67436
|
];
|
|
67242
67437
|
return lines.join(`
|
|
67243
67438
|
`);
|
|
@@ -67386,7 +67581,7 @@ ${CLEAR_BELOW3}`);
|
|
|
67386
67581
|
input.on("data", onData);
|
|
67387
67582
|
});
|
|
67388
67583
|
}
|
|
67389
|
-
var
|
|
67584
|
+
var import_picocolors42, ESC9, HIDE_CURSOR5, SHOW_CURSOR5, CTRL_C6, KEY_UP6, KEY_DOWN6, CURSOR_HOME3, CLEAR_BELOW3, CLEAR_EOL3, PAGES_VIEW_LINES = 12, PAGE_BODY_LINES = 14, PAGES_FETCH_BATCH = 100;
|
|
67390
67585
|
var init_pages_view = __esm(() => {
|
|
67391
67586
|
init_trpc();
|
|
67392
67587
|
init_config();
|
|
@@ -67396,7 +67591,7 @@ var init_pages_view = __esm(() => {
|
|
|
67396
67591
|
init_analytics_view();
|
|
67397
67592
|
init_layout();
|
|
67398
67593
|
init_menu();
|
|
67399
|
-
|
|
67594
|
+
import_picocolors42 = __toESM(require_picocolors(), 1);
|
|
67400
67595
|
ESC9 = String.fromCharCode(27);
|
|
67401
67596
|
HIDE_CURSOR5 = `${ESC9}[?25l`;
|
|
67402
67597
|
SHOW_CURSOR5 = `${ESC9}[?25h`;
|
|
@@ -67509,7 +67704,7 @@ function isSetUp(cfg) {
|
|
|
67509
67704
|
}
|
|
67510
67705
|
function setupHint(cfg) {
|
|
67511
67706
|
const started = Boolean(cfg.active_account?.target);
|
|
67512
|
-
return
|
|
67707
|
+
return import_picocolors43.default.yellow(started ? `incomplete · missing ${missingSetupSteps(cfg).join(" + ")}` : "not set up yet");
|
|
67513
67708
|
}
|
|
67514
67709
|
function isStudying() {
|
|
67515
67710
|
try {
|
|
@@ -67754,7 +67949,7 @@ function handleLogout(cfg) {
|
|
|
67754
67949
|
saveConfig(cfg);
|
|
67755
67950
|
log2.success("Credentials cleared.");
|
|
67756
67951
|
}
|
|
67757
|
-
var
|
|
67952
|
+
var import_picocolors43, ESC10, CLEAR_SCREEN;
|
|
67758
67953
|
var init_tui = __esm(() => {
|
|
67759
67954
|
init_client();
|
|
67760
67955
|
init_config();
|
|
@@ -67778,7 +67973,7 @@ var init_tui = __esm(() => {
|
|
|
67778
67973
|
init_menu();
|
|
67779
67974
|
init_pages_view();
|
|
67780
67975
|
init_prompts();
|
|
67781
|
-
|
|
67976
|
+
import_picocolors43 = __toESM(require_picocolors(), 1);
|
|
67782
67977
|
ESC10 = String.fromCharCode(27);
|
|
67783
67978
|
CLEAR_SCREEN = `${ESC10}[2J${ESC10}[H`;
|
|
67784
67979
|
});
|
|
@@ -68881,11 +69076,20 @@ async function execute() {
|
|
|
68881
69076
|
try {
|
|
68882
69077
|
await program.parseAsync(process.argv);
|
|
68883
69078
|
} catch (err) {
|
|
69079
|
+
printFatalError2(err);
|
|
69080
|
+
logFatalError(err);
|
|
68884
69081
|
if (telemetry)
|
|
68885
69082
|
await finishTelemetry(() => telemetry.fail(err));
|
|
68886
|
-
|
|
69083
|
+
process.exit(1);
|
|
68887
69084
|
}
|
|
68888
69085
|
}
|
|
69086
|
+
function logFatalError(err) {
|
|
69087
|
+
try {
|
|
69088
|
+
const message = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
|
|
69089
|
+
const diagnostics = fatalErrorDiagnostics2(err);
|
|
69090
|
+
logger.error("cli", diagnostics ? `${message} (${diagnostics})` : message);
|
|
69091
|
+
} catch {}
|
|
69092
|
+
}
|
|
68889
69093
|
function processCommandTelemetry() {
|
|
68890
69094
|
try {
|
|
68891
69095
|
const settings = loadTelemetrySettings();
|
|
@@ -68934,8 +69138,63 @@ var init_cli = __esm(() => {
|
|
|
68934
69138
|
init_skill_update_check();
|
|
68935
69139
|
init_update_check();
|
|
68936
69140
|
init_errors();
|
|
69141
|
+
init_fatal_error();
|
|
68937
69142
|
});
|
|
68938
69143
|
|
|
69144
|
+
// src/cli/fatal-error.ts
|
|
69145
|
+
init_command_error();
|
|
69146
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
69147
|
+
var REQUEST_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9:._-]{0,127}$/;
|
|
69148
|
+
function read(value, key) {
|
|
69149
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
69150
|
+
return;
|
|
69151
|
+
}
|
|
69152
|
+
try {
|
|
69153
|
+
return Reflect.get(value, key);
|
|
69154
|
+
} catch {
|
|
69155
|
+
return;
|
|
69156
|
+
}
|
|
69157
|
+
}
|
|
69158
|
+
function tokenOf(data, key) {
|
|
69159
|
+
const value = read(data, key);
|
|
69160
|
+
if (typeof value !== "string")
|
|
69161
|
+
return;
|
|
69162
|
+
const trimmed = value.trim();
|
|
69163
|
+
return REQUEST_ID_PATTERN.test(trimmed) ? trimmed : undefined;
|
|
69164
|
+
}
|
|
69165
|
+
function statusOf(data) {
|
|
69166
|
+
const value = read(data, "httpStatus");
|
|
69167
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 100 && value <= 599 ? value : undefined;
|
|
69168
|
+
}
|
|
69169
|
+
function fatalErrorDiagnostics(err) {
|
|
69170
|
+
const data = read(err, "data");
|
|
69171
|
+
if (!data)
|
|
69172
|
+
return;
|
|
69173
|
+
const code = tokenOf(data, "code");
|
|
69174
|
+
const path = tokenOf(data, "path");
|
|
69175
|
+
const status = statusOf(data);
|
|
69176
|
+
const requestId = tokenOf(data, "requestId");
|
|
69177
|
+
const parts = [
|
|
69178
|
+
code && `code=${code}`,
|
|
69179
|
+
path && `path=${path}`,
|
|
69180
|
+
status && `status=${status}`,
|
|
69181
|
+
requestId && `request_id=${requestId}`
|
|
69182
|
+
].filter(Boolean);
|
|
69183
|
+
return parts.length > 0 ? parts.join(" ") : undefined;
|
|
69184
|
+
}
|
|
69185
|
+
function printFatalError(err) {
|
|
69186
|
+
if (isCommandError(err)) {
|
|
69187
|
+
console.error(import_picocolors.default.red(err.message));
|
|
69188
|
+
for (const line of err.details)
|
|
69189
|
+
console.error(import_picocolors.default.dim(line));
|
|
69190
|
+
return;
|
|
69191
|
+
}
|
|
69192
|
+
console.error(read(err, "message") ?? err);
|
|
69193
|
+
const diagnostics = fatalErrorDiagnostics(err);
|
|
69194
|
+
if (diagnostics)
|
|
69195
|
+
console.error(diagnostics);
|
|
69196
|
+
}
|
|
69197
|
+
|
|
68939
69198
|
// src/statusline/argv.ts
|
|
68940
69199
|
var RENDER_ARGV = ["knowledge", "statusline", "render"];
|
|
68941
69200
|
function isStatuslineRenderArgv(argv) {
|
|
@@ -68954,17 +69213,8 @@ async function main() {
|
|
|
68954
69213
|
await execute();
|
|
68955
69214
|
}
|
|
68956
69215
|
main().catch((err) => {
|
|
68957
|
-
|
|
68958
|
-
const data = err?.data;
|
|
68959
|
-
if (data && (data.code || data.path || data.httpStatus)) {
|
|
68960
|
-
const parts = [
|
|
68961
|
-
data.code && `code=${data.code}`,
|
|
68962
|
-
data.path && `path=${data.path}`,
|
|
68963
|
-
data.httpStatus && `status=${data.httpStatus}`
|
|
68964
|
-
].filter(Boolean);
|
|
68965
|
-
console.error(parts.join(" "));
|
|
68966
|
-
}
|
|
69216
|
+
printFatalError(err);
|
|
68967
69217
|
process.exit(1);
|
|
68968
69218
|
});
|
|
68969
69219
|
|
|
68970
|
-
//# debugId=
|
|
69220
|
+
//# debugId=fa693edb-14f4-abcb-6475-6e2164756e21
|