ctx7 0.3.4 → 0.3.6
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/dist/index.js +63 -33
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -123,6 +123,7 @@ var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
123
123
|
var pkg = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
|
|
124
124
|
var VERSION = pkg.version;
|
|
125
125
|
var NAME = pkg.name;
|
|
126
|
+
var CLI_CLIENT_ID = "2veBSofhicRBguUT";
|
|
126
127
|
|
|
127
128
|
// src/utils/api.ts
|
|
128
129
|
var baseUrl = "https://context7.com";
|
|
@@ -810,6 +811,39 @@ function isTokenExpired(tokens) {
|
|
|
810
811
|
}
|
|
811
812
|
return Date.now() > tokens.expires_at - 6e4;
|
|
812
813
|
}
|
|
814
|
+
async function refreshAccessToken(refreshToken) {
|
|
815
|
+
const response = await fetch(`${getBaseUrl()}/api/oauth/token`, {
|
|
816
|
+
method: "POST",
|
|
817
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
818
|
+
body: new URLSearchParams({
|
|
819
|
+
grant_type: "refresh_token",
|
|
820
|
+
client_id: CLI_CLIENT_ID,
|
|
821
|
+
refresh_token: refreshToken
|
|
822
|
+
}).toString()
|
|
823
|
+
});
|
|
824
|
+
if (!response.ok) {
|
|
825
|
+
const err = await response.json().catch(() => ({}));
|
|
826
|
+
throw new Error(err.error_description || err.error || "Failed to refresh token");
|
|
827
|
+
}
|
|
828
|
+
return await response.json();
|
|
829
|
+
}
|
|
830
|
+
async function getValidAccessToken() {
|
|
831
|
+
const tokens = loadTokens();
|
|
832
|
+
if (!tokens) return null;
|
|
833
|
+
if (!isTokenExpired(tokens)) {
|
|
834
|
+
return tokens.access_token;
|
|
835
|
+
}
|
|
836
|
+
if (!tokens.refresh_token) {
|
|
837
|
+
return null;
|
|
838
|
+
}
|
|
839
|
+
try {
|
|
840
|
+
const newTokens = await refreshAccessToken(tokens.refresh_token);
|
|
841
|
+
saveTokens(newTokens);
|
|
842
|
+
return newTokens.access_token;
|
|
843
|
+
} catch {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
813
847
|
var CALLBACK_PORT = 52417;
|
|
814
848
|
function createCallbackServer(expectedState) {
|
|
815
849
|
let resolvePort;
|
|
@@ -953,7 +987,6 @@ function buildAuthorizationUrl(baseUrl3, clientId, redirectUri, codeChallenge, s
|
|
|
953
987
|
import pc4 from "picocolors";
|
|
954
988
|
import ora from "ora";
|
|
955
989
|
import open from "open";
|
|
956
|
-
var CLI_CLIENT_ID = "2veBSofhicRBguUT";
|
|
957
990
|
var baseUrl2 = "https://context7.com";
|
|
958
991
|
function setAuthBaseUrl(url) {
|
|
959
992
|
baseUrl2 = url;
|
|
@@ -1029,18 +1062,13 @@ async function performLogin(openBrowser = true) {
|
|
|
1029
1062
|
}
|
|
1030
1063
|
async function loginCommand(options) {
|
|
1031
1064
|
trackEvent("command", { name: "login" });
|
|
1032
|
-
const
|
|
1033
|
-
if (
|
|
1034
|
-
|
|
1035
|
-
if
|
|
1036
|
-
|
|
1037
|
-
console.log(
|
|
1038
|
-
pc4.dim("Run 'ctx7 logout' first if you want to log in with a different account.")
|
|
1039
|
-
);
|
|
1040
|
-
return;
|
|
1041
|
-
}
|
|
1042
|
-
clearTokens();
|
|
1065
|
+
const existingToken = await getValidAccessToken();
|
|
1066
|
+
if (existingToken) {
|
|
1067
|
+
console.log(pc4.yellow("You are already logged in."));
|
|
1068
|
+
console.log(pc4.dim("Run 'ctx7 logout' first if you want to log in with a different account."));
|
|
1069
|
+
return;
|
|
1043
1070
|
}
|
|
1071
|
+
clearTokens();
|
|
1044
1072
|
const token = await performLogin(options.browser);
|
|
1045
1073
|
if (!token) {
|
|
1046
1074
|
process.exit(1);
|
|
@@ -1058,29 +1086,30 @@ function logoutCommand() {
|
|
|
1058
1086
|
}
|
|
1059
1087
|
async function whoamiCommand() {
|
|
1060
1088
|
trackEvent("command", { name: "whoami" });
|
|
1061
|
-
const
|
|
1062
|
-
if (!
|
|
1089
|
+
const accessToken = await getValidAccessToken();
|
|
1090
|
+
if (!accessToken) {
|
|
1063
1091
|
console.log(pc4.yellow("Not logged in."));
|
|
1064
1092
|
console.log(pc4.dim("Run 'ctx7 login' to authenticate."));
|
|
1065
1093
|
return;
|
|
1066
1094
|
}
|
|
1067
1095
|
console.log(pc4.green("Logged in"));
|
|
1068
1096
|
try {
|
|
1069
|
-
const
|
|
1070
|
-
if (
|
|
1071
|
-
console.log(`${pc4.dim("Name:".padEnd(
|
|
1097
|
+
const whoami = await fetchWhoami(accessToken);
|
|
1098
|
+
if (whoami.name) {
|
|
1099
|
+
console.log(`${pc4.dim("Name:".padEnd(13))}${whoami.name}`);
|
|
1072
1100
|
}
|
|
1073
|
-
if (
|
|
1074
|
-
console.log(`${pc4.dim("Email:".padEnd(
|
|
1101
|
+
if (whoami.email) {
|
|
1102
|
+
console.log(`${pc4.dim("Email:".padEnd(13))}${whoami.email}`);
|
|
1075
1103
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
console.log(pc4.dim("(Session may be expired - run 'ctx7 login' to refresh)"));
|
|
1104
|
+
if (whoami.teamspace) {
|
|
1105
|
+
console.log(`${pc4.dim("Teamspace:".padEnd(13))}${whoami.teamspace.name}`);
|
|
1079
1106
|
}
|
|
1107
|
+
} catch {
|
|
1108
|
+
console.log(pc4.dim("(Session may be expired - run 'ctx7 login' to refresh)"));
|
|
1080
1109
|
}
|
|
1081
1110
|
}
|
|
1082
|
-
async function
|
|
1083
|
-
const response = await fetch(
|
|
1111
|
+
async function fetchWhoami(accessToken) {
|
|
1112
|
+
const response = await fetch(`${getBaseUrl()}/api/dashboard/whoami`, {
|
|
1084
1113
|
headers: {
|
|
1085
1114
|
Authorization: `Bearer ${accessToken}`
|
|
1086
1115
|
}
|
|
@@ -2584,8 +2613,7 @@ function registerSetupCommand(program2) {
|
|
|
2584
2613
|
});
|
|
2585
2614
|
}
|
|
2586
2615
|
async function authenticateAndGenerateKey() {
|
|
2587
|
-
const
|
|
2588
|
-
const accessToken = existingTokens && !isTokenExpired(existingTokens) ? existingTokens.access_token : await performLogin();
|
|
2616
|
+
const accessToken = await getValidAccessToken() ?? await performLogin();
|
|
2589
2617
|
if (!accessToken) return null;
|
|
2590
2618
|
const spinner = ora4("Configuring authentication...").start();
|
|
2591
2619
|
try {
|
|
@@ -2625,15 +2653,15 @@ async function resolveMode(options) {
|
|
|
2625
2653
|
return select3({
|
|
2626
2654
|
message: "How should your agent access Context7?",
|
|
2627
2655
|
choices: [
|
|
2628
|
-
{
|
|
2629
|
-
name: `CLI + Skills
|
|
2630
|
-
${pc8.dim("Installs a find-docs skill that guides your agent to fetch up-to-date library docs using ")}${pc8.dim(pc8.bold("ctx7"))}${pc8.dim(" CLI commands")}`,
|
|
2631
|
-
value: "cli"
|
|
2632
|
-
},
|
|
2633
2656
|
{
|
|
2634
2657
|
name: `MCP server
|
|
2635
2658
|
${pc8.dim("Agent calls Context7 tools via MCP protocol to retrieve up-to-date library docs")}`,
|
|
2636
2659
|
value: "mcp"
|
|
2660
|
+
},
|
|
2661
|
+
{
|
|
2662
|
+
name: `CLI + Skills
|
|
2663
|
+
${pc8.dim("Installs a find-docs skill that guides your agent to fetch up-to-date library docs using ")}${pc8.dim(pc8.bold("ctx7"))}${pc8.dim(" CLI commands")}`,
|
|
2664
|
+
value: "cli"
|
|
2637
2665
|
}
|
|
2638
2666
|
],
|
|
2639
2667
|
theme: {
|
|
@@ -2651,8 +2679,8 @@ async function resolveCliAuth(apiKey) {
|
|
|
2651
2679
|
log.plain(`${pc8.green("\u2714")} Authenticated`);
|
|
2652
2680
|
return;
|
|
2653
2681
|
}
|
|
2654
|
-
const
|
|
2655
|
-
if (
|
|
2682
|
+
const validToken = await getValidAccessToken();
|
|
2683
|
+
if (validToken) {
|
|
2656
2684
|
log.blank();
|
|
2657
2685
|
log.plain(`${pc8.green("\u2714")} Authenticated`);
|
|
2658
2686
|
return;
|
|
@@ -2798,6 +2826,7 @@ async function setupMcp(agents2, options, scope) {
|
|
|
2798
2826
|
}
|
|
2799
2827
|
log.blank();
|
|
2800
2828
|
trackEvent("setup", { agents: agents2, scope, authMode: auth.mode });
|
|
2829
|
+
trackEvent("install", { skills: ["/upstash/context7/context7-mcp"], ides: agents2 });
|
|
2801
2830
|
}
|
|
2802
2831
|
async function setupCli(options) {
|
|
2803
2832
|
await resolveCliAuth(options.apiKey);
|
|
@@ -2835,6 +2864,7 @@ async function setupCli(options) {
|
|
|
2835
2864
|
log.plain(` Ask your agent: ${pc8.cyan(`"Use ctx7 CLI to look up React hooks"`)}`);
|
|
2836
2865
|
log.blank();
|
|
2837
2866
|
trackEvent("setup", { mode: "cli" });
|
|
2867
|
+
trackEvent("install", { skills: ["/upstash/context7/find-docs"], ides: targets.ides });
|
|
2838
2868
|
}
|
|
2839
2869
|
async function setupCommand(options) {
|
|
2840
2870
|
trackEvent("command", { name: "setup" });
|