ctx7 0.2.4 → 0.3.0
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 +38 -0
- package/dist/index.js +351 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,18 @@ npm install -g ctx7
|
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
|
+
```bash
|
|
20
|
+
# Set up Context7 MCP for your coding agents
|
|
21
|
+
ctx7 setup
|
|
22
|
+
|
|
23
|
+
# Target a specific agent
|
|
24
|
+
ctx7 setup --cursor
|
|
25
|
+
ctx7 setup --claude
|
|
26
|
+
ctx7 setup --opencode
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Skills
|
|
30
|
+
|
|
19
31
|
```bash
|
|
20
32
|
# Search for skills
|
|
21
33
|
ctx7 skills search pdf
|
|
@@ -32,6 +44,32 @@ ctx7 skills list --claude
|
|
|
32
44
|
|
|
33
45
|
## Usage
|
|
34
46
|
|
|
47
|
+
### Setup
|
|
48
|
+
|
|
49
|
+
Configure Context7 MCP and a rule for your AI coding agents. Authenticates via OAuth, generates an API key, and writes the config.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Interactive (prompts for agent selection)
|
|
53
|
+
ctx7 setup
|
|
54
|
+
|
|
55
|
+
# Target specific agents
|
|
56
|
+
ctx7 setup --cursor
|
|
57
|
+
ctx7 setup --claude
|
|
58
|
+
ctx7 setup --opencode
|
|
59
|
+
|
|
60
|
+
# Use an existing API key instead of OAuth
|
|
61
|
+
ctx7 setup --api-key YOUR_API_KEY
|
|
62
|
+
|
|
63
|
+
# Use OAuth endpoint (IDE handles auth flow)
|
|
64
|
+
ctx7 setup --oauth
|
|
65
|
+
|
|
66
|
+
# Configure for current project only (default is global)
|
|
67
|
+
ctx7 setup --project
|
|
68
|
+
|
|
69
|
+
# Skip prompts
|
|
70
|
+
ctx7 setup --yes
|
|
71
|
+
```
|
|
72
|
+
|
|
35
73
|
### Generate skills
|
|
36
74
|
|
|
37
75
|
Generate custom skills tailored to your use case using AI. Requires authentication.
|
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 pc9 from "picocolors";
|
|
6
6
|
import figlet from "figlet";
|
|
7
7
|
|
|
8
8
|
// src/commands/skill.ts
|
|
@@ -2256,19 +2256,363 @@ ${headerLine}`,
|
|
|
2256
2256
|
logInstallSummary(targets, targetDirs, installedNames);
|
|
2257
2257
|
}
|
|
2258
2258
|
|
|
2259
|
+
// src/commands/setup.ts
|
|
2260
|
+
import pc8 from "picocolors";
|
|
2261
|
+
import ora4 from "ora";
|
|
2262
|
+
import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
|
|
2263
|
+
import { dirname as dirname3, join as join8 } from "path";
|
|
2264
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
2265
|
+
|
|
2266
|
+
// src/setup/agents.ts
|
|
2267
|
+
import { access as access2 } from "fs/promises";
|
|
2268
|
+
import { join as join7 } from "path";
|
|
2269
|
+
import { homedir as homedir5 } from "os";
|
|
2270
|
+
var SETUP_AGENT_NAMES = {
|
|
2271
|
+
claude: "Claude Code",
|
|
2272
|
+
cursor: "Cursor",
|
|
2273
|
+
opencode: "OpenCode"
|
|
2274
|
+
};
|
|
2275
|
+
var AUTH_MODE_LABELS = {
|
|
2276
|
+
oauth: "OAuth",
|
|
2277
|
+
"api-key": "API Key"
|
|
2278
|
+
};
|
|
2279
|
+
var MCP_BASE_URL = "https://mcp.context7.com";
|
|
2280
|
+
function mcpUrl(auth) {
|
|
2281
|
+
return auth.mode === "oauth" ? `${MCP_BASE_URL}/mcp/oauth` : `${MCP_BASE_URL}/mcp`;
|
|
2282
|
+
}
|
|
2283
|
+
function withHeaders(base, auth) {
|
|
2284
|
+
if (auth.mode === "api-key" && auth.apiKey) {
|
|
2285
|
+
return { ...base, headers: { CONTEXT7_API_KEY: auth.apiKey } };
|
|
2286
|
+
}
|
|
2287
|
+
return base;
|
|
2288
|
+
}
|
|
2289
|
+
var agents = {
|
|
2290
|
+
claude: {
|
|
2291
|
+
name: "claude",
|
|
2292
|
+
displayName: "Claude Code",
|
|
2293
|
+
mcp: {
|
|
2294
|
+
projectPath: ".mcp.json",
|
|
2295
|
+
globalPath: join7(homedir5(), ".claude.json"),
|
|
2296
|
+
configKey: "mcpServers",
|
|
2297
|
+
buildEntry: (auth) => withHeaders({ type: "http", url: mcpUrl(auth) }, auth)
|
|
2298
|
+
},
|
|
2299
|
+
rule: {
|
|
2300
|
+
dir: (scope) => scope === "global" ? join7(homedir5(), ".claude", "rules") : join7(".claude", "rules"),
|
|
2301
|
+
filename: "context7.md"
|
|
2302
|
+
},
|
|
2303
|
+
detect: {
|
|
2304
|
+
projectPaths: [".mcp.json", ".claude"],
|
|
2305
|
+
globalPaths: [join7(homedir5(), ".claude")]
|
|
2306
|
+
}
|
|
2307
|
+
},
|
|
2308
|
+
cursor: {
|
|
2309
|
+
name: "cursor",
|
|
2310
|
+
displayName: "Cursor",
|
|
2311
|
+
mcp: {
|
|
2312
|
+
projectPath: join7(".cursor", "mcp.json"),
|
|
2313
|
+
globalPath: join7(homedir5(), ".cursor", "mcp.json"),
|
|
2314
|
+
configKey: "mcpServers",
|
|
2315
|
+
buildEntry: (auth) => withHeaders({ url: mcpUrl(auth) }, auth)
|
|
2316
|
+
},
|
|
2317
|
+
rule: {
|
|
2318
|
+
dir: (scope) => scope === "global" ? join7(homedir5(), ".cursor", "rules") : join7(".cursor", "rules"),
|
|
2319
|
+
filename: "context7.mdc"
|
|
2320
|
+
},
|
|
2321
|
+
detect: {
|
|
2322
|
+
projectPaths: [".cursor"],
|
|
2323
|
+
globalPaths: [join7(homedir5(), ".cursor")]
|
|
2324
|
+
}
|
|
2325
|
+
},
|
|
2326
|
+
opencode: {
|
|
2327
|
+
name: "opencode",
|
|
2328
|
+
displayName: "OpenCode",
|
|
2329
|
+
mcp: {
|
|
2330
|
+
projectPath: ".opencode.json",
|
|
2331
|
+
globalPath: join7(homedir5(), ".config", "opencode", "opencode.json"),
|
|
2332
|
+
configKey: "mcp",
|
|
2333
|
+
buildEntry: (auth) => withHeaders({ type: "remote", url: mcpUrl(auth), enabled: true }, auth)
|
|
2334
|
+
},
|
|
2335
|
+
rule: {
|
|
2336
|
+
dir: (scope) => scope === "global" ? join7(homedir5(), ".config", "opencode", "rules") : join7(".opencode", "rules"),
|
|
2337
|
+
filename: "context7.md",
|
|
2338
|
+
instructionsGlob: (scope) => scope === "global" ? join7(homedir5(), ".config", "opencode", "rules", "*.md") : ".opencode/rules/*.md"
|
|
2339
|
+
},
|
|
2340
|
+
detect: {
|
|
2341
|
+
projectPaths: [".opencode.json"],
|
|
2342
|
+
globalPaths: [join7(homedir5(), ".config", "opencode")]
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
};
|
|
2346
|
+
function getAgent(name) {
|
|
2347
|
+
return agents[name];
|
|
2348
|
+
}
|
|
2349
|
+
var ALL_AGENT_NAMES = Object.keys(agents);
|
|
2350
|
+
async function pathExists(p) {
|
|
2351
|
+
try {
|
|
2352
|
+
await access2(p);
|
|
2353
|
+
return true;
|
|
2354
|
+
} catch {
|
|
2355
|
+
return false;
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
async function detectAgents(scope) {
|
|
2359
|
+
const detected = [];
|
|
2360
|
+
for (const agent of Object.values(agents)) {
|
|
2361
|
+
const paths = scope === "global" ? agent.detect.globalPaths : agent.detect.projectPaths;
|
|
2362
|
+
for (const p of paths) {
|
|
2363
|
+
const fullPath = scope === "global" ? p : join7(process.cwd(), p);
|
|
2364
|
+
if (await pathExists(fullPath)) {
|
|
2365
|
+
detected.push(agent.name);
|
|
2366
|
+
break;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
return detected;
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
// src/setup/templates.ts
|
|
2374
|
+
var RULE_CONTENT = `---
|
|
2375
|
+
alwaysApply: true
|
|
2376
|
+
---
|
|
2377
|
+
|
|
2378
|
+
When working with libraries, frameworks, or APIs \u2014 use Context7 MCP to fetch current documentation instead of relying on training data. This includes setup questions, code generation, API references, and anything involving specific packages.
|
|
2379
|
+
|
|
2380
|
+
## Steps
|
|
2381
|
+
|
|
2382
|
+
1. Call \`resolve-library-id\` with the library name and the user's question
|
|
2383
|
+
2. Pick the best match \u2014 prefer exact names and version-specific IDs when a version is mentioned
|
|
2384
|
+
3. Call \`query-docs\` with the selected library ID and the user's question
|
|
2385
|
+
4. Answer using the fetched docs \u2014 include code examples and cite the version
|
|
2386
|
+
`;
|
|
2387
|
+
|
|
2388
|
+
// src/setup/mcp-writer.ts
|
|
2389
|
+
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
2390
|
+
import { dirname as dirname2 } from "path";
|
|
2391
|
+
async function readJsonConfig(filePath) {
|
|
2392
|
+
let raw;
|
|
2393
|
+
try {
|
|
2394
|
+
raw = await readFile3(filePath, "utf-8");
|
|
2395
|
+
} catch {
|
|
2396
|
+
return {};
|
|
2397
|
+
}
|
|
2398
|
+
raw = raw.trim();
|
|
2399
|
+
if (!raw) return {};
|
|
2400
|
+
return JSON.parse(raw);
|
|
2401
|
+
}
|
|
2402
|
+
function mergeServerEntry(existing, configKey, serverName, entry) {
|
|
2403
|
+
const section = existing[configKey] ?? {};
|
|
2404
|
+
if (serverName in section) {
|
|
2405
|
+
return { config: existing, alreadyExists: true };
|
|
2406
|
+
}
|
|
2407
|
+
return {
|
|
2408
|
+
config: {
|
|
2409
|
+
...existing,
|
|
2410
|
+
[configKey]: {
|
|
2411
|
+
...section,
|
|
2412
|
+
[serverName]: entry
|
|
2413
|
+
}
|
|
2414
|
+
},
|
|
2415
|
+
alreadyExists: false
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
function mergeInstructions(config, glob) {
|
|
2419
|
+
const instructions = config.instructions ?? [];
|
|
2420
|
+
if (instructions.includes(glob)) return config;
|
|
2421
|
+
return { ...config, instructions: [...instructions, glob] };
|
|
2422
|
+
}
|
|
2423
|
+
async function writeJsonConfig(filePath, config) {
|
|
2424
|
+
await mkdir3(dirname2(filePath), { recursive: true });
|
|
2425
|
+
await writeFile3(filePath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
// src/commands/setup.ts
|
|
2429
|
+
var CHECKBOX_THEME = {
|
|
2430
|
+
style: {
|
|
2431
|
+
highlight: (text) => pc8.green(text),
|
|
2432
|
+
disabledChoice: (text) => ` ${pc8.dim("\u25EF")} ${pc8.dim(text)}`
|
|
2433
|
+
}
|
|
2434
|
+
};
|
|
2435
|
+
function getSelectedAgents(options) {
|
|
2436
|
+
const agents2 = [];
|
|
2437
|
+
if (options.claude) agents2.push("claude");
|
|
2438
|
+
if (options.cursor) agents2.push("cursor");
|
|
2439
|
+
if (options.opencode) agents2.push("opencode");
|
|
2440
|
+
return agents2;
|
|
2441
|
+
}
|
|
2442
|
+
function registerSetupCommand(program2) {
|
|
2443
|
+
program2.command("setup").description("Set up Context7 MCP and rule for your AI coding agent").option("--claude", "Set up for Claude Code").option("--cursor", "Set up for Cursor").option("--opencode", "Set up for OpenCode").option("-p, --project", "Configure for current project instead of globally").option("-y, --yes", "Skip confirmation prompts").option("--api-key <key>", "Use API key authentication").option("--oauth", "Use OAuth endpoint (IDE handles auth flow)").action(async (options) => {
|
|
2444
|
+
await setupCommand(options);
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
async function authenticateAndGenerateKey() {
|
|
2448
|
+
const existingTokens = loadTokens();
|
|
2449
|
+
const accessToken = existingTokens && !isTokenExpired(existingTokens) ? existingTokens.access_token : await performLogin();
|
|
2450
|
+
if (!accessToken) return null;
|
|
2451
|
+
const spinner = ora4("Configuring authentication...").start();
|
|
2452
|
+
try {
|
|
2453
|
+
const response = await fetch(`${getBaseUrl()}/api/dashboard/api-keys`, {
|
|
2454
|
+
method: "POST",
|
|
2455
|
+
headers: {
|
|
2456
|
+
Authorization: `Bearer ${accessToken}`,
|
|
2457
|
+
"Content-Type": "application/json"
|
|
2458
|
+
},
|
|
2459
|
+
body: JSON.stringify({ name: `ctx7-cli-${randomBytes2(3).toString("hex")}` })
|
|
2460
|
+
});
|
|
2461
|
+
if (!response.ok) {
|
|
2462
|
+
const err = await response.json().catch(() => ({}));
|
|
2463
|
+
spinner.fail("Authentication failed");
|
|
2464
|
+
log.error(err.message || err.error || `HTTP ${response.status}`);
|
|
2465
|
+
return null;
|
|
2466
|
+
}
|
|
2467
|
+
const result = await response.json();
|
|
2468
|
+
spinner.succeed("Authenticated");
|
|
2469
|
+
return result.data.apiKey;
|
|
2470
|
+
} catch (err) {
|
|
2471
|
+
spinner.fail("Authentication failed");
|
|
2472
|
+
log.error(err instanceof Error ? err.message : String(err));
|
|
2473
|
+
return null;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
async function resolveAuth(options) {
|
|
2477
|
+
if (options.apiKey) return { mode: "api-key", apiKey: options.apiKey };
|
|
2478
|
+
if (options.oauth) return { mode: "oauth" };
|
|
2479
|
+
const apiKey = await authenticateAndGenerateKey();
|
|
2480
|
+
if (!apiKey) return null;
|
|
2481
|
+
return { mode: "api-key", apiKey };
|
|
2482
|
+
}
|
|
2483
|
+
async function isAlreadyConfigured(agentName, scope) {
|
|
2484
|
+
const agent = getAgent(agentName);
|
|
2485
|
+
const mcpPath = scope === "global" ? agent.mcp.globalPath : join8(process.cwd(), agent.mcp.projectPath);
|
|
2486
|
+
try {
|
|
2487
|
+
const existing = await readJsonConfig(mcpPath);
|
|
2488
|
+
const section = existing[agent.mcp.configKey] ?? {};
|
|
2489
|
+
return "context7" in section;
|
|
2490
|
+
} catch {
|
|
2491
|
+
return false;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
async function promptAgents(scope) {
|
|
2495
|
+
const choices = await Promise.all(
|
|
2496
|
+
ALL_AGENT_NAMES.map(async (name) => {
|
|
2497
|
+
const configured = await isAlreadyConfigured(name, scope);
|
|
2498
|
+
return {
|
|
2499
|
+
name: SETUP_AGENT_NAMES[name],
|
|
2500
|
+
value: name,
|
|
2501
|
+
disabled: configured ? "(already configured)" : false
|
|
2502
|
+
};
|
|
2503
|
+
})
|
|
2504
|
+
);
|
|
2505
|
+
if (choices.every((c) => c.disabled)) {
|
|
2506
|
+
log.info("Context7 is already configured for all detected agents.");
|
|
2507
|
+
return null;
|
|
2508
|
+
}
|
|
2509
|
+
try {
|
|
2510
|
+
return await checkboxWithHover(
|
|
2511
|
+
{
|
|
2512
|
+
message: "Which agents do you want to set up?",
|
|
2513
|
+
choices,
|
|
2514
|
+
loop: false,
|
|
2515
|
+
theme: CHECKBOX_THEME
|
|
2516
|
+
},
|
|
2517
|
+
{ getName: (a) => SETUP_AGENT_NAMES[a] }
|
|
2518
|
+
);
|
|
2519
|
+
} catch {
|
|
2520
|
+
return null;
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
async function resolveAgents(options, scope) {
|
|
2524
|
+
const explicit = getSelectedAgents(options);
|
|
2525
|
+
if (explicit.length > 0) return explicit;
|
|
2526
|
+
const detected = await detectAgents(scope);
|
|
2527
|
+
if (detected.length > 0 && options.yes) return detected;
|
|
2528
|
+
log.blank();
|
|
2529
|
+
const selected = await promptAgents(scope);
|
|
2530
|
+
if (!selected) {
|
|
2531
|
+
log.warn("Setup cancelled");
|
|
2532
|
+
return [];
|
|
2533
|
+
}
|
|
2534
|
+
return selected;
|
|
2535
|
+
}
|
|
2536
|
+
async function setupAgent(agentName, auth, scope) {
|
|
2537
|
+
const agent = getAgent(agentName);
|
|
2538
|
+
const mcpPath = scope === "global" ? agent.mcp.globalPath : join8(process.cwd(), agent.mcp.projectPath);
|
|
2539
|
+
let mcpStatus;
|
|
2540
|
+
try {
|
|
2541
|
+
const existing = await readJsonConfig(mcpPath);
|
|
2542
|
+
const { config, alreadyExists } = mergeServerEntry(
|
|
2543
|
+
existing,
|
|
2544
|
+
agent.mcp.configKey,
|
|
2545
|
+
"context7",
|
|
2546
|
+
agent.mcp.buildEntry(auth)
|
|
2547
|
+
);
|
|
2548
|
+
if (alreadyExists) {
|
|
2549
|
+
mcpStatus = "already configured";
|
|
2550
|
+
} else {
|
|
2551
|
+
mcpStatus = `configured with ${AUTH_MODE_LABELS[auth.mode]}`;
|
|
2552
|
+
}
|
|
2553
|
+
const finalConfig = agent.rule.instructionsGlob ? mergeInstructions(config, agent.rule.instructionsGlob(scope)) : config;
|
|
2554
|
+
if (finalConfig !== existing) {
|
|
2555
|
+
await writeJsonConfig(mcpPath, finalConfig);
|
|
2556
|
+
}
|
|
2557
|
+
} catch (err) {
|
|
2558
|
+
mcpStatus = `failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
2559
|
+
}
|
|
2560
|
+
const rulePath = scope === "global" ? join8(agent.rule.dir("global"), agent.rule.filename) : join8(process.cwd(), agent.rule.dir("project"), agent.rule.filename);
|
|
2561
|
+
let ruleStatus;
|
|
2562
|
+
try {
|
|
2563
|
+
await mkdir4(dirname3(rulePath), { recursive: true });
|
|
2564
|
+
await writeFile4(rulePath, RULE_CONTENT, "utf-8");
|
|
2565
|
+
ruleStatus = "installed";
|
|
2566
|
+
} catch (err) {
|
|
2567
|
+
ruleStatus = `failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
2568
|
+
}
|
|
2569
|
+
return { agent: agent.displayName, mcpStatus, mcpPath, ruleStatus, rulePath };
|
|
2570
|
+
}
|
|
2571
|
+
async function setupCommand(options) {
|
|
2572
|
+
trackEvent("command", { name: "setup" });
|
|
2573
|
+
const scope = options.project ? "project" : "global";
|
|
2574
|
+
const agents2 = await resolveAgents(options, scope);
|
|
2575
|
+
if (agents2.length === 0) return;
|
|
2576
|
+
const auth = await resolveAuth(options);
|
|
2577
|
+
if (!auth) {
|
|
2578
|
+
log.warn("Setup cancelled");
|
|
2579
|
+
return;
|
|
2580
|
+
}
|
|
2581
|
+
log.blank();
|
|
2582
|
+
const spinner = ora4("Setting up Context7...").start();
|
|
2583
|
+
const results = [];
|
|
2584
|
+
for (const agentName of agents2) {
|
|
2585
|
+
spinner.text = `Setting up ${getAgent(agentName).displayName}...`;
|
|
2586
|
+
results.push(await setupAgent(agentName, auth, scope));
|
|
2587
|
+
}
|
|
2588
|
+
spinner.succeed("Context7 setup complete");
|
|
2589
|
+
log.blank();
|
|
2590
|
+
for (const r of results) {
|
|
2591
|
+
log.plain(` ${pc8.bold(r.agent)}`);
|
|
2592
|
+
const mcpIcon = r.mcpStatus.startsWith("configured") ? pc8.green("+") : pc8.dim("~");
|
|
2593
|
+
log.plain(` ${mcpIcon} MCP server ${r.mcpStatus}`);
|
|
2594
|
+
log.plain(` ${pc8.dim(r.mcpPath)}`);
|
|
2595
|
+
const ruleIcon = r.ruleStatus === "installed" ? pc8.green("+") : pc8.dim("~");
|
|
2596
|
+
log.plain(` ${ruleIcon} Rule ${r.ruleStatus}`);
|
|
2597
|
+
log.plain(` ${pc8.dim(r.rulePath)}`);
|
|
2598
|
+
}
|
|
2599
|
+
log.blank();
|
|
2600
|
+
trackEvent("setup", { agents: agents2, scope, authMode: auth.mode });
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2259
2603
|
// src/constants.ts
|
|
2260
2604
|
import { readFileSync as readFileSync2 } from "fs";
|
|
2261
2605
|
import { fileURLToPath } from "url";
|
|
2262
|
-
import { dirname as
|
|
2263
|
-
var __dirname =
|
|
2264
|
-
var pkg = JSON.parse(readFileSync2(
|
|
2606
|
+
import { dirname as dirname4, join as join9 } from "path";
|
|
2607
|
+
var __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
2608
|
+
var pkg = JSON.parse(readFileSync2(join9(__dirname, "../package.json"), "utf-8"));
|
|
2265
2609
|
var VERSION = pkg.version;
|
|
2266
2610
|
var NAME = pkg.name;
|
|
2267
2611
|
|
|
2268
2612
|
// src/index.ts
|
|
2269
2613
|
var brand = {
|
|
2270
|
-
primary:
|
|
2271
|
-
dim:
|
|
2614
|
+
primary: pc9.green,
|
|
2615
|
+
dim: pc9.dim
|
|
2272
2616
|
};
|
|
2273
2617
|
var program = new Command();
|
|
2274
2618
|
program.name("ctx7").description("Context7 CLI - Manage AI coding skills and documentation context").version(VERSION).option("--base-url <url>").hook("preAction", (thisCommand) => {
|
|
@@ -2303,6 +2647,7 @@ Visit ${brand.primary("https://context7.com")} to browse skills
|
|
|
2303
2647
|
registerSkillCommands(program);
|
|
2304
2648
|
registerSkillAliases(program);
|
|
2305
2649
|
registerAuthCommands(program);
|
|
2650
|
+
registerSetupCommand(program);
|
|
2306
2651
|
program.action(() => {
|
|
2307
2652
|
console.log("");
|
|
2308
2653
|
const banner = figlet.textSync("Context7", { font: "ANSI Shadow" });
|