@dosu/cli 0.68.4 → 0.68.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/dosu.js +381 -378
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -1128,7 +1128,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
|
|
|
1128
1128
|
function getVersionString() {
|
|
1129
1129
|
return `v${VERSION}`;
|
|
1130
1130
|
}
|
|
1131
|
-
var VERSION = "0.68.
|
|
1131
|
+
var VERSION = "0.68.5", INSTALL_CHANNEL = "npm";
|
|
1132
1132
|
|
|
1133
1133
|
// src/debug/logger.ts
|
|
1134
1134
|
import {
|
|
@@ -8801,6 +8801,365 @@ var init_ask = __esm(() => {
|
|
|
8801
8801
|
import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
8802
8802
|
});
|
|
8803
8803
|
|
|
8804
|
+
// src/auth/errors.ts
|
|
8805
|
+
var OAuthCallbackError;
|
|
8806
|
+
var init_errors = __esm(() => {
|
|
8807
|
+
OAuthCallbackError = class OAuthCallbackError extends Error {
|
|
8808
|
+
error;
|
|
8809
|
+
errorCode;
|
|
8810
|
+
errorDescription;
|
|
8811
|
+
constructor(message, details = {}) {
|
|
8812
|
+
super(message);
|
|
8813
|
+
this.name = "OAuthCallbackError";
|
|
8814
|
+
this.error = details.error;
|
|
8815
|
+
this.errorCode = details.errorCode;
|
|
8816
|
+
this.errorDescription = details.errorDescription;
|
|
8817
|
+
}
|
|
8818
|
+
get userMessage() {
|
|
8819
|
+
const desc = this.errorDescription ?? this.message;
|
|
8820
|
+
if (this.errorCode === "bad_oauth_state" || /state/i.test(desc)) {
|
|
8821
|
+
return `Authentication failed: ${desc}. Run \`dosu login\` again.`;
|
|
8822
|
+
}
|
|
8823
|
+
return `Authentication failed: ${desc}`;
|
|
8824
|
+
}
|
|
8825
|
+
};
|
|
8826
|
+
});
|
|
8827
|
+
|
|
8828
|
+
// src/auth/server.ts
|
|
8829
|
+
function escapeHtml(value) {
|
|
8830
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
8831
|
+
}
|
|
8832
|
+
function buildErrorHtml(message) {
|
|
8833
|
+
const safe = escapeHtml(message);
|
|
8834
|
+
return `<!DOCTYPE html>
|
|
8835
|
+
<html lang="en">
|
|
8836
|
+
<head>
|
|
8837
|
+
<meta charset="UTF-8">
|
|
8838
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
8839
|
+
<title>Dosu CLI - Authentication Failed</title>
|
|
8840
|
+
<style>
|
|
8841
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
8842
|
+
body {
|
|
8843
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
8844
|
+
background: #fafafa;
|
|
8845
|
+
color: #171717;
|
|
8846
|
+
min-height: 100vh;
|
|
8847
|
+
display: flex;
|
|
8848
|
+
align-items: center;
|
|
8849
|
+
justify-content: center;
|
|
8850
|
+
padding: 20px;
|
|
8851
|
+
}
|
|
8852
|
+
.container {
|
|
8853
|
+
max-width: 480px;
|
|
8854
|
+
width: 100%;
|
|
8855
|
+
text-align: center;
|
|
8856
|
+
background: white;
|
|
8857
|
+
border: 1px solid #e5e7eb;
|
|
8858
|
+
border-radius: 12px;
|
|
8859
|
+
padding: 40px 32px;
|
|
8860
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
8861
|
+
}
|
|
8862
|
+
h1 { font-size: 20px; font-weight: 600; color: #b91c1c; margin-bottom: 12px; }
|
|
8863
|
+
p { font-size: 14px; color: #4b5563; line-height: 1.5; }
|
|
8864
|
+
.detail { margin-top: 16px; padding: 12px; background: #fef2f2; border-radius: 8px; color: #991b1b; font-size: 13px; }
|
|
8865
|
+
.next { margin-top: 20px; color: #6b7280; font-size: 13px; }
|
|
8866
|
+
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: #f3f4f6; padding: 2px 6px; border-radius: 4px; color: #111827; }
|
|
8867
|
+
</style>
|
|
8868
|
+
</head>
|
|
8869
|
+
<body>
|
|
8870
|
+
<div class="container">
|
|
8871
|
+
<h1>Authentication Failed</h1>
|
|
8872
|
+
<p>The OAuth flow could not be completed.</p>
|
|
8873
|
+
<div class="detail">${safe}</div>
|
|
8874
|
+
<p class="next">You can close this tab. In your terminal, run <code>dosu login</code> again.</p>
|
|
8875
|
+
</div>
|
|
8876
|
+
</body>
|
|
8877
|
+
</html>`;
|
|
8878
|
+
}
|
|
8879
|
+
function buildSuccessHtml(email, variant = "auth") {
|
|
8880
|
+
const copy = SUCCESS_COPY[variant];
|
|
8881
|
+
const closeMsg = copy.close;
|
|
8882
|
+
const emailLine = email ? `<p class="email">Signed in as <strong>${email.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</strong></p>` : "";
|
|
8883
|
+
return `<!DOCTYPE html>
|
|
8884
|
+
<html lang="en">
|
|
8885
|
+
<head>
|
|
8886
|
+
<meta charset="UTF-8">
|
|
8887
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
8888
|
+
<title>${copy.title}</title>
|
|
8889
|
+
<style>
|
|
8890
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
8891
|
+
body {
|
|
8892
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
8893
|
+
background: #fafafa;
|
|
8894
|
+
color: #171717;
|
|
8895
|
+
min-height: 100vh;
|
|
8896
|
+
position: relative;
|
|
8897
|
+
padding: 20px;
|
|
8898
|
+
}
|
|
8899
|
+
.container {
|
|
8900
|
+
position: absolute;
|
|
8901
|
+
top: 50%;
|
|
8902
|
+
left: 50%;
|
|
8903
|
+
transform: translate(-50%, -50%);
|
|
8904
|
+
max-width: 420px;
|
|
8905
|
+
width: 100%;
|
|
8906
|
+
text-align: center;
|
|
8907
|
+
}
|
|
8908
|
+
.logo {
|
|
8909
|
+
width: 52px;
|
|
8910
|
+
height: 52px;
|
|
8911
|
+
margin: 0 auto 28px;
|
|
8912
|
+
}
|
|
8913
|
+
h1 {
|
|
8914
|
+
font-size: 24px;
|
|
8915
|
+
font-weight: 600;
|
|
8916
|
+
color: #171717;
|
|
8917
|
+
letter-spacing: -0.02em;
|
|
8918
|
+
margin-bottom: 18px;
|
|
8919
|
+
}
|
|
8920
|
+
.email {
|
|
8921
|
+
font-size: 14px;
|
|
8922
|
+
color: #999;
|
|
8923
|
+
margin-bottom: 18px;
|
|
8924
|
+
}
|
|
8925
|
+
.close-msg {
|
|
8926
|
+
font-size: 16px;
|
|
8927
|
+
color: #666;
|
|
8928
|
+
}
|
|
8929
|
+
.tip {
|
|
8930
|
+
position: fixed;
|
|
8931
|
+
left: 50%;
|
|
8932
|
+
bottom: 28px;
|
|
8933
|
+
transform: translateX(-50%);
|
|
8934
|
+
width: calc(100vw - 48px);
|
|
8935
|
+
text-align: center;
|
|
8936
|
+
font-size: 14px;
|
|
8937
|
+
line-height: 1.5;
|
|
8938
|
+
color: #666;
|
|
8939
|
+
white-space: nowrap;
|
|
8940
|
+
}
|
|
8941
|
+
.tip-rule {
|
|
8942
|
+
display: flex;
|
|
8943
|
+
align-items: center;
|
|
8944
|
+
gap: 12px;
|
|
8945
|
+
width: min(720px, 100%);
|
|
8946
|
+
margin-bottom: 14px;
|
|
8947
|
+
margin-left: auto;
|
|
8948
|
+
margin-right: auto;
|
|
8949
|
+
}
|
|
8950
|
+
.tip-rule::before,
|
|
8951
|
+
.tip-rule::after {
|
|
8952
|
+
content: "";
|
|
8953
|
+
flex: 1;
|
|
8954
|
+
height: 1px;
|
|
8955
|
+
background: #eeeeee;
|
|
8956
|
+
}
|
|
8957
|
+
.tip-dot {
|
|
8958
|
+
width: 3px;
|
|
8959
|
+
height: 3px;
|
|
8960
|
+
border-radius: 999px;
|
|
8961
|
+
background: #dddddd;
|
|
8962
|
+
}
|
|
8963
|
+
.tip-label {
|
|
8964
|
+
font-weight: 600;
|
|
8965
|
+
color: #171717;
|
|
8966
|
+
}
|
|
8967
|
+
@media (max-width: 900px) {
|
|
8968
|
+
.tip {
|
|
8969
|
+
white-space: normal;
|
|
8970
|
+
}
|
|
8971
|
+
}
|
|
8972
|
+
</style>
|
|
8973
|
+
</head>
|
|
8974
|
+
<body>
|
|
8975
|
+
<div class="container">
|
|
8976
|
+
<div class="logo">
|
|
8977
|
+
<svg width="52" height="54" viewBox="0 0 86 89" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
8978
|
+
<path d="M5.29236 12.7928L17.7593 6.68188V72.5667L5.29236 84.0618V12.7928Z" fill="#B4BB91"/>
|
|
8979
|
+
<path d="M18.2575 73.1196L59.1329 72.748L51.7011 82.4095L29.0338 86.291L6.23962 85.1554L18.2575 73.1196Z" fill="#778561"/>
|
|
8980
|
+
<path d="M17.4916 3.73633L3.58557 12.7099V83.5792C3.58557 84.7542 4.98563 85.3652 5.84705 84.566L19.6296 71.7801" stroke="black" stroke-width="6.42844" stroke-linecap="round"/>
|
|
8981
|
+
<mask id="path-4-inside-1_355_26707" fill="white">
|
|
8982
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.704 0.518066H17.0439V76.2221H40.704H42.5805H47.8013C68.7064 76.2221 85.6533 59.2752 85.6533 38.3701C85.6533 17.465 68.7063 0.518066 47.8013 0.518066H42.5805H40.704Z"/>
|
|
8983
|
+
</mask>
|
|
8984
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.704 0.518066H17.0439V76.2221H40.704H42.5805H47.8013C68.7064 76.2221 85.6533 59.2752 85.6533 38.3701C85.6533 17.465 68.7063 0.518066 47.8013 0.518066H42.5805H40.704Z" fill="#F3F6F1"/>
|
|
8985
|
+
<path d="M17.0439 0.518066V-6.57919H9.94669V0.518066H17.0439ZM17.0439 76.2221H9.94669V83.3194H17.0439V76.2221ZM17.0439 7.61532H40.704V-6.57919H17.0439V7.61532ZM24.1412 76.2221V0.518066H9.94669V76.2221H24.1412ZM40.704 69.1249H17.0439V83.3194H40.704V69.1249ZM42.5805 69.1249H40.704V83.3194H42.5805V69.1249ZM47.8013 69.1249H42.5805V83.3194H47.8013V69.1249ZM78.556 38.3701C78.556 55.3555 64.7867 69.1249 47.8013 69.1249V83.3194C72.6261 83.3194 92.7505 63.1949 92.7505 38.3701H78.556ZM47.8013 7.61532C64.7866 7.61532 78.556 21.3847 78.556 38.3701H92.7505C92.7505 13.5453 72.626 -6.57919 47.8013 -6.57919V7.61532ZM42.5805 7.61532H47.8013V-6.57919H42.5805V7.61532ZM40.704 7.61532H42.5805V-6.57919H40.704V7.61532Z" fill="black" mask="url(#path-4-inside-1_355_26707)"/>
|
|
8986
|
+
<path d="M68.9215 36.0135C68.9215 36.0135 65.7369 49.4738 51.4231 49.4738C37.1093 49.4738 32.5787 37.3596 32.5787 36.0135" stroke="black" stroke-width="7.69161" stroke-linecap="round" stroke-linejoin="round"/>
|
|
8987
|
+
<path d="M0.348633 85.4946C0.348633 85.4946 29.4856 85.8309 34.809 85.698C44.8337 85.4477 51.2872 84.402 57.5269 78.9724C62.8129 74.3727 75.1342 59.6836 75.1342 59.6836" stroke="black" stroke-width="6.16482"/>
|
|
8988
|
+
</svg>
|
|
8989
|
+
</div>
|
|
8990
|
+
<h1 id="heading">${copy.heading}</h1>
|
|
8991
|
+
${emailLine}
|
|
8992
|
+
<p class="close-msg" id="close-msg">${closeMsg}</p>
|
|
8993
|
+
</div>
|
|
8994
|
+
<div class="tip">
|
|
8995
|
+
<div class="tip-rule" aria-hidden="true"><span class="tip-dot"></span></div>
|
|
8996
|
+
<span class="tip-label">Did you know?</span>
|
|
8997
|
+
You can use Dosu to make your coding agents faster and cheaper. Just ask your agent to use Dosu to update your AGENTS.md.
|
|
8998
|
+
</div>
|
|
8999
|
+
</body>
|
|
9000
|
+
</html>`;
|
|
9001
|
+
}
|
|
9002
|
+
async function startCallbackServer(opts = {}) {
|
|
9003
|
+
let resolveToken;
|
|
9004
|
+
let rejectToken;
|
|
9005
|
+
const tokenPromise = new Promise((resolve, reject) => {
|
|
9006
|
+
resolveToken = resolve;
|
|
9007
|
+
rejectToken = reject;
|
|
9008
|
+
});
|
|
9009
|
+
const http = __require("node:http");
|
|
9010
|
+
const httpServer = http.createServer((req, res) => {
|
|
9011
|
+
const url = new URL(req.url ?? "/", `http://localhost`);
|
|
9012
|
+
const cookieLen = (req.headers.cookie ?? "").length;
|
|
9013
|
+
const ua = req.headers["user-agent"] ?? "none";
|
|
9014
|
+
logger.debug("auth.server", `Request: ${req.method} ${url.pathname} cookie-len=${cookieLen} ua=${ua} has-token=${url.searchParams.has("access_token")}`);
|
|
9015
|
+
if (url.pathname !== "/callback") {
|
|
9016
|
+
logger.debug("auth.server", `404: ${url.pathname}`);
|
|
9017
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
9018
|
+
res.end("Not Found");
|
|
9019
|
+
return;
|
|
9020
|
+
}
|
|
9021
|
+
const errorParam = url.searchParams.get("error");
|
|
9022
|
+
const errorCodeParam = url.searchParams.get("error_code");
|
|
9023
|
+
const errorDescriptionParam = url.searchParams.get("error_description");
|
|
9024
|
+
if (errorParam || errorCodeParam || errorDescriptionParam) {
|
|
9025
|
+
const rawDescription = errorDescriptionParam ?? errorCodeParam ?? errorParam ?? "OAuth authentication failed";
|
|
9026
|
+
const sanitized = rawDescription.replace(/<[^>]*>/g, "");
|
|
9027
|
+
logger.warn("auth.server", `OAuth callback received error: code=${errorCodeParam ?? "n/a"} description=${sanitized}`);
|
|
9028
|
+
rejectToken?.(new OAuthCallbackError(sanitized, {
|
|
9029
|
+
error: errorParam ?? undefined,
|
|
9030
|
+
errorCode: errorCodeParam ?? undefined,
|
|
9031
|
+
errorDescription: sanitized
|
|
9032
|
+
}));
|
|
9033
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9034
|
+
res.end(buildErrorHtml(rawDescription));
|
|
9035
|
+
return;
|
|
9036
|
+
}
|
|
9037
|
+
const accessToken = url.searchParams.get("access_token");
|
|
9038
|
+
const refreshToken = url.searchParams.get("refresh_token");
|
|
9039
|
+
const expiresIn = url.searchParams.get("expires_in");
|
|
9040
|
+
const email = url.searchParams.get("email");
|
|
9041
|
+
if (!accessToken) {
|
|
9042
|
+
logger.debug("auth.server", "Served extract HTML (no token in query)");
|
|
9043
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9044
|
+
res.end(CALLBACK_HTML_EXTRACT);
|
|
9045
|
+
return;
|
|
9046
|
+
}
|
|
9047
|
+
let expiresInInt = 3600;
|
|
9048
|
+
if (expiresIn) {
|
|
9049
|
+
const parsed = parseInt(expiresIn, 10);
|
|
9050
|
+
if (!Number.isNaN(parsed))
|
|
9051
|
+
expiresInInt = parsed;
|
|
9052
|
+
}
|
|
9053
|
+
logger.info("auth.server", `Token resolved, email=${email ?? "none"}`);
|
|
9054
|
+
resolveToken?.({
|
|
9055
|
+
access_token: accessToken,
|
|
9056
|
+
refresh_token: refreshToken && refreshToken !== "null" ? refreshToken : "",
|
|
9057
|
+
expires_in: expiresInInt,
|
|
9058
|
+
email: email ?? undefined
|
|
9059
|
+
});
|
|
9060
|
+
logger.info("auth.server", "Served success HTML");
|
|
9061
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
9062
|
+
res.end(buildSuccessHtml(email ?? undefined, opts.successVariant ?? "auth"));
|
|
9063
|
+
});
|
|
9064
|
+
await new Promise((resolve) => {
|
|
9065
|
+
httpServer.listen(0, CALLBACK_HOST, () => resolve());
|
|
9066
|
+
});
|
|
9067
|
+
httpServer.unref();
|
|
9068
|
+
const addr = httpServer.address();
|
|
9069
|
+
logger.info("auth.server", `Callback server listening on port ${addr.port}`);
|
|
9070
|
+
return {
|
|
9071
|
+
server: {
|
|
9072
|
+
port: addr.port,
|
|
9073
|
+
close: () => {
|
|
9074
|
+
httpServer.close();
|
|
9075
|
+
httpServer.closeAllConnections?.();
|
|
9076
|
+
}
|
|
9077
|
+
},
|
|
9078
|
+
tokenPromise
|
|
9079
|
+
};
|
|
9080
|
+
}
|
|
9081
|
+
var CALLBACK_HTML_EXTRACT = `<!DOCTYPE html>
|
|
9082
|
+
<html lang="en">
|
|
9083
|
+
<head>
|
|
9084
|
+
<meta charset="UTF-8">
|
|
9085
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
9086
|
+
<title>Dosu CLI - Completing Authentication</title>
|
|
9087
|
+
<style>
|
|
9088
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9089
|
+
body {
|
|
9090
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
9091
|
+
background: #fafafa;
|
|
9092
|
+
min-height: 100vh;
|
|
9093
|
+
display: flex;
|
|
9094
|
+
align-items: center;
|
|
9095
|
+
justify-content: center;
|
|
9096
|
+
padding: 20px;
|
|
9097
|
+
}
|
|
9098
|
+
.container {
|
|
9099
|
+
background: white;
|
|
9100
|
+
border-radius: 12px;
|
|
9101
|
+
padding: 48px 40px;
|
|
9102
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
9103
|
+
max-width: 480px;
|
|
9104
|
+
width: 100%;
|
|
9105
|
+
text-align: center;
|
|
9106
|
+
border: 1px solid #e5e7eb;
|
|
9107
|
+
}
|
|
9108
|
+
.spinner {
|
|
9109
|
+
width: 48px;
|
|
9110
|
+
height: 48px;
|
|
9111
|
+
border: 4px solid #e5e7eb;
|
|
9112
|
+
border-top-color: #3b82f6;
|
|
9113
|
+
border-radius: 50%;
|
|
9114
|
+
animation: spin 0.8s linear infinite;
|
|
9115
|
+
margin: 0 auto 24px;
|
|
9116
|
+
}
|
|
9117
|
+
@keyframes spin { to { transform: rotate(360deg); } }
|
|
9118
|
+
h1 { font-size: 20px; font-weight: 600; color: #111827; margin-bottom: 8px; }
|
|
9119
|
+
p { font-size: 14px; color: #6b7280; }
|
|
9120
|
+
</style>
|
|
9121
|
+
</head>
|
|
9122
|
+
<body>
|
|
9123
|
+
<div class="container">
|
|
9124
|
+
<div class="spinner"></div>
|
|
9125
|
+
<h1>Completing authentication...</h1>
|
|
9126
|
+
<p>Please wait</p>
|
|
9127
|
+
</div>
|
|
9128
|
+
<script>
|
|
9129
|
+
const hash = window.location.hash.substring(1);
|
|
9130
|
+
if (hash) {
|
|
9131
|
+
const params = new URLSearchParams(hash);
|
|
9132
|
+
const token = params.get('access_token');
|
|
9133
|
+
const refresh = params.get('refresh_token') || '';
|
|
9134
|
+
const expires = params.get('expires_in') || '';
|
|
9135
|
+
const email = params.get('email');
|
|
9136
|
+
if (token) {
|
|
9137
|
+
window.location.href = '/callback?access_token=' + encodeURIComponent(token) +
|
|
9138
|
+
'&refresh_token=' + encodeURIComponent(refresh) +
|
|
9139
|
+
'&expires_in=' + encodeURIComponent(expires) +
|
|
9140
|
+
(email ? '&email=' + encodeURIComponent(email) : '');
|
|
9141
|
+
}
|
|
9142
|
+
}
|
|
9143
|
+
</script>
|
|
9144
|
+
</body>
|
|
9145
|
+
</html>`, SUCCESS_COPY, CALLBACK_HOST = "127.0.0.1";
|
|
9146
|
+
var init_server = __esm(() => {
|
|
9147
|
+
init_logger();
|
|
9148
|
+
init_errors();
|
|
9149
|
+
SUCCESS_COPY = {
|
|
9150
|
+
auth: {
|
|
9151
|
+
title: "Dosu CLI - Authentication Successful",
|
|
9152
|
+
heading: "Authentication Successful",
|
|
9153
|
+
close: "You can close this tab and return to your terminal."
|
|
9154
|
+
},
|
|
9155
|
+
onboarding: {
|
|
9156
|
+
title: "Dosu CLI - Onboarding Complete",
|
|
9157
|
+
heading: "Onboarding Complete",
|
|
9158
|
+
close: "You're all set. Return to your terminal, where Dosu is finishing your setup."
|
|
9159
|
+
}
|
|
9160
|
+
};
|
|
9161
|
+
});
|
|
9162
|
+
|
|
8804
9163
|
// src/setup/styles.ts
|
|
8805
9164
|
import { stripVTControlCharacters as stripVTControlCharacters4 } from "node:util";
|
|
8806
9165
|
function hasTruecolor() {
|
|
@@ -9770,7 +10129,7 @@ async function startInstallationCallbackServer() {
|
|
|
9770
10129
|
res.end(SUCCESS_HTML);
|
|
9771
10130
|
});
|
|
9772
10131
|
await new Promise((resolve) => {
|
|
9773
|
-
httpServer.listen(0,
|
|
10132
|
+
httpServer.listen(0, CALLBACK_HOST, () => resolve());
|
|
9774
10133
|
});
|
|
9775
10134
|
const addr = httpServer.address();
|
|
9776
10135
|
logger.info("installation.server", `Listening on port ${addr.port}`);
|
|
@@ -9956,6 +10315,7 @@ var SUCCESS_HTML = `<!DOCTYPE html>
|
|
|
9956
10315
|
</body>
|
|
9957
10316
|
</html>`;
|
|
9958
10317
|
var init_installation_server = __esm(() => {
|
|
10318
|
+
init_server();
|
|
9959
10319
|
init_logger();
|
|
9960
10320
|
});
|
|
9961
10321
|
|
|
@@ -10764,7 +11124,7 @@ async function openGitHubInstallFlow(onInstalled, opts) {
|
|
|
10764
11124
|
const { server, installationPromise } = await startInstallationCallbackServer();
|
|
10765
11125
|
let timeoutId;
|
|
10766
11126
|
try {
|
|
10767
|
-
const callbackURL = `http
|
|
11127
|
+
const callbackURL = `http://${CALLBACK_HOST}:${server.port}/callback`;
|
|
10768
11128
|
const webAppURL = getWebAppURL();
|
|
10769
11129
|
const middleURL = new URL("/cli/connect-github", webAppURL);
|
|
10770
11130
|
middleURL.searchParams.set("callback", callbackURL);
|
|
@@ -11043,6 +11403,7 @@ async function stepConnectGitHubRepo(cfg, detected = detectGitRepo(), opts = {})
|
|
|
11043
11403
|
}
|
|
11044
11404
|
var INSTALLATION_TIMEOUT_MS, REPO_REFRESH_POLL_INTERVAL_MS = 500, REPO_REFRESH_POLL_TIMEOUT_MS = 1e4, REPO_MULTISELECT_MAX_ITEMS = 10, DATA_SOURCE_VERIFY_POLL_INTERVAL_MS = 1000, DATA_SOURCE_VERIFY_POLL_TIMEOUT_MS = 1e4;
|
|
11045
11405
|
var init_github_step = __esm(() => {
|
|
11406
|
+
init_server();
|
|
11046
11407
|
init_trpc();
|
|
11047
11408
|
init_logger();
|
|
11048
11409
|
init_prompts();
|
|
@@ -11621,7 +11982,7 @@ var init_deployments = __esm(() => {
|
|
|
11621
11982
|
|
|
11622
11983
|
// src/cli/errors.ts
|
|
11623
11984
|
var CliUsageError;
|
|
11624
|
-
var
|
|
11985
|
+
var init_errors2 = __esm(() => {
|
|
11625
11986
|
CliUsageError = class CliUsageError extends Error {
|
|
11626
11987
|
exitCode = 1;
|
|
11627
11988
|
constructor(message) {
|
|
@@ -12061,7 +12422,7 @@ var init_docs = __esm(() => {
|
|
|
12061
12422
|
init_dist8();
|
|
12062
12423
|
init_dist();
|
|
12063
12424
|
init_commander();
|
|
12064
|
-
|
|
12425
|
+
init_errors2();
|
|
12065
12426
|
init_client();
|
|
12066
12427
|
init_trpc();
|
|
12067
12428
|
init_logger();
|
|
@@ -14356,7 +14717,7 @@ var init_conflicts = __esm(() => {
|
|
|
14356
14717
|
});
|
|
14357
14718
|
|
|
14358
14719
|
// src/telemetry/debug-id.ts
|
|
14359
|
-
var BUNDLE_DEBUG_ID_PLACEHOLDER = "
|
|
14720
|
+
var BUNDLE_DEBUG_ID_PLACEHOLDER = "af4149bf-b423-bc43-6475-6e2164756e21";
|
|
14360
14721
|
|
|
14361
14722
|
// src/telemetry/telemetry.ts
|
|
14362
14723
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -54580,7 +54941,7 @@ var _messageDesc, _zodDesc2, _issuesDesc, _installedToString, initializer = (ins
|
|
|
54580
54941
|
});
|
|
54581
54942
|
}
|
|
54582
54943
|
}, $ZodError, $ZodRealError;
|
|
54583
|
-
var
|
|
54944
|
+
var init_errors3 = __esm(() => {
|
|
54584
54945
|
init_core();
|
|
54585
54946
|
init_util();
|
|
54586
54947
|
_messageDesc = {
|
|
@@ -54689,7 +55050,7 @@ var _parse = (_Err) => {
|
|
|
54689
55050
|
};
|
|
54690
55051
|
var init_parse = __esm(() => {
|
|
54691
55052
|
init_core();
|
|
54692
|
-
|
|
55053
|
+
init_errors3();
|
|
54693
55054
|
init_util();
|
|
54694
55055
|
safeParse = /* @__PURE__ */ _safeParse($ZodRealError);
|
|
54695
55056
|
safeParseAsync = /* @__PURE__ */ _safeParseAsync($ZodRealError);
|
|
@@ -57691,7 +58052,7 @@ var init_core2 = __esm(() => {
|
|
|
57691
58052
|
init_json_schema();
|
|
57692
58053
|
init_core();
|
|
57693
58054
|
init_parse();
|
|
57694
|
-
|
|
58055
|
+
init_errors3();
|
|
57695
58056
|
init_schemas();
|
|
57696
58057
|
init_memoizer();
|
|
57697
58058
|
init_checks();
|
|
@@ -57747,7 +58108,7 @@ var _installedErrorProtos, initializer2 = (inst, issues) => {
|
|
|
57747
58108
|
}
|
|
57748
58109
|
});
|
|
57749
58110
|
}, ZodRealError;
|
|
57750
|
-
var
|
|
58111
|
+
var init_errors4 = __esm(() => {
|
|
57751
58112
|
init_core2();
|
|
57752
58113
|
init_core2();
|
|
57753
58114
|
init_util();
|
|
@@ -57761,7 +58122,7 @@ var init_errors3 = __esm(() => {
|
|
|
57761
58122
|
var parse6, parseAsync2, safeParse2, safeParseAsync2, encode, decode, encodeAsync, decodeAsync, safeEncode, safeDecode, safeEncodeAsync, safeDecodeAsync;
|
|
57762
58123
|
var init_parse2 = __esm(() => {
|
|
57763
58124
|
init_core2();
|
|
57764
|
-
|
|
58125
|
+
init_errors4();
|
|
57765
58126
|
parse6 = /* @__PURE__ */ _parse(ZodRealError);
|
|
57766
58127
|
parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
57767
58128
|
safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
@@ -58510,7 +58871,7 @@ var init_external = __esm(() => {
|
|
|
58510
58871
|
init_coerce();
|
|
58511
58872
|
init_schemas2();
|
|
58512
58873
|
init_checks2();
|
|
58513
|
-
|
|
58874
|
+
init_errors4();
|
|
58514
58875
|
init_parse2();
|
|
58515
58876
|
init_compat();
|
|
58516
58877
|
});
|
|
@@ -61932,7 +62293,7 @@ function sourcesCommand() {
|
|
|
61932
62293
|
let timeoutId;
|
|
61933
62294
|
try {
|
|
61934
62295
|
const connectURL = new URL("/cli/connect-github", getWebAppURL());
|
|
61935
|
-
connectURL.searchParams.set("callback", `http
|
|
62296
|
+
connectURL.searchParams.set("callback", `http://${CALLBACK_HOST}:${server.port}/callback`);
|
|
61936
62297
|
const url = connectURL.toString();
|
|
61937
62298
|
if (opts.json) {
|
|
61938
62299
|
console.log(JSON.stringify({
|
|
@@ -62070,6 +62431,7 @@ function sourcesCommand() {
|
|
|
62070
62431
|
var import_picocolors29, CONNECT_TIMEOUT_DEFAULT_SECONDS = 600;
|
|
62071
62432
|
var init_sources = __esm(() => {
|
|
62072
62433
|
init_commander();
|
|
62434
|
+
init_server();
|
|
62073
62435
|
init_trpc();
|
|
62074
62436
|
init_github_step();
|
|
62075
62437
|
init_installation_server();
|
|
@@ -63690,30 +64052,6 @@ var init_skill_update_check = __esm(() => {
|
|
|
63690
64052
|
import_picocolors33 = __toESM(require_picocolors(), 1);
|
|
63691
64053
|
});
|
|
63692
64054
|
|
|
63693
|
-
// src/auth/errors.ts
|
|
63694
|
-
var OAuthCallbackError;
|
|
63695
|
-
var init_errors4 = __esm(() => {
|
|
63696
|
-
OAuthCallbackError = class OAuthCallbackError extends Error {
|
|
63697
|
-
error;
|
|
63698
|
-
errorCode;
|
|
63699
|
-
errorDescription;
|
|
63700
|
-
constructor(message, details = {}) {
|
|
63701
|
-
super(message);
|
|
63702
|
-
this.name = "OAuthCallbackError";
|
|
63703
|
-
this.error = details.error;
|
|
63704
|
-
this.errorCode = details.errorCode;
|
|
63705
|
-
this.errorDescription = details.errorDescription;
|
|
63706
|
-
}
|
|
63707
|
-
get userMessage() {
|
|
63708
|
-
const desc = this.errorDescription ?? this.message;
|
|
63709
|
-
if (this.errorCode === "bad_oauth_state" || /state/i.test(desc)) {
|
|
63710
|
-
return `Authentication failed: ${desc}. Run \`dosu login\` again.`;
|
|
63711
|
-
}
|
|
63712
|
-
return `Authentication failed: ${desc}`;
|
|
63713
|
-
}
|
|
63714
|
-
};
|
|
63715
|
-
});
|
|
63716
|
-
|
|
63717
64055
|
// src/mcp/constants.ts
|
|
63718
64056
|
var MCP_PROVIDER_SLUG2 = "dosu_mcp";
|
|
63719
64057
|
|
|
@@ -65022,341 +65360,6 @@ var init_rules_step = __esm(() => {
|
|
|
65022
65360
|
init_styles();
|
|
65023
65361
|
});
|
|
65024
65362
|
|
|
65025
|
-
// src/auth/server.ts
|
|
65026
|
-
function escapeHtml(value) {
|
|
65027
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
65028
|
-
}
|
|
65029
|
-
function buildErrorHtml(message) {
|
|
65030
|
-
const safe = escapeHtml(message);
|
|
65031
|
-
return `<!DOCTYPE html>
|
|
65032
|
-
<html lang="en">
|
|
65033
|
-
<head>
|
|
65034
|
-
<meta charset="UTF-8">
|
|
65035
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
65036
|
-
<title>Dosu CLI - Authentication Failed</title>
|
|
65037
|
-
<style>
|
|
65038
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
65039
|
-
body {
|
|
65040
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
65041
|
-
background: #fafafa;
|
|
65042
|
-
color: #171717;
|
|
65043
|
-
min-height: 100vh;
|
|
65044
|
-
display: flex;
|
|
65045
|
-
align-items: center;
|
|
65046
|
-
justify-content: center;
|
|
65047
|
-
padding: 20px;
|
|
65048
|
-
}
|
|
65049
|
-
.container {
|
|
65050
|
-
max-width: 480px;
|
|
65051
|
-
width: 100%;
|
|
65052
|
-
text-align: center;
|
|
65053
|
-
background: white;
|
|
65054
|
-
border: 1px solid #e5e7eb;
|
|
65055
|
-
border-radius: 12px;
|
|
65056
|
-
padding: 40px 32px;
|
|
65057
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
65058
|
-
}
|
|
65059
|
-
h1 { font-size: 20px; font-weight: 600; color: #b91c1c; margin-bottom: 12px; }
|
|
65060
|
-
p { font-size: 14px; color: #4b5563; line-height: 1.5; }
|
|
65061
|
-
.detail { margin-top: 16px; padding: 12px; background: #fef2f2; border-radius: 8px; color: #991b1b; font-size: 13px; }
|
|
65062
|
-
.next { margin-top: 20px; color: #6b7280; font-size: 13px; }
|
|
65063
|
-
code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: #f3f4f6; padding: 2px 6px; border-radius: 4px; color: #111827; }
|
|
65064
|
-
</style>
|
|
65065
|
-
</head>
|
|
65066
|
-
<body>
|
|
65067
|
-
<div class="container">
|
|
65068
|
-
<h1>Authentication Failed</h1>
|
|
65069
|
-
<p>The OAuth flow could not be completed.</p>
|
|
65070
|
-
<div class="detail">${safe}</div>
|
|
65071
|
-
<p class="next">You can close this tab. In your terminal, run <code>dosu login</code> again.</p>
|
|
65072
|
-
</div>
|
|
65073
|
-
</body>
|
|
65074
|
-
</html>`;
|
|
65075
|
-
}
|
|
65076
|
-
function buildSuccessHtml(email, variant = "auth") {
|
|
65077
|
-
const copy = SUCCESS_COPY[variant];
|
|
65078
|
-
const closeMsg = copy.close;
|
|
65079
|
-
const emailLine = email ? `<p class="email">Signed in as <strong>${email.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</strong></p>` : "";
|
|
65080
|
-
return `<!DOCTYPE html>
|
|
65081
|
-
<html lang="en">
|
|
65082
|
-
<head>
|
|
65083
|
-
<meta charset="UTF-8">
|
|
65084
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
65085
|
-
<title>${copy.title}</title>
|
|
65086
|
-
<style>
|
|
65087
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
65088
|
-
body {
|
|
65089
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
65090
|
-
background: #fafafa;
|
|
65091
|
-
color: #171717;
|
|
65092
|
-
min-height: 100vh;
|
|
65093
|
-
position: relative;
|
|
65094
|
-
padding: 20px;
|
|
65095
|
-
}
|
|
65096
|
-
.container {
|
|
65097
|
-
position: absolute;
|
|
65098
|
-
top: 50%;
|
|
65099
|
-
left: 50%;
|
|
65100
|
-
transform: translate(-50%, -50%);
|
|
65101
|
-
max-width: 420px;
|
|
65102
|
-
width: 100%;
|
|
65103
|
-
text-align: center;
|
|
65104
|
-
}
|
|
65105
|
-
.logo {
|
|
65106
|
-
width: 52px;
|
|
65107
|
-
height: 52px;
|
|
65108
|
-
margin: 0 auto 28px;
|
|
65109
|
-
}
|
|
65110
|
-
h1 {
|
|
65111
|
-
font-size: 24px;
|
|
65112
|
-
font-weight: 600;
|
|
65113
|
-
color: #171717;
|
|
65114
|
-
letter-spacing: -0.02em;
|
|
65115
|
-
margin-bottom: 18px;
|
|
65116
|
-
}
|
|
65117
|
-
.email {
|
|
65118
|
-
font-size: 14px;
|
|
65119
|
-
color: #999;
|
|
65120
|
-
margin-bottom: 18px;
|
|
65121
|
-
}
|
|
65122
|
-
.close-msg {
|
|
65123
|
-
font-size: 16px;
|
|
65124
|
-
color: #666;
|
|
65125
|
-
}
|
|
65126
|
-
.tip {
|
|
65127
|
-
position: fixed;
|
|
65128
|
-
left: 50%;
|
|
65129
|
-
bottom: 28px;
|
|
65130
|
-
transform: translateX(-50%);
|
|
65131
|
-
width: calc(100vw - 48px);
|
|
65132
|
-
text-align: center;
|
|
65133
|
-
font-size: 14px;
|
|
65134
|
-
line-height: 1.5;
|
|
65135
|
-
color: #666;
|
|
65136
|
-
white-space: nowrap;
|
|
65137
|
-
}
|
|
65138
|
-
.tip-rule {
|
|
65139
|
-
display: flex;
|
|
65140
|
-
align-items: center;
|
|
65141
|
-
gap: 12px;
|
|
65142
|
-
width: min(720px, 100%);
|
|
65143
|
-
margin-bottom: 14px;
|
|
65144
|
-
margin-left: auto;
|
|
65145
|
-
margin-right: auto;
|
|
65146
|
-
}
|
|
65147
|
-
.tip-rule::before,
|
|
65148
|
-
.tip-rule::after {
|
|
65149
|
-
content: "";
|
|
65150
|
-
flex: 1;
|
|
65151
|
-
height: 1px;
|
|
65152
|
-
background: #eeeeee;
|
|
65153
|
-
}
|
|
65154
|
-
.tip-dot {
|
|
65155
|
-
width: 3px;
|
|
65156
|
-
height: 3px;
|
|
65157
|
-
border-radius: 999px;
|
|
65158
|
-
background: #dddddd;
|
|
65159
|
-
}
|
|
65160
|
-
.tip-label {
|
|
65161
|
-
font-weight: 600;
|
|
65162
|
-
color: #171717;
|
|
65163
|
-
}
|
|
65164
|
-
@media (max-width: 900px) {
|
|
65165
|
-
.tip {
|
|
65166
|
-
white-space: normal;
|
|
65167
|
-
}
|
|
65168
|
-
}
|
|
65169
|
-
</style>
|
|
65170
|
-
</head>
|
|
65171
|
-
<body>
|
|
65172
|
-
<div class="container">
|
|
65173
|
-
<div class="logo">
|
|
65174
|
-
<svg width="52" height="54" viewBox="0 0 86 89" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
65175
|
-
<path d="M5.29236 12.7928L17.7593 6.68188V72.5667L5.29236 84.0618V12.7928Z" fill="#B4BB91"/>
|
|
65176
|
-
<path d="M18.2575 73.1196L59.1329 72.748L51.7011 82.4095L29.0338 86.291L6.23962 85.1554L18.2575 73.1196Z" fill="#778561"/>
|
|
65177
|
-
<path d="M17.4916 3.73633L3.58557 12.7099V83.5792C3.58557 84.7542 4.98563 85.3652 5.84705 84.566L19.6296 71.7801" stroke="black" stroke-width="6.42844" stroke-linecap="round"/>
|
|
65178
|
-
<mask id="path-4-inside-1_355_26707" fill="white">
|
|
65179
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.704 0.518066H17.0439V76.2221H40.704H42.5805H47.8013C68.7064 76.2221 85.6533 59.2752 85.6533 38.3701C85.6533 17.465 68.7063 0.518066 47.8013 0.518066H42.5805H40.704Z"/>
|
|
65180
|
-
</mask>
|
|
65181
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.704 0.518066H17.0439V76.2221H40.704H42.5805H47.8013C68.7064 76.2221 85.6533 59.2752 85.6533 38.3701C85.6533 17.465 68.7063 0.518066 47.8013 0.518066H42.5805H40.704Z" fill="#F3F6F1"/>
|
|
65182
|
-
<path d="M17.0439 0.518066V-6.57919H9.94669V0.518066H17.0439ZM17.0439 76.2221H9.94669V83.3194H17.0439V76.2221ZM17.0439 7.61532H40.704V-6.57919H17.0439V7.61532ZM24.1412 76.2221V0.518066H9.94669V76.2221H24.1412ZM40.704 69.1249H17.0439V83.3194H40.704V69.1249ZM42.5805 69.1249H40.704V83.3194H42.5805V69.1249ZM47.8013 69.1249H42.5805V83.3194H47.8013V69.1249ZM78.556 38.3701C78.556 55.3555 64.7867 69.1249 47.8013 69.1249V83.3194C72.6261 83.3194 92.7505 63.1949 92.7505 38.3701H78.556ZM47.8013 7.61532C64.7866 7.61532 78.556 21.3847 78.556 38.3701H92.7505C92.7505 13.5453 72.626 -6.57919 47.8013 -6.57919V7.61532ZM42.5805 7.61532H47.8013V-6.57919H42.5805V7.61532ZM40.704 7.61532H42.5805V-6.57919H40.704V7.61532Z" fill="black" mask="url(#path-4-inside-1_355_26707)"/>
|
|
65183
|
-
<path d="M68.9215 36.0135C68.9215 36.0135 65.7369 49.4738 51.4231 49.4738C37.1093 49.4738 32.5787 37.3596 32.5787 36.0135" stroke="black" stroke-width="7.69161" stroke-linecap="round" stroke-linejoin="round"/>
|
|
65184
|
-
<path d="M0.348633 85.4946C0.348633 85.4946 29.4856 85.8309 34.809 85.698C44.8337 85.4477 51.2872 84.402 57.5269 78.9724C62.8129 74.3727 75.1342 59.6836 75.1342 59.6836" stroke="black" stroke-width="6.16482"/>
|
|
65185
|
-
</svg>
|
|
65186
|
-
</div>
|
|
65187
|
-
<h1 id="heading">${copy.heading}</h1>
|
|
65188
|
-
${emailLine}
|
|
65189
|
-
<p class="close-msg" id="close-msg">${closeMsg}</p>
|
|
65190
|
-
</div>
|
|
65191
|
-
<div class="tip">
|
|
65192
|
-
<div class="tip-rule" aria-hidden="true"><span class="tip-dot"></span></div>
|
|
65193
|
-
<span class="tip-label">Did you know?</span>
|
|
65194
|
-
You can use Dosu to make your coding agents faster and cheaper. Just ask your agent to use Dosu to update your AGENTS.md.
|
|
65195
|
-
</div>
|
|
65196
|
-
</body>
|
|
65197
|
-
</html>`;
|
|
65198
|
-
}
|
|
65199
|
-
async function startCallbackServer(opts = {}) {
|
|
65200
|
-
let resolveToken;
|
|
65201
|
-
let rejectToken;
|
|
65202
|
-
const tokenPromise = new Promise((resolve, reject) => {
|
|
65203
|
-
resolveToken = resolve;
|
|
65204
|
-
rejectToken = reject;
|
|
65205
|
-
});
|
|
65206
|
-
const http = __require("node:http");
|
|
65207
|
-
const httpServer = http.createServer((req, res) => {
|
|
65208
|
-
const url = new URL(req.url ?? "/", `http://localhost`);
|
|
65209
|
-
const cookieLen = (req.headers.cookie ?? "").length;
|
|
65210
|
-
const ua = req.headers["user-agent"] ?? "none";
|
|
65211
|
-
logger.debug("auth.server", `Request: ${req.method} ${url.pathname} cookie-len=${cookieLen} ua=${ua} has-token=${url.searchParams.has("access_token")}`);
|
|
65212
|
-
if (url.pathname !== "/callback") {
|
|
65213
|
-
logger.debug("auth.server", `404: ${url.pathname}`);
|
|
65214
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
65215
|
-
res.end("Not Found");
|
|
65216
|
-
return;
|
|
65217
|
-
}
|
|
65218
|
-
const errorParam = url.searchParams.get("error");
|
|
65219
|
-
const errorCodeParam = url.searchParams.get("error_code");
|
|
65220
|
-
const errorDescriptionParam = url.searchParams.get("error_description");
|
|
65221
|
-
if (errorParam || errorCodeParam || errorDescriptionParam) {
|
|
65222
|
-
const rawDescription = errorDescriptionParam ?? errorCodeParam ?? errorParam ?? "OAuth authentication failed";
|
|
65223
|
-
const sanitized = rawDescription.replace(/<[^>]*>/g, "");
|
|
65224
|
-
logger.warn("auth.server", `OAuth callback received error: code=${errorCodeParam ?? "n/a"} description=${sanitized}`);
|
|
65225
|
-
rejectToken?.(new OAuthCallbackError(sanitized, {
|
|
65226
|
-
error: errorParam ?? undefined,
|
|
65227
|
-
errorCode: errorCodeParam ?? undefined,
|
|
65228
|
-
errorDescription: sanitized
|
|
65229
|
-
}));
|
|
65230
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
65231
|
-
res.end(buildErrorHtml(rawDescription));
|
|
65232
|
-
return;
|
|
65233
|
-
}
|
|
65234
|
-
const accessToken = url.searchParams.get("access_token");
|
|
65235
|
-
const refreshToken = url.searchParams.get("refresh_token");
|
|
65236
|
-
const expiresIn = url.searchParams.get("expires_in");
|
|
65237
|
-
const email = url.searchParams.get("email");
|
|
65238
|
-
if (!accessToken) {
|
|
65239
|
-
logger.debug("auth.server", "Served extract HTML (no token in query)");
|
|
65240
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
65241
|
-
res.end(CALLBACK_HTML_EXTRACT);
|
|
65242
|
-
return;
|
|
65243
|
-
}
|
|
65244
|
-
let expiresInInt = 3600;
|
|
65245
|
-
if (expiresIn) {
|
|
65246
|
-
const parsed = parseInt(expiresIn, 10);
|
|
65247
|
-
if (!Number.isNaN(parsed))
|
|
65248
|
-
expiresInInt = parsed;
|
|
65249
|
-
}
|
|
65250
|
-
logger.info("auth.server", `Token resolved, email=${email ?? "none"}`);
|
|
65251
|
-
resolveToken?.({
|
|
65252
|
-
access_token: accessToken,
|
|
65253
|
-
refresh_token: refreshToken && refreshToken !== "null" ? refreshToken : "",
|
|
65254
|
-
expires_in: expiresInInt,
|
|
65255
|
-
email: email ?? undefined
|
|
65256
|
-
});
|
|
65257
|
-
logger.info("auth.server", "Served success HTML");
|
|
65258
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
65259
|
-
res.end(buildSuccessHtml(email ?? undefined, opts.successVariant ?? "auth"));
|
|
65260
|
-
});
|
|
65261
|
-
await new Promise((resolve) => {
|
|
65262
|
-
httpServer.listen(0, CALLBACK_HOST, () => resolve());
|
|
65263
|
-
});
|
|
65264
|
-
httpServer.unref();
|
|
65265
|
-
const addr = httpServer.address();
|
|
65266
|
-
logger.info("auth.server", `Callback server listening on port ${addr.port}`);
|
|
65267
|
-
return {
|
|
65268
|
-
server: {
|
|
65269
|
-
port: addr.port,
|
|
65270
|
-
close: () => {
|
|
65271
|
-
httpServer.close();
|
|
65272
|
-
httpServer.closeAllConnections?.();
|
|
65273
|
-
}
|
|
65274
|
-
},
|
|
65275
|
-
tokenPromise
|
|
65276
|
-
};
|
|
65277
|
-
}
|
|
65278
|
-
var CALLBACK_HTML_EXTRACT = `<!DOCTYPE html>
|
|
65279
|
-
<html lang="en">
|
|
65280
|
-
<head>
|
|
65281
|
-
<meta charset="UTF-8">
|
|
65282
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
65283
|
-
<title>Dosu CLI - Completing Authentication</title>
|
|
65284
|
-
<style>
|
|
65285
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
65286
|
-
body {
|
|
65287
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
65288
|
-
background: #fafafa;
|
|
65289
|
-
min-height: 100vh;
|
|
65290
|
-
display: flex;
|
|
65291
|
-
align-items: center;
|
|
65292
|
-
justify-content: center;
|
|
65293
|
-
padding: 20px;
|
|
65294
|
-
}
|
|
65295
|
-
.container {
|
|
65296
|
-
background: white;
|
|
65297
|
-
border-radius: 12px;
|
|
65298
|
-
padding: 48px 40px;
|
|
65299
|
-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
|
65300
|
-
max-width: 480px;
|
|
65301
|
-
width: 100%;
|
|
65302
|
-
text-align: center;
|
|
65303
|
-
border: 1px solid #e5e7eb;
|
|
65304
|
-
}
|
|
65305
|
-
.spinner {
|
|
65306
|
-
width: 48px;
|
|
65307
|
-
height: 48px;
|
|
65308
|
-
border: 4px solid #e5e7eb;
|
|
65309
|
-
border-top-color: #3b82f6;
|
|
65310
|
-
border-radius: 50%;
|
|
65311
|
-
animation: spin 0.8s linear infinite;
|
|
65312
|
-
margin: 0 auto 24px;
|
|
65313
|
-
}
|
|
65314
|
-
@keyframes spin { to { transform: rotate(360deg); } }
|
|
65315
|
-
h1 { font-size: 20px; font-weight: 600; color: #111827; margin-bottom: 8px; }
|
|
65316
|
-
p { font-size: 14px; color: #6b7280; }
|
|
65317
|
-
</style>
|
|
65318
|
-
</head>
|
|
65319
|
-
<body>
|
|
65320
|
-
<div class="container">
|
|
65321
|
-
<div class="spinner"></div>
|
|
65322
|
-
<h1>Completing authentication...</h1>
|
|
65323
|
-
<p>Please wait</p>
|
|
65324
|
-
</div>
|
|
65325
|
-
<script>
|
|
65326
|
-
const hash = window.location.hash.substring(1);
|
|
65327
|
-
if (hash) {
|
|
65328
|
-
const params = new URLSearchParams(hash);
|
|
65329
|
-
const token = params.get('access_token');
|
|
65330
|
-
const refresh = params.get('refresh_token') || '';
|
|
65331
|
-
const expires = params.get('expires_in') || '';
|
|
65332
|
-
const email = params.get('email');
|
|
65333
|
-
if (token) {
|
|
65334
|
-
window.location.href = '/callback?access_token=' + encodeURIComponent(token) +
|
|
65335
|
-
'&refresh_token=' + encodeURIComponent(refresh) +
|
|
65336
|
-
'&expires_in=' + encodeURIComponent(expires) +
|
|
65337
|
-
(email ? '&email=' + encodeURIComponent(email) : '');
|
|
65338
|
-
}
|
|
65339
|
-
}
|
|
65340
|
-
</script>
|
|
65341
|
-
</body>
|
|
65342
|
-
</html>`, SUCCESS_COPY, CALLBACK_HOST = "127.0.0.1";
|
|
65343
|
-
var init_server = __esm(() => {
|
|
65344
|
-
init_logger();
|
|
65345
|
-
init_errors4();
|
|
65346
|
-
SUCCESS_COPY = {
|
|
65347
|
-
auth: {
|
|
65348
|
-
title: "Dosu CLI - Authentication Successful",
|
|
65349
|
-
heading: "Authentication Successful",
|
|
65350
|
-
close: "You can close this tab and return to your terminal."
|
|
65351
|
-
},
|
|
65352
|
-
onboarding: {
|
|
65353
|
-
title: "Dosu CLI - Onboarding Complete",
|
|
65354
|
-
heading: "Onboarding Complete",
|
|
65355
|
-
close: "You're all set. Return to your terminal, where Dosu is finishing your setup."
|
|
65356
|
-
}
|
|
65357
|
-
};
|
|
65358
|
-
});
|
|
65359
|
-
|
|
65360
65363
|
// src/auth/flow.ts
|
|
65361
65364
|
async function startOAuthFlow(signal, path = "/cli/auth", params = {}, onAuthURL, options = {}) {
|
|
65362
65365
|
const { server, tokenPromise } = await startCallbackServer({
|
|
@@ -65821,7 +65824,7 @@ async function stepSetupHandshake(cfg, onboardingRunID) {
|
|
|
65821
65824
|
const msg = err instanceof Error ? err.message : String(err);
|
|
65822
65825
|
logger.warn("setup", `Setup handshake did not complete: ${msg}`);
|
|
65823
65826
|
s.stop("Setup not completed");
|
|
65824
|
-
await Promise.resolve().then(() =>
|
|
65827
|
+
await Promise.resolve().then(() => init_errors());
|
|
65825
65828
|
if (err instanceof OAuthCallbackError) {
|
|
65826
65829
|
log2.error(err.userMessage);
|
|
65827
65830
|
return false;
|
|
@@ -66362,7 +66365,7 @@ ${dim(wrapLog("Type it in a chat to keep that chat out of Dosu. To keep a whole
|
|
|
66362
66365
|
}
|
|
66363
66366
|
var import_picocolors35, OAUTH_ANALYTICS_REASONS, SETUP_HANDSHAKE_TIMEOUT_MS = 1800000, LIBRARY_SELECT_CANCELLED;
|
|
66364
66367
|
var init_flow2 = __esm(() => {
|
|
66365
|
-
|
|
66368
|
+
init_errors();
|
|
66366
66369
|
init_client();
|
|
66367
66370
|
init_skill();
|
|
66368
66371
|
init_config();
|
|
@@ -68018,7 +68021,7 @@ async function handleAuthenticate(cfg) {
|
|
|
68018
68021
|
});
|
|
68019
68022
|
saveConfig(cfg);
|
|
68020
68023
|
} catch (err) {
|
|
68021
|
-
await Promise.resolve().then(() =>
|
|
68024
|
+
await Promise.resolve().then(() => init_errors());
|
|
68022
68025
|
if (err instanceof OAuthCallbackError) {
|
|
68023
68026
|
log2.error(err.userMessage);
|
|
68024
68027
|
return;
|
|
@@ -68847,7 +68850,7 @@ Run 'dosu --help' to see available commands.`;
|
|
|
68847
68850
|
}
|
|
68848
68851
|
await Promise.resolve();
|
|
68849
68852
|
const useDeviceFlow = !opts.browser || isHeadless();
|
|
68850
|
-
await Promise.resolve().then(() =>
|
|
68853
|
+
await Promise.resolve().then(() => init_errors());
|
|
68851
68854
|
let token;
|
|
68852
68855
|
if (useDeviceFlow) {
|
|
68853
68856
|
await Promise.resolve().then(() => init_device());
|
|
@@ -69223,7 +69226,7 @@ var init_cli = __esm(() => {
|
|
|
69223
69226
|
init_pending_tasks_check();
|
|
69224
69227
|
init_skill_update_check();
|
|
69225
69228
|
init_update_check();
|
|
69226
|
-
|
|
69229
|
+
init_errors2();
|
|
69227
69230
|
init_fatal_error();
|
|
69228
69231
|
});
|
|
69229
69232
|
|
|
@@ -69303,4 +69306,4 @@ main().catch((err) => {
|
|
|
69303
69306
|
process.exit(1);
|
|
69304
69307
|
});
|
|
69305
69308
|
|
|
69306
|
-
//# debugId=
|
|
69309
|
+
//# debugId=af4149bf-b423-bc43-6475-6e2164756e21
|