ctx7 0.5.1 → 0.5.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/dist/index.js +177 -43
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -925,48 +925,153 @@ function trackEvent(event, data) {
|
|
|
925
925
|
// src/commands/generate.ts
|
|
926
926
|
import pc6 from "picocolors";
|
|
927
927
|
import ora2 from "ora";
|
|
928
|
-
import { mkdir as
|
|
928
|
+
import { mkdir as mkdir3, writeFile as writeFile2, readFile, unlink } from "fs/promises";
|
|
929
929
|
import { join as join4 } from "path";
|
|
930
930
|
import { homedir as homedir3 } from "os";
|
|
931
931
|
import { spawn } from "child_process";
|
|
932
932
|
import { input, select as select2 } from "@inquirer/prompts";
|
|
933
933
|
|
|
934
934
|
// src/utils/auth.ts
|
|
935
|
+
import * as fs2 from "fs";
|
|
936
|
+
import * as os2 from "os";
|
|
937
|
+
|
|
938
|
+
// src/utils/storage-paths.ts
|
|
935
939
|
import * as fs from "fs";
|
|
936
|
-
import
|
|
940
|
+
import { access as access2, chmod, mkdir as mkdir2, rename } from "fs/promises";
|
|
937
941
|
import * as os from "os";
|
|
938
|
-
|
|
939
|
-
var
|
|
942
|
+
import * as path from "path";
|
|
943
|
+
var APP_DIR = "context7";
|
|
944
|
+
var LEGACY_DIR = ".context7";
|
|
945
|
+
var CREDENTIALS_FILE_NAME = "credentials.json";
|
|
946
|
+
var UPDATE_STATE_FILE_NAME = "cli-state.json";
|
|
947
|
+
var PREVIEWS_DIR_NAME = "previews";
|
|
948
|
+
function xdgBase(envVar, ...defaultSegments) {
|
|
949
|
+
const value = process.env[envVar];
|
|
950
|
+
const base = value && path.isAbsolute(value) ? value : path.join(os.homedir(), ...defaultSegments);
|
|
951
|
+
return path.join(base, APP_DIR);
|
|
952
|
+
}
|
|
953
|
+
function getConfigDir() {
|
|
954
|
+
return xdgBase("XDG_CONFIG_HOME", ".config");
|
|
955
|
+
}
|
|
956
|
+
function getStateDir() {
|
|
957
|
+
return xdgBase("XDG_STATE_HOME", ".local", "state");
|
|
958
|
+
}
|
|
959
|
+
function getCacheDir() {
|
|
960
|
+
return xdgBase("XDG_CACHE_HOME", ".cache");
|
|
961
|
+
}
|
|
962
|
+
function getCredentialsFilePath() {
|
|
963
|
+
return path.join(getConfigDir(), CREDENTIALS_FILE_NAME);
|
|
964
|
+
}
|
|
965
|
+
function getUpdateStateFilePath() {
|
|
966
|
+
return path.join(getStateDir(), UPDATE_STATE_FILE_NAME);
|
|
967
|
+
}
|
|
968
|
+
function getPreviewsDir() {
|
|
969
|
+
return path.join(getCacheDir(), PREVIEWS_DIR_NAME);
|
|
970
|
+
}
|
|
971
|
+
function getLegacyFilePath(fileName) {
|
|
972
|
+
return path.join(os.homedir(), LEGACY_DIR, fileName);
|
|
973
|
+
}
|
|
974
|
+
function migrateLegacyFileSync(fileName, targetPath, mode) {
|
|
975
|
+
const legacyPath = getLegacyFilePath(fileName);
|
|
976
|
+
if (legacyPath === targetPath || fs.existsSync(targetPath) || !fs.existsSync(legacyPath)) {
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
try {
|
|
980
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true, mode: 448 });
|
|
981
|
+
fs.renameSync(legacyPath, targetPath);
|
|
982
|
+
if (mode !== void 0) {
|
|
983
|
+
fs.chmodSync(targetPath, mode);
|
|
984
|
+
}
|
|
985
|
+
} catch {
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
async function migrateLegacyFile(fileName, targetPath, mode) {
|
|
989
|
+
const legacyPath = getLegacyFilePath(fileName);
|
|
990
|
+
if (legacyPath === targetPath || await exists(targetPath) || !await exists(legacyPath)) {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
try {
|
|
994
|
+
await mkdir2(path.dirname(targetPath), { recursive: true, mode: 448 });
|
|
995
|
+
await rename(legacyPath, targetPath);
|
|
996
|
+
if (mode !== void 0) {
|
|
997
|
+
await chmod(targetPath, mode);
|
|
998
|
+
}
|
|
999
|
+
} catch {
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function resolveReadPathSync(fileName, targetPath, mode) {
|
|
1003
|
+
migrateLegacyFileSync(fileName, targetPath, mode);
|
|
1004
|
+
if (fs.existsSync(targetPath)) {
|
|
1005
|
+
return targetPath;
|
|
1006
|
+
}
|
|
1007
|
+
const legacyPath = getLegacyFilePath(fileName);
|
|
1008
|
+
return fs.existsSync(legacyPath) ? legacyPath : targetPath;
|
|
1009
|
+
}
|
|
1010
|
+
async function resolveReadPath(fileName, targetPath, mode) {
|
|
1011
|
+
await migrateLegacyFile(fileName, targetPath, mode);
|
|
1012
|
+
if (await exists(targetPath)) {
|
|
1013
|
+
return targetPath;
|
|
1014
|
+
}
|
|
1015
|
+
const legacyPath = getLegacyFilePath(fileName);
|
|
1016
|
+
return await exists(legacyPath) ? legacyPath : targetPath;
|
|
1017
|
+
}
|
|
1018
|
+
async function exists(filePath) {
|
|
1019
|
+
try {
|
|
1020
|
+
await access2(filePath);
|
|
1021
|
+
return true;
|
|
1022
|
+
} catch {
|
|
1023
|
+
return false;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// src/utils/auth.ts
|
|
940
1028
|
function ensureConfigDir() {
|
|
941
|
-
|
|
942
|
-
|
|
1029
|
+
const configDir = getConfigDir();
|
|
1030
|
+
if (!fs2.existsSync(configDir)) {
|
|
1031
|
+
fs2.mkdirSync(configDir, { recursive: true, mode: 448 });
|
|
943
1032
|
}
|
|
944
1033
|
}
|
|
1034
|
+
var CREDENTIALS_MODE = 384;
|
|
945
1035
|
function saveTokens(tokens) {
|
|
1036
|
+
const credentialsFile = getCredentialsFilePath();
|
|
1037
|
+
migrateLegacyFileSync(CREDENTIALS_FILE_NAME, credentialsFile, CREDENTIALS_MODE);
|
|
946
1038
|
ensureConfigDir();
|
|
947
1039
|
const data = {
|
|
948
1040
|
...tokens,
|
|
949
1041
|
expires_at: tokens.expires_at ?? (tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : void 0)
|
|
950
1042
|
};
|
|
951
|
-
|
|
1043
|
+
fs2.writeFileSync(credentialsFile, JSON.stringify(data, null, 2), { mode: CREDENTIALS_MODE });
|
|
1044
|
+
fs2.chmodSync(credentialsFile, CREDENTIALS_MODE);
|
|
952
1045
|
}
|
|
953
1046
|
function loadTokens() {
|
|
954
|
-
|
|
1047
|
+
const credentialsFile = resolveReadPathSync(
|
|
1048
|
+
CREDENTIALS_FILE_NAME,
|
|
1049
|
+
getCredentialsFilePath(),
|
|
1050
|
+
CREDENTIALS_MODE
|
|
1051
|
+
);
|
|
1052
|
+
if (!fs2.existsSync(credentialsFile)) {
|
|
955
1053
|
return null;
|
|
956
1054
|
}
|
|
957
1055
|
try {
|
|
958
|
-
const data = JSON.parse(
|
|
1056
|
+
const data = JSON.parse(fs2.readFileSync(credentialsFile, "utf-8"));
|
|
959
1057
|
return data;
|
|
960
1058
|
} catch {
|
|
961
1059
|
return null;
|
|
962
1060
|
}
|
|
963
1061
|
}
|
|
964
1062
|
function clearTokens() {
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1063
|
+
const credentialsFile = getCredentialsFilePath();
|
|
1064
|
+
let removed = false;
|
|
1065
|
+
if (fs2.existsSync(credentialsFile)) {
|
|
1066
|
+
fs2.unlinkSync(credentialsFile);
|
|
1067
|
+
removed = true;
|
|
968
1068
|
}
|
|
969
|
-
|
|
1069
|
+
const legacyCredentialsFile = getLegacyFilePath(CREDENTIALS_FILE_NAME);
|
|
1070
|
+
if (fs2.existsSync(legacyCredentialsFile)) {
|
|
1071
|
+
fs2.unlinkSync(legacyCredentialsFile);
|
|
1072
|
+
removed = true;
|
|
1073
|
+
}
|
|
1074
|
+
return removed;
|
|
970
1075
|
}
|
|
971
1076
|
function isTokenExpired(tokens) {
|
|
972
1077
|
if (!tokens.expires_at) {
|
|
@@ -1012,7 +1117,7 @@ var DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 5;
|
|
|
1012
1117
|
async function startDeviceAuthorization(baseUrl3, clientId) {
|
|
1013
1118
|
const params = new URLSearchParams({ client_id: clientId });
|
|
1014
1119
|
try {
|
|
1015
|
-
const hostname2 =
|
|
1120
|
+
const hostname2 = os2.hostname();
|
|
1016
1121
|
if (hostname2) params.set("hostname", hostname2);
|
|
1017
1122
|
} catch {
|
|
1018
1123
|
}
|
|
@@ -1686,8 +1791,8 @@ async function generateCommand(options) {
|
|
|
1686
1791
|
log.blank();
|
|
1687
1792
|
};
|
|
1688
1793
|
const openInEditor = async () => {
|
|
1689
|
-
const previewDir =
|
|
1690
|
-
await
|
|
1794
|
+
const previewDir = getPreviewsDir();
|
|
1795
|
+
await mkdir3(previewDir, { recursive: true });
|
|
1691
1796
|
previewFile = join4(previewDir, `${skillName}.md`);
|
|
1692
1797
|
if (!previewFileWritten) {
|
|
1693
1798
|
await writeFile2(previewFile, generatedContent, "utf-8");
|
|
@@ -1767,7 +1872,7 @@ async function generateCommand(options) {
|
|
|
1767
1872
|
const skillDir = join4(finalDir, skillName);
|
|
1768
1873
|
const skillPath = join4(skillDir, "SKILL.md");
|
|
1769
1874
|
try {
|
|
1770
|
-
await
|
|
1875
|
+
await mkdir3(skillDir, { recursive: true });
|
|
1771
1876
|
await writeFile2(skillPath, generatedContent, "utf-8");
|
|
1772
1877
|
} catch (err) {
|
|
1773
1878
|
const error = err;
|
|
@@ -2619,12 +2724,12 @@ ${headerLine}`,
|
|
|
2619
2724
|
import pc8 from "picocolors";
|
|
2620
2725
|
import ora4 from "ora";
|
|
2621
2726
|
import { select as select3 } from "@inquirer/prompts";
|
|
2622
|
-
import { mkdir as
|
|
2623
|
-
import { dirname as
|
|
2727
|
+
import { mkdir as mkdir5, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
2728
|
+
import { dirname as dirname7, join as join8 } from "path";
|
|
2624
2729
|
import { randomBytes } from "crypto";
|
|
2625
2730
|
|
|
2626
2731
|
// src/setup/agents.ts
|
|
2627
|
-
import { access as
|
|
2732
|
+
import { access as access3 } from "fs/promises";
|
|
2628
2733
|
import { join as join7 } from "path";
|
|
2629
2734
|
import { homedir as homedir5 } from "os";
|
|
2630
2735
|
var SETUP_AGENT_NAMES = {
|
|
@@ -2828,7 +2933,7 @@ function getAgent(name) {
|
|
|
2828
2933
|
var ALL_AGENT_NAMES = Object.keys(agents);
|
|
2829
2934
|
async function pathExists(p) {
|
|
2830
2935
|
try {
|
|
2831
|
-
await
|
|
2936
|
+
await access3(p);
|
|
2832
2937
|
return true;
|
|
2833
2938
|
} catch {
|
|
2834
2939
|
return false;
|
|
@@ -2937,8 +3042,8 @@ function customizeSkillFilesForAgent(agent, skillName, files) {
|
|
|
2937
3042
|
}
|
|
2938
3043
|
|
|
2939
3044
|
// src/setup/mcp-writer.ts
|
|
2940
|
-
import { access as
|
|
2941
|
-
import { dirname as
|
|
3045
|
+
import { access as access4, readFile as readFile3, writeFile as writeFile3, mkdir as mkdir4 } from "fs/promises";
|
|
3046
|
+
import { dirname as dirname6 } from "path";
|
|
2942
3047
|
function stripJsonComments(text) {
|
|
2943
3048
|
let result = "";
|
|
2944
3049
|
let i = 0;
|
|
@@ -3009,7 +3114,7 @@ function removeServerEntry(existing, configKey, serverName) {
|
|
|
3009
3114
|
async function resolveMcpPath(candidates) {
|
|
3010
3115
|
for (const candidate of candidates) {
|
|
3011
3116
|
try {
|
|
3012
|
-
await
|
|
3117
|
+
await access4(candidate);
|
|
3013
3118
|
return candidate;
|
|
3014
3119
|
} catch {
|
|
3015
3120
|
}
|
|
@@ -3017,7 +3122,7 @@ async function resolveMcpPath(candidates) {
|
|
|
3017
3122
|
return candidates[0];
|
|
3018
3123
|
}
|
|
3019
3124
|
async function writeJsonConfig(filePath, config) {
|
|
3020
|
-
await
|
|
3125
|
+
await mkdir4(dirname6(filePath), { recursive: true });
|
|
3021
3126
|
await writeFile3(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
3022
3127
|
}
|
|
3023
3128
|
async function readTomlServerExists(filePath, serverName) {
|
|
@@ -3137,11 +3242,11 @@ async function appendTomlServer(filePath, serverName, entry) {
|
|
|
3137
3242
|
const before = rawBefore.length > 0 ? rawBefore + "\n\n" : "";
|
|
3138
3243
|
const after = rawAfter.length > 0 ? "\n" + rawAfter : "";
|
|
3139
3244
|
const content = before + block + after;
|
|
3140
|
-
await
|
|
3245
|
+
await mkdir4(dirname6(filePath), { recursive: true });
|
|
3141
3246
|
await writeFile3(filePath, content, "utf-8");
|
|
3142
3247
|
} else {
|
|
3143
3248
|
const separator = existing.length > 0 && !existing.endsWith("\n") ? "\n\n" : existing.length > 0 ? "\n" : "";
|
|
3144
|
-
await
|
|
3249
|
+
await mkdir4(dirname6(filePath), { recursive: true });
|
|
3145
3250
|
await writeFile3(filePath, existing + separator + block, "utf-8");
|
|
3146
3251
|
}
|
|
3147
3252
|
return { alreadyExists };
|
|
@@ -3174,7 +3279,7 @@ async function removeTomlServer(filePath, serverName) {
|
|
|
3174
3279
|
const rawBefore = existing.slice(0, startIdx).replace(/\n+$/, "");
|
|
3175
3280
|
const rawAfter = existing.slice(startIdx + sectionHeader.length + endOffset).replace(/^\n+/, "");
|
|
3176
3281
|
const content = [rawBefore, rawAfter].filter(Boolean).join("\n\n");
|
|
3177
|
-
await
|
|
3282
|
+
await mkdir4(dirname6(filePath), { recursive: true });
|
|
3178
3283
|
await writeFile3(filePath, content.length > 0 ? `${content}
|
|
3179
3284
|
` : "", "utf-8");
|
|
3180
3285
|
return { removed: true };
|
|
@@ -3320,7 +3425,7 @@ async function installRule(agentName, mode, scope) {
|
|
|
3320
3425
|
if (rule.kind === "file") {
|
|
3321
3426
|
const ruleDir = scope === "global" ? rule.dir("global") : join8(process.cwd(), rule.dir("project"));
|
|
3322
3427
|
const rulePath = join8(ruleDir, rule.filename);
|
|
3323
|
-
await
|
|
3428
|
+
await mkdir5(dirname7(rulePath), { recursive: true });
|
|
3324
3429
|
await writeFile4(rulePath, content, "utf-8");
|
|
3325
3430
|
return { status: "installed", path: rulePath };
|
|
3326
3431
|
}
|
|
@@ -3340,7 +3445,7 @@ ${content}${rule.sectionMarker}`;
|
|
|
3340
3445
|
return { status: "updated", path: filePath };
|
|
3341
3446
|
}
|
|
3342
3447
|
const separator = existing.length > 0 && !existing.endsWith("\n") ? "\n\n" : existing.length > 0 ? "\n" : "";
|
|
3343
|
-
await
|
|
3448
|
+
await mkdir5(dirname7(filePath), { recursive: true });
|
|
3344
3449
|
await writeFile4(filePath, existing + separator + section + "\n", "utf-8");
|
|
3345
3450
|
return { status: "installed", path: filePath };
|
|
3346
3451
|
}
|
|
@@ -3444,7 +3549,7 @@ async function setupMcp(agents2, options, scope) {
|
|
|
3444
3549
|
log.plain(` ${pc8.dim(r.skillPath)}`);
|
|
3445
3550
|
if (r.skillStatus.includes("EACCES")) {
|
|
3446
3551
|
log.plain(
|
|
3447
|
-
` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${
|
|
3552
|
+
` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${dirname7(dirname7(r.skillPath))}`)}`
|
|
3448
3553
|
);
|
|
3449
3554
|
}
|
|
3450
3555
|
}
|
|
@@ -3505,7 +3610,7 @@ async function setupCli(options) {
|
|
|
3505
3610
|
log.plain(` ${pc8.dim(r.skillPath)}`);
|
|
3506
3611
|
if (r.skillStatus.includes("EACCES")) {
|
|
3507
3612
|
log.plain(
|
|
3508
|
-
` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${
|
|
3613
|
+
` ${pc8.yellow("tip:")} fix permissions with: ${pc8.cyan(`sudo chown -R $(whoami) ${dirname7(dirname7(r.skillPath))}`)}`
|
|
3509
3614
|
);
|
|
3510
3615
|
}
|
|
3511
3616
|
const ruleIcon = r.ruleStatus === "installed" || r.ruleStatus === "updated" ? pc8.green("+") : pc8.dim("~");
|
|
@@ -3538,7 +3643,7 @@ async function setupCommand(options) {
|
|
|
3538
3643
|
import pc9 from "picocolors";
|
|
3539
3644
|
import ora5 from "ora";
|
|
3540
3645
|
import { join as join9 } from "path";
|
|
3541
|
-
import { access as
|
|
3646
|
+
import { access as access5, readFile as readFile5, rm as rm3, writeFile as writeFile5 } from "fs/promises";
|
|
3542
3647
|
var CHECKBOX_THEME2 = {
|
|
3543
3648
|
style: {
|
|
3544
3649
|
highlight: (text) => pc9.green(text),
|
|
@@ -3638,7 +3743,7 @@ function resolveFlagModes(options) {
|
|
|
3638
3743
|
}
|
|
3639
3744
|
async function pathExists2(path2) {
|
|
3640
3745
|
try {
|
|
3641
|
-
await
|
|
3746
|
+
await access5(path2);
|
|
3642
3747
|
return true;
|
|
3643
3748
|
} catch {
|
|
3644
3749
|
return false;
|
|
@@ -3885,6 +3990,18 @@ async function removeCommand2(options) {
|
|
|
3885
3990
|
// src/commands/docs.ts
|
|
3886
3991
|
import pc10 from "picocolors";
|
|
3887
3992
|
import ora6 from "ora";
|
|
3993
|
+
|
|
3994
|
+
// src/utils/library-id.ts
|
|
3995
|
+
function recoverLibraryId(input2) {
|
|
3996
|
+
if (input2.startsWith("//")) return input2.replace(/^\/+/, "/");
|
|
3997
|
+
if (input2.startsWith("/")) return input2;
|
|
3998
|
+
if (!/^[A-Za-z]:[\\/]/.test(input2)) return input2;
|
|
3999
|
+
const normalized = input2.replace(/\\/g, "/");
|
|
4000
|
+
const match = normalized.match(/^[A-Za-z]:\/.*?\/(?:Git|PortableGit|git-bash)\/(.+)$/i);
|
|
4001
|
+
return match ? `/${match[1]}` : input2;
|
|
4002
|
+
}
|
|
4003
|
+
|
|
4004
|
+
// src/commands/docs.ts
|
|
3888
4005
|
var isTTY = process.stdout.isTTY;
|
|
3889
4006
|
function getReputationLabel(score) {
|
|
3890
4007
|
if (score === void 0 || score < 0) return "Unknown";
|
|
@@ -3970,10 +4087,16 @@ async function resolveCommand(library, query, options) {
|
|
|
3970
4087
|
}
|
|
3971
4088
|
async function queryCommand(libraryId, query, options) {
|
|
3972
4089
|
trackEvent("command", { name: "docs" });
|
|
4090
|
+
libraryId = recoverLibraryId(libraryId);
|
|
3973
4091
|
if (!libraryId.startsWith("/") || !/^\/[^/]+\/[^/]/.test(libraryId)) {
|
|
3974
4092
|
log.error(`Invalid library ID: "${libraryId}"`);
|
|
3975
4093
|
log.info(`Expected format: /owner/repo or /owner/repo/version (e.g., /facebook/react)`);
|
|
3976
4094
|
log.info(`Run "ctx7 library <name>" to find the correct ID`);
|
|
4095
|
+
if (process.platform === "win32") {
|
|
4096
|
+
log.info(
|
|
4097
|
+
`On Git Bash, prefix the ID with an extra slash to avoid path conversion: ctx7 docs "//facebook/react" "<your question>"`
|
|
4098
|
+
);
|
|
4099
|
+
}
|
|
3977
4100
|
process.exitCode = 1;
|
|
3978
4101
|
return;
|
|
3979
4102
|
}
|
|
@@ -4057,25 +4180,36 @@ import { spawn as spawn2 } from "child_process";
|
|
|
4057
4180
|
import pc11 from "picocolors";
|
|
4058
4181
|
|
|
4059
4182
|
// src/utils/update-check.ts
|
|
4060
|
-
import {
|
|
4061
|
-
import {
|
|
4062
|
-
import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
|
|
4183
|
+
import { dirname as dirname8 } from "path";
|
|
4184
|
+
import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
|
|
4063
4185
|
var DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
4064
|
-
var UPDATE_STATE_FILE = join10(homedir6(), ".context7", "cli-state.json");
|
|
4065
4186
|
function getStateFilePath(stateFile) {
|
|
4066
|
-
return stateFile ??
|
|
4187
|
+
return stateFile ?? getUpdateStateFilePath();
|
|
4188
|
+
}
|
|
4189
|
+
async function readStateFilePath(stateFile) {
|
|
4190
|
+
if (stateFile) {
|
|
4191
|
+
return stateFile;
|
|
4192
|
+
}
|
|
4193
|
+
return resolveReadPath(UPDATE_STATE_FILE_NAME, getUpdateStateFilePath());
|
|
4194
|
+
}
|
|
4195
|
+
async function writeStateFilePath(stateFile) {
|
|
4196
|
+
const path2 = getStateFilePath(stateFile);
|
|
4197
|
+
if (!stateFile) {
|
|
4198
|
+
await migrateLegacyFile(UPDATE_STATE_FILE_NAME, path2);
|
|
4199
|
+
}
|
|
4200
|
+
return path2;
|
|
4067
4201
|
}
|
|
4068
4202
|
async function readUpdateState(stateFile) {
|
|
4069
4203
|
try {
|
|
4070
|
-
const raw = await readFile6(
|
|
4204
|
+
const raw = await readFile6(await readStateFilePath(stateFile), "utf-8");
|
|
4071
4205
|
return JSON.parse(raw);
|
|
4072
4206
|
} catch {
|
|
4073
4207
|
return {};
|
|
4074
4208
|
}
|
|
4075
4209
|
}
|
|
4076
4210
|
async function writeUpdateState(state, stateFile) {
|
|
4077
|
-
const path2 =
|
|
4078
|
-
await
|
|
4211
|
+
const path2 = await writeStateFilePath(stateFile);
|
|
4212
|
+
await mkdir6(dirname8(path2), { recursive: true });
|
|
4079
4213
|
await writeFile6(path2, JSON.stringify(state, null, 2) + "\n", "utf-8");
|
|
4080
4214
|
}
|
|
4081
4215
|
function compareVersions(a, b) {
|
|
@@ -4379,7 +4513,7 @@ var brand = {
|
|
|
4379
4513
|
dim: pc12.dim
|
|
4380
4514
|
};
|
|
4381
4515
|
var program = new Command();
|
|
4382
|
-
program.name("ctx7").description("Context7 CLI - Fetch documentation context and configure Context7").version(VERSION).option("--base-url <url>").hook("preAction", (thisCommand) => {
|
|
4516
|
+
program.name("ctx7").description("Context7 CLI - Fetch documentation context and configure Context7").version(VERSION, "-v, --version").option("--base-url <url>").hook("preAction", (thisCommand) => {
|
|
4383
4517
|
const opts = thisCommand.opts();
|
|
4384
4518
|
if (opts.baseUrl) {
|
|
4385
4519
|
setBaseUrl(opts.baseUrl);
|