ctx7 0.3.0 → 0.3.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 +39 -1
- package/dist/index.js +318 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ctx7
|
|
2
2
|
|
|
3
|
-
CLI for
|
|
3
|
+
CLI for [Context7](https://context7.com) - query up-to-date library documentation and manage AI coding skills.
|
|
4
4
|
|
|
5
5
|
Skills are reusable prompt instructions that enhance your AI coding assistant with specialized capabilities like working with specific frameworks, libraries, or coding patterns.
|
|
6
6
|
|
|
@@ -26,6 +26,18 @@ ctx7 setup --claude
|
|
|
26
26
|
ctx7 setup --opencode
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
### Library Documentation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Find a library
|
|
33
|
+
ctx7 library react
|
|
34
|
+
ctx7 library nextjs "app router"
|
|
35
|
+
|
|
36
|
+
# Get documentation
|
|
37
|
+
ctx7 docs /facebook/react "useEffect cleanup"
|
|
38
|
+
ctx7 docs /vercel/next.js "middleware"
|
|
39
|
+
```
|
|
40
|
+
|
|
29
41
|
### Skills
|
|
30
42
|
|
|
31
43
|
```bash
|
|
@@ -44,6 +56,32 @@ ctx7 skills list --claude
|
|
|
44
56
|
|
|
45
57
|
## Usage
|
|
46
58
|
|
|
59
|
+
### Find a library
|
|
60
|
+
|
|
61
|
+
Resolve a library name to a Context7 library ID.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
ctx7 library react
|
|
65
|
+
ctx7 library nextjs "app router setup"
|
|
66
|
+
ctx7 library prisma "database relations"
|
|
67
|
+
|
|
68
|
+
# Output as JSON
|
|
69
|
+
ctx7 library react --json
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Query documentation
|
|
73
|
+
|
|
74
|
+
Fetch documentation for a specific library using its Context7 ID.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ctx7 docs /facebook/react "useEffect cleanup"
|
|
78
|
+
ctx7 docs /vercel/next.js "middleware authentication"
|
|
79
|
+
ctx7 docs /prisma/prisma "one-to-many relations"
|
|
80
|
+
|
|
81
|
+
# Output as JSON
|
|
82
|
+
ctx7 docs /facebook/react "hooks" --json
|
|
83
|
+
```
|
|
84
|
+
|
|
47
85
|
### Setup
|
|
48
86
|
|
|
49
87
|
Configure Context7 MCP and a rule for your AI coding agents. Authenticates via OAuth, generates an API key, and writes the config.
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import
|
|
5
|
+
import pc10 from "picocolors";
|
|
6
6
|
import figlet from "figlet";
|
|
7
7
|
|
|
8
8
|
// src/commands/skill.ts
|
|
@@ -289,6 +289,65 @@ async function handleGenerateResponse(response, libraryName, onEvent) {
|
|
|
289
289
|
}
|
|
290
290
|
return { content, libraryName: finalLibraryName, error };
|
|
291
291
|
}
|
|
292
|
+
function getAuthHeaders(accessToken) {
|
|
293
|
+
const headers = {};
|
|
294
|
+
const apiKey = process.env.CONTEXT7_API_KEY;
|
|
295
|
+
if (apiKey) {
|
|
296
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
297
|
+
} else if (accessToken) {
|
|
298
|
+
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
299
|
+
}
|
|
300
|
+
return headers;
|
|
301
|
+
}
|
|
302
|
+
async function resolveLibrary(libraryName, query, accessToken) {
|
|
303
|
+
const params = new URLSearchParams({ libraryName });
|
|
304
|
+
if (query) {
|
|
305
|
+
params.set("query", query);
|
|
306
|
+
}
|
|
307
|
+
const response = await fetch(`${baseUrl}/api/v2/libs/search?${params}`, {
|
|
308
|
+
headers: getAuthHeaders(accessToken)
|
|
309
|
+
});
|
|
310
|
+
if (!response.ok) {
|
|
311
|
+
const errorData = await response.json().catch(() => ({}));
|
|
312
|
+
return {
|
|
313
|
+
results: [],
|
|
314
|
+
error: errorData.error || `HTTP error ${response.status}`,
|
|
315
|
+
message: errorData.message
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
return await response.json();
|
|
319
|
+
}
|
|
320
|
+
async function getLibraryContext(libraryId, query, options, accessToken) {
|
|
321
|
+
const params = new URLSearchParams({ libraryId, query });
|
|
322
|
+
if (options?.type) {
|
|
323
|
+
params.set("type", options.type);
|
|
324
|
+
}
|
|
325
|
+
const response = await fetch(`${baseUrl}/api/v2/context?${params}`, {
|
|
326
|
+
headers: getAuthHeaders(accessToken)
|
|
327
|
+
});
|
|
328
|
+
if (!response.ok) {
|
|
329
|
+
const errorData = await response.json().catch(() => ({}));
|
|
330
|
+
if (response.status === 301 && errorData.redirectUrl) {
|
|
331
|
+
return {
|
|
332
|
+
codeSnippets: [],
|
|
333
|
+
infoSnippets: [],
|
|
334
|
+
error: errorData.error || "library_redirected",
|
|
335
|
+
message: errorData.message,
|
|
336
|
+
redirectUrl: errorData.redirectUrl
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
codeSnippets: [],
|
|
341
|
+
infoSnippets: [],
|
|
342
|
+
error: errorData.error || `HTTP error ${response.status}`,
|
|
343
|
+
message: errorData.message
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
if (options?.type === "txt") {
|
|
347
|
+
return await response.text();
|
|
348
|
+
}
|
|
349
|
+
return await response.json();
|
|
350
|
+
}
|
|
292
351
|
|
|
293
352
|
// src/utils/logger.ts
|
|
294
353
|
import pc from "picocolors";
|
|
@@ -2300,6 +2359,10 @@ var agents = {
|
|
|
2300
2359
|
dir: (scope) => scope === "global" ? join7(homedir5(), ".claude", "rules") : join7(".claude", "rules"),
|
|
2301
2360
|
filename: "context7.md"
|
|
2302
2361
|
},
|
|
2362
|
+
skill: {
|
|
2363
|
+
name: "documentation-lookup",
|
|
2364
|
+
dir: (scope) => scope === "global" ? join7(homedir5(), ".claude", "skills") : join7(".claude", "skills")
|
|
2365
|
+
},
|
|
2303
2366
|
detect: {
|
|
2304
2367
|
projectPaths: [".mcp.json", ".claude"],
|
|
2305
2368
|
globalPaths: [join7(homedir5(), ".claude")]
|
|
@@ -2318,6 +2381,10 @@ var agents = {
|
|
|
2318
2381
|
dir: (scope) => scope === "global" ? join7(homedir5(), ".cursor", "rules") : join7(".cursor", "rules"),
|
|
2319
2382
|
filename: "context7.mdc"
|
|
2320
2383
|
},
|
|
2384
|
+
skill: {
|
|
2385
|
+
name: "documentation-lookup",
|
|
2386
|
+
dir: (scope) => scope === "global" ? join7(homedir5(), ".cursor", "skills") : join7(".cursor", "skills")
|
|
2387
|
+
},
|
|
2321
2388
|
detect: {
|
|
2322
2389
|
projectPaths: [".cursor"],
|
|
2323
2390
|
globalPaths: [join7(homedir5(), ".cursor")]
|
|
@@ -2337,6 +2404,10 @@ var agents = {
|
|
|
2337
2404
|
filename: "context7.md",
|
|
2338
2405
|
instructionsGlob: (scope) => scope === "global" ? join7(homedir5(), ".config", "opencode", "rules", "*.md") : ".opencode/rules/*.md"
|
|
2339
2406
|
},
|
|
2407
|
+
skill: {
|
|
2408
|
+
name: "documentation-lookup",
|
|
2409
|
+
dir: (scope) => scope === "global" ? join7(homedir5(), ".agents", "skills") : join7(".agents", "skills")
|
|
2410
|
+
},
|
|
2340
2411
|
detect: {
|
|
2341
2412
|
projectPaths: [".opencode.json"],
|
|
2342
2413
|
globalPaths: [join7(homedir5(), ".config", "opencode")]
|
|
@@ -2371,6 +2442,60 @@ async function detectAgents(scope) {
|
|
|
2371
2442
|
}
|
|
2372
2443
|
|
|
2373
2444
|
// src/setup/templates.ts
|
|
2445
|
+
var SKILL_CONTENT = `---
|
|
2446
|
+
name: documentation-lookup
|
|
2447
|
+
description: This skill should be used when the user asks about libraries, frameworks, API references, or needs code examples. Activates for setup questions, code generation involving libraries, or mentions of specific frameworks like React, Vue, Next.js, Prisma, Supabase, etc.
|
|
2448
|
+
---
|
|
2449
|
+
|
|
2450
|
+
When the user asks about libraries, frameworks, or needs code examples, use Context7 to fetch current documentation instead of relying on training data.
|
|
2451
|
+
|
|
2452
|
+
## When to Use This Skill
|
|
2453
|
+
|
|
2454
|
+
Activate this skill when the user:
|
|
2455
|
+
|
|
2456
|
+
- Asks setup or configuration questions ("How do I configure Next.js middleware?")
|
|
2457
|
+
- Requests code involving libraries ("Write a Prisma query for...")
|
|
2458
|
+
- Needs API references ("What are the Supabase auth methods?")
|
|
2459
|
+
- Mentions specific frameworks (React, Vue, Svelte, Express, Tailwind, etc.)
|
|
2460
|
+
|
|
2461
|
+
## How to Fetch Documentation
|
|
2462
|
+
|
|
2463
|
+
### Step 1: Resolve the Library ID
|
|
2464
|
+
|
|
2465
|
+
Call \`resolve-library-id\` with:
|
|
2466
|
+
|
|
2467
|
+
- \`libraryName\`: The library name extracted from the user's question
|
|
2468
|
+
- \`query\`: The user's full question (improves relevance ranking)
|
|
2469
|
+
|
|
2470
|
+
### Step 2: Select the Best Match
|
|
2471
|
+
|
|
2472
|
+
From the resolution results, choose based on:
|
|
2473
|
+
|
|
2474
|
+
- Exact or closest name match to what the user asked for
|
|
2475
|
+
- Higher benchmark scores indicate better documentation quality
|
|
2476
|
+
- If the user mentioned a version (e.g., "React 19"), prefer version-specific IDs
|
|
2477
|
+
|
|
2478
|
+
### Step 3: Fetch the Documentation
|
|
2479
|
+
|
|
2480
|
+
Call \`query-docs\` with:
|
|
2481
|
+
|
|
2482
|
+
- \`libraryId\`: The selected Context7 library ID (e.g., \`/vercel/next.js\`)
|
|
2483
|
+
- \`query\`: The user's specific question
|
|
2484
|
+
|
|
2485
|
+
### Step 4: Use the Documentation
|
|
2486
|
+
|
|
2487
|
+
Incorporate the fetched documentation into your response:
|
|
2488
|
+
|
|
2489
|
+
- Answer the user's question using current, accurate information
|
|
2490
|
+
- Include relevant code examples from the docs
|
|
2491
|
+
- Cite the library version when relevant
|
|
2492
|
+
|
|
2493
|
+
## Guidelines
|
|
2494
|
+
|
|
2495
|
+
- **Be specific**: Pass the user's full question as the query for better results
|
|
2496
|
+
- **Version awareness**: When users mention versions ("Next.js 15", "React 19"), use version-specific library IDs if available from the resolution step
|
|
2497
|
+
- **Prefer official sources**: When multiple matches exist, prefer official/primary packages over community forks
|
|
2498
|
+
`;
|
|
2374
2499
|
var RULE_CONTENT = `---
|
|
2375
2500
|
alwaysApply: true
|
|
2376
2501
|
---
|
|
@@ -2566,7 +2691,25 @@ async function setupAgent(agentName, auth, scope) {
|
|
|
2566
2691
|
} catch (err) {
|
|
2567
2692
|
ruleStatus = `failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
2568
2693
|
}
|
|
2569
|
-
|
|
2694
|
+
const skillDir = scope === "global" ? agent.skill.dir("global") : join8(process.cwd(), agent.skill.dir("project"));
|
|
2695
|
+
const skillPath = join8(skillDir, agent.skill.name, "SKILL.md");
|
|
2696
|
+
let skillStatus;
|
|
2697
|
+
try {
|
|
2698
|
+
await mkdir4(dirname3(skillPath), { recursive: true });
|
|
2699
|
+
await writeFile4(skillPath, SKILL_CONTENT, "utf-8");
|
|
2700
|
+
skillStatus = "installed";
|
|
2701
|
+
} catch (err) {
|
|
2702
|
+
skillStatus = `failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
2703
|
+
}
|
|
2704
|
+
return {
|
|
2705
|
+
agent: agent.displayName,
|
|
2706
|
+
mcpStatus,
|
|
2707
|
+
mcpPath,
|
|
2708
|
+
ruleStatus,
|
|
2709
|
+
rulePath,
|
|
2710
|
+
skillStatus,
|
|
2711
|
+
skillPath
|
|
2712
|
+
};
|
|
2570
2713
|
}
|
|
2571
2714
|
async function setupCommand(options) {
|
|
2572
2715
|
trackEvent("command", { name: "setup" });
|
|
@@ -2595,11 +2738,177 @@ async function setupCommand(options) {
|
|
|
2595
2738
|
const ruleIcon = r.ruleStatus === "installed" ? pc8.green("+") : pc8.dim("~");
|
|
2596
2739
|
log.plain(` ${ruleIcon} Rule ${r.ruleStatus}`);
|
|
2597
2740
|
log.plain(` ${pc8.dim(r.rulePath)}`);
|
|
2741
|
+
const skillIcon = r.skillStatus === "installed" ? pc8.green("+") : pc8.dim("~");
|
|
2742
|
+
log.plain(` ${skillIcon} Skill ${r.skillStatus}`);
|
|
2743
|
+
log.plain(` ${pc8.dim(r.skillPath)}`);
|
|
2598
2744
|
}
|
|
2599
2745
|
log.blank();
|
|
2600
2746
|
trackEvent("setup", { agents: agents2, scope, authMode: auth.mode });
|
|
2601
2747
|
}
|
|
2602
2748
|
|
|
2749
|
+
// src/commands/docs.ts
|
|
2750
|
+
import pc9 from "picocolors";
|
|
2751
|
+
import ora5 from "ora";
|
|
2752
|
+
var isTTY = process.stdout.isTTY;
|
|
2753
|
+
function getAccessToken() {
|
|
2754
|
+
const tokens = loadTokens();
|
|
2755
|
+
if (!tokens || isTokenExpired(tokens)) return void 0;
|
|
2756
|
+
return tokens.access_token;
|
|
2757
|
+
}
|
|
2758
|
+
function formatLibraryResult(lib, index) {
|
|
2759
|
+
const lines = [];
|
|
2760
|
+
lines.push(`${pc9.dim(`${index + 1}.`)} ${pc9.bold(lib.title)} ${pc9.cyan(lib.id)}`);
|
|
2761
|
+
if (lib.description) {
|
|
2762
|
+
lines.push(` ${pc9.dim(lib.description)}`);
|
|
2763
|
+
}
|
|
2764
|
+
const meta = [];
|
|
2765
|
+
if (lib.totalSnippets) {
|
|
2766
|
+
meta.push(`${lib.totalSnippets} snippets`);
|
|
2767
|
+
}
|
|
2768
|
+
if (lib.stars && lib.stars > 0) {
|
|
2769
|
+
meta.push(`${lib.stars.toLocaleString()} stars`);
|
|
2770
|
+
}
|
|
2771
|
+
if (lib.trustScore !== void 0) {
|
|
2772
|
+
meta.push(`trust: ${lib.trustScore}/10`);
|
|
2773
|
+
}
|
|
2774
|
+
if (lib.benchmarkScore !== void 0 && lib.benchmarkScore > 0) {
|
|
2775
|
+
meta.push(`benchmark: ${lib.benchmarkScore}`);
|
|
2776
|
+
}
|
|
2777
|
+
if (meta.length > 0) {
|
|
2778
|
+
lines.push(` ${pc9.dim(meta.join(" \xB7 "))}`);
|
|
2779
|
+
}
|
|
2780
|
+
if (lib.versions && lib.versions.length > 0) {
|
|
2781
|
+
lines.push(` ${pc9.dim(`versions: ${lib.versions.join(", ")}`)}`);
|
|
2782
|
+
}
|
|
2783
|
+
return lines.join("\n");
|
|
2784
|
+
}
|
|
2785
|
+
async function resolveCommand(library, query, options) {
|
|
2786
|
+
trackEvent("command", { name: "library" });
|
|
2787
|
+
const spinner = isTTY ? ora5(`Searching for "${library}"...`).start() : null;
|
|
2788
|
+
const accessToken = getAccessToken();
|
|
2789
|
+
let data;
|
|
2790
|
+
try {
|
|
2791
|
+
data = await resolveLibrary(library, query, accessToken);
|
|
2792
|
+
} catch (err) {
|
|
2793
|
+
spinner?.fail(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
2794
|
+
if (!spinner) log.error(err instanceof Error ? err.message : String(err));
|
|
2795
|
+
process.exitCode = 1;
|
|
2796
|
+
return;
|
|
2797
|
+
}
|
|
2798
|
+
if (data.error) {
|
|
2799
|
+
spinner?.fail(data.message || data.error);
|
|
2800
|
+
if (!spinner) log.error(data.message || data.error);
|
|
2801
|
+
process.exitCode = 1;
|
|
2802
|
+
return;
|
|
2803
|
+
}
|
|
2804
|
+
if (!data.results || data.results.length === 0) {
|
|
2805
|
+
spinner?.warn(`No libraries found matching "${library}"`);
|
|
2806
|
+
if (!spinner) log.warn(`No libraries found matching "${library}"`);
|
|
2807
|
+
return;
|
|
2808
|
+
}
|
|
2809
|
+
const results = data.results;
|
|
2810
|
+
spinner?.stop();
|
|
2811
|
+
if (options.json) {
|
|
2812
|
+
console.log(JSON.stringify(results, null, 2));
|
|
2813
|
+
return;
|
|
2814
|
+
}
|
|
2815
|
+
log.blank();
|
|
2816
|
+
for (let i = 0; i < results.length; i++) {
|
|
2817
|
+
log.plain(formatLibraryResult(results[i], i));
|
|
2818
|
+
log.blank();
|
|
2819
|
+
}
|
|
2820
|
+
if (isTTY && results.length > 0) {
|
|
2821
|
+
const best = results[0];
|
|
2822
|
+
log.plain(
|
|
2823
|
+
`${pc9.bold("Quick command:")}
|
|
2824
|
+
${pc9.cyan(`ctx7 docs "${best.id}" "<your question>"`)}`
|
|
2825
|
+
);
|
|
2826
|
+
log.blank();
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
async function queryCommand(libraryId, query, options) {
|
|
2830
|
+
trackEvent("command", { name: "docs" });
|
|
2831
|
+
if (!libraryId.startsWith("/")) {
|
|
2832
|
+
log.error(`Invalid library ID: ${libraryId}`);
|
|
2833
|
+
log.info(`Library IDs start with "/" (e.g., /facebook/react)`);
|
|
2834
|
+
log.info(`Run "ctx7 library <name>" to find the correct ID`);
|
|
2835
|
+
process.exitCode = 1;
|
|
2836
|
+
return;
|
|
2837
|
+
}
|
|
2838
|
+
const spinner = isTTY ? ora5(`Fetching docs for "${libraryId}"...`).start() : null;
|
|
2839
|
+
const accessToken = getAccessToken();
|
|
2840
|
+
const outputType = options.json ? "json" : "txt";
|
|
2841
|
+
let result;
|
|
2842
|
+
try {
|
|
2843
|
+
result = await getLibraryContext(libraryId, query, { type: outputType }, accessToken);
|
|
2844
|
+
} catch (err) {
|
|
2845
|
+
spinner?.fail(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
2846
|
+
if (!spinner) log.error(err instanceof Error ? err.message : String(err));
|
|
2847
|
+
process.exitCode = 1;
|
|
2848
|
+
return;
|
|
2849
|
+
}
|
|
2850
|
+
if (typeof result === "string") {
|
|
2851
|
+
spinner?.stop();
|
|
2852
|
+
console.log(result);
|
|
2853
|
+
return;
|
|
2854
|
+
}
|
|
2855
|
+
const ctx = result;
|
|
2856
|
+
if (ctx.error) {
|
|
2857
|
+
if (ctx.redirectUrl) {
|
|
2858
|
+
spinner?.warn("Library has been redirected");
|
|
2859
|
+
if (!spinner) log.warn("Library has been redirected");
|
|
2860
|
+
log.info(`New ID: ${pc9.cyan(ctx.redirectUrl)}`);
|
|
2861
|
+
log.info(`Run: ${pc9.cyan(`ctx7 docs "${ctx.redirectUrl}" "${query}"`)}`);
|
|
2862
|
+
process.exitCode = 1;
|
|
2863
|
+
return;
|
|
2864
|
+
}
|
|
2865
|
+
spinner?.fail(ctx.message || ctx.error);
|
|
2866
|
+
if (!spinner) log.error(ctx.message || ctx.error);
|
|
2867
|
+
process.exitCode = 1;
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
const total = (ctx.codeSnippets?.length || 0) + (ctx.infoSnippets?.length || 0);
|
|
2871
|
+
if (total === 0) {
|
|
2872
|
+
spinner?.warn(`No documentation found for: "${query}"`);
|
|
2873
|
+
if (!spinner) log.warn(`No documentation found for: "${query}"`);
|
|
2874
|
+
return;
|
|
2875
|
+
}
|
|
2876
|
+
spinner?.stop();
|
|
2877
|
+
if (options.json) {
|
|
2878
|
+
console.log(JSON.stringify(ctx, null, 2));
|
|
2879
|
+
return;
|
|
2880
|
+
}
|
|
2881
|
+
log.blank();
|
|
2882
|
+
if (ctx.codeSnippets) {
|
|
2883
|
+
for (const snippet of ctx.codeSnippets) {
|
|
2884
|
+
log.plain(pc9.bold(snippet.codeTitle));
|
|
2885
|
+
if (snippet.codeDescription) log.dim(snippet.codeDescription);
|
|
2886
|
+
log.blank();
|
|
2887
|
+
for (const code of snippet.codeList) {
|
|
2888
|
+
log.plain("```" + code.language);
|
|
2889
|
+
log.plain(code.code);
|
|
2890
|
+
log.plain("```");
|
|
2891
|
+
log.blank();
|
|
2892
|
+
}
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
if (ctx.infoSnippets) {
|
|
2896
|
+
for (const snippet of ctx.infoSnippets) {
|
|
2897
|
+
if (snippet.breadcrumb) log.plain(pc9.bold(snippet.breadcrumb));
|
|
2898
|
+
log.plain(snippet.content);
|
|
2899
|
+
log.blank();
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
function registerDocsCommands(program2) {
|
|
2904
|
+
program2.command("library").argument("<name>", "Library name to search for").argument("[query]", "Question or task for relevance ranking").option("--json", "Output as JSON").description("Resolve a library name to a Context7 library ID").action(async (name, query, options) => {
|
|
2905
|
+
await resolveCommand(name, query, options);
|
|
2906
|
+
});
|
|
2907
|
+
program2.command("docs").argument("<libraryId>", "Context7 library ID (e.g., /facebook/react)").argument("<query>", "Question or task to get docs for").option("--json", "Output as JSON").description("Query documentation for a library").action(async (libraryId, query, options) => {
|
|
2908
|
+
await queryCommand(libraryId, query, options);
|
|
2909
|
+
});
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2603
2912
|
// src/constants.ts
|
|
2604
2913
|
import { readFileSync as readFileSync2 } from "fs";
|
|
2605
2914
|
import { fileURLToPath } from "url";
|
|
@@ -2611,8 +2920,8 @@ var NAME = pkg.name;
|
|
|
2611
2920
|
|
|
2612
2921
|
// src/index.ts
|
|
2613
2922
|
var brand = {
|
|
2614
|
-
primary:
|
|
2615
|
-
dim:
|
|
2923
|
+
primary: pc10.green,
|
|
2924
|
+
dim: pc10.dim
|
|
2616
2925
|
};
|
|
2617
2926
|
var program = new Command();
|
|
2618
2927
|
program.name("ctx7").description("Context7 CLI - Manage AI coding skills and documentation context").version(VERSION).option("--base-url <url>").hook("preAction", (thisCommand) => {
|
|
@@ -2641,6 +2950,10 @@ Examples:
|
|
|
2641
2950
|
${brand.primary("npx ctx7 skills list --claude")}
|
|
2642
2951
|
${brand.primary("npx ctx7 skills remove pdf")}
|
|
2643
2952
|
|
|
2953
|
+
${brand.dim("# Query library documentation")}
|
|
2954
|
+
${brand.primary('npx ctx7 library react "how to use hooks"')}
|
|
2955
|
+
${brand.primary('npx ctx7 docs /facebook/react "useEffect examples"')}
|
|
2956
|
+
|
|
2644
2957
|
Visit ${brand.primary("https://context7.com")} to browse skills
|
|
2645
2958
|
`
|
|
2646
2959
|
);
|
|
@@ -2648,6 +2961,7 @@ registerSkillCommands(program);
|
|
|
2648
2961
|
registerSkillAliases(program);
|
|
2649
2962
|
registerAuthCommands(program);
|
|
2650
2963
|
registerSetupCommand(program);
|
|
2964
|
+
registerDocsCommands(program);
|
|
2651
2965
|
program.action(() => {
|
|
2652
2966
|
console.log("");
|
|
2653
2967
|
const banner = figlet.textSync("Context7", { font: "ANSI Shadow" });
|