doc2mcp 0.1.18 → 0.1.20
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 +169 -63
- package/package.json +1 -1
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
|
|
|
7
7
|
// src/commands/account.ts
|
|
8
8
|
import pc from "picocolors";
|
|
@@ -77,7 +77,7 @@ async function runWhoami() {
|
|
|
77
77
|
import { createInterface } from "readline/promises";
|
|
78
78
|
import { stdin as input, stdout as output } from "process";
|
|
79
79
|
import ora2 from "ora";
|
|
80
|
-
import
|
|
80
|
+
import pc8 from "picocolors";
|
|
81
81
|
|
|
82
82
|
// src/api.ts
|
|
83
83
|
import pc2 from "picocolors";
|
|
@@ -139,13 +139,117 @@ function printError(error) {
|
|
|
139
139
|
`);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
// src/banner.ts
|
|
143
|
+
import pc3 from "picocolors";
|
|
144
|
+
var LOGO = [
|
|
145
|
+
"\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
146
|
+
"\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557",
|
|
147
|
+
"\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D",
|
|
148
|
+
"\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u255D ",
|
|
149
|
+
"\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 ",
|
|
150
|
+
"\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D "
|
|
151
|
+
];
|
|
152
|
+
var SHADES = [pc3.cyan, pc3.cyan, pc3.blue, pc3.blue, pc3.cyan, pc3.cyan];
|
|
153
|
+
var POWERED_BY = "meerutcodehub team";
|
|
154
|
+
function divider(width = 58) {
|
|
155
|
+
return pc3.dim("\u2500".repeat(width));
|
|
156
|
+
}
|
|
157
|
+
function printBanner() {
|
|
158
|
+
process.stdout.write("\n");
|
|
159
|
+
LOGO.forEach((line, index) => {
|
|
160
|
+
const color = SHADES[index] ?? pc3.cyan;
|
|
161
|
+
process.stdout.write(` ${pc3.bold(color(line))}
|
|
162
|
+
`);
|
|
163
|
+
});
|
|
164
|
+
process.stdout.write(`
|
|
165
|
+
${divider()}
|
|
166
|
+
`);
|
|
167
|
+
process.stdout.write(
|
|
168
|
+
` ${pc3.dim("powered by")} ${pc3.bold(pc3.cyan(POWERED_BY))}
|
|
169
|
+
|
|
170
|
+
`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/markdown.ts
|
|
175
|
+
import pc4 from "picocolors";
|
|
176
|
+
var LINK = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
177
|
+
var INLINE_CODE = /`([^`]+)`/g;
|
|
178
|
+
var BOLD = /\*\*([^*]+)\*\*/g;
|
|
179
|
+
var ITALIC = /(^|[^*])\*([^*\n]+)\*/g;
|
|
180
|
+
var HEADING = /^(#{1,6})\s+(.*)$/;
|
|
181
|
+
var BULLET = /^(\s*)[-*]\s+(.*)$/;
|
|
182
|
+
var ORDERED = /^(\s*)(\d+)\.\s+(.*)$/;
|
|
183
|
+
var FENCE = /^```(\w*)\s*$/;
|
|
184
|
+
var BLOCKQUOTE = /^>\s?(.*)$/;
|
|
185
|
+
function renderInline(text) {
|
|
186
|
+
let out = text.replace(
|
|
187
|
+
LINK,
|
|
188
|
+
(_m, label, url) => `${pc4.cyan(pc4.underline(label))} ${pc4.dim(`(${url})`)}`
|
|
189
|
+
);
|
|
190
|
+
out = out.replace(INLINE_CODE, (_m, code) => pc4.yellow(code));
|
|
191
|
+
out = out.replace(BOLD, (_m, bold) => pc4.bold(bold));
|
|
192
|
+
out = out.replace(
|
|
193
|
+
ITALIC,
|
|
194
|
+
(_m, prefix, italic) => `${prefix}${pc4.italic(italic)}`
|
|
195
|
+
);
|
|
196
|
+
return out;
|
|
197
|
+
}
|
|
198
|
+
function renderMarkdown(markdown) {
|
|
199
|
+
const lines = markdown.split("\n");
|
|
200
|
+
const out = [];
|
|
201
|
+
let inCode = false;
|
|
202
|
+
for (const line of lines) {
|
|
203
|
+
const fence = line.match(FENCE);
|
|
204
|
+
if (fence) {
|
|
205
|
+
if (inCode) {
|
|
206
|
+
out.push(pc4.dim(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
207
|
+
inCode = false;
|
|
208
|
+
} else {
|
|
209
|
+
const lang = fence[1] || "code";
|
|
210
|
+
out.push(pc4.dim(` \u250C\u2500\u2500\u2500\u2500\u2500\u2500 ${lang}`));
|
|
211
|
+
inCode = true;
|
|
212
|
+
}
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (inCode) {
|
|
216
|
+
out.push(` ${pc4.green(line)}`);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const heading = line.match(HEADING);
|
|
220
|
+
if (heading) {
|
|
221
|
+
out.push(pc4.bold(pc4.cyan(renderInline(heading[2] ?? ""))));
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const ordered = line.match(ORDERED);
|
|
225
|
+
if (ordered) {
|
|
226
|
+
out.push(
|
|
227
|
+
`${ordered[1] ?? ""}${pc4.cyan(`${ordered[2] ?? ""}.`)} ${renderInline(ordered[3] ?? "")}`
|
|
228
|
+
);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
const bullet = line.match(BULLET);
|
|
232
|
+
if (bullet) {
|
|
233
|
+
out.push(`${bullet[1] ?? ""}${pc4.cyan("\u2022")} ${renderInline(bullet[2] ?? "")}`);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const quote = line.match(BLOCKQUOTE);
|
|
237
|
+
if (quote) {
|
|
238
|
+
out.push(`${pc4.dim("\u2502")} ${pc4.dim(renderInline(quote[1] ?? ""))}`);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
out.push(renderInline(line));
|
|
242
|
+
}
|
|
243
|
+
return out.join("\n");
|
|
244
|
+
}
|
|
245
|
+
|
|
142
246
|
// src/commands/convert.ts
|
|
143
|
-
import
|
|
247
|
+
import pc7 from "picocolors";
|
|
144
248
|
|
|
145
249
|
// src/commands/login.ts
|
|
146
250
|
import open from "open";
|
|
147
251
|
import ora from "ora";
|
|
148
|
-
import
|
|
252
|
+
import pc5 from "picocolors";
|
|
149
253
|
function sleep(ms) {
|
|
150
254
|
return new Promise((resolve) => {
|
|
151
255
|
setTimeout(resolve, ms);
|
|
@@ -163,13 +267,13 @@ async function runLogin() {
|
|
|
163
267
|
spinner.stop();
|
|
164
268
|
process.stdout.write(
|
|
165
269
|
`
|
|
166
|
-
${
|
|
167
|
-
${
|
|
270
|
+
${pc5.cyan("Open this link to authorize:")}
|
|
271
|
+
${pc5.bold(start.verifyUrl)}
|
|
168
272
|
|
|
169
273
|
`
|
|
170
274
|
);
|
|
171
275
|
process.stdout.write(
|
|
172
|
-
`${
|
|
276
|
+
`${pc5.dim("Code:")} ${pc5.bold(start.userCode)} ${pc5.dim("(also shown in browser)")}
|
|
173
277
|
|
|
174
278
|
`
|
|
175
279
|
);
|
|
@@ -177,7 +281,7 @@ ${pc3.bold(start.verifyUrl)}
|
|
|
177
281
|
await open(start.verifyUrl);
|
|
178
282
|
} catch {
|
|
179
283
|
process.stdout.write(
|
|
180
|
-
`${
|
|
284
|
+
`${pc5.yellow("Could not auto-open browser. Open the link manually.")}
|
|
181
285
|
|
|
182
286
|
`
|
|
183
287
|
);
|
|
@@ -203,7 +307,7 @@ ${pc3.bold(start.verifyUrl)}
|
|
|
203
307
|
user: poll.user
|
|
204
308
|
});
|
|
205
309
|
process.stdout.write(
|
|
206
|
-
`${
|
|
310
|
+
`${pc5.green("Logged in as")} ${poll.user.email}
|
|
207
311
|
`
|
|
208
312
|
);
|
|
209
313
|
return;
|
|
@@ -238,7 +342,7 @@ async function ensureLoggedIn() {
|
|
|
238
342
|
|
|
239
343
|
// src/commands/install.ts
|
|
240
344
|
import { confirm, multiselect } from "@clack/prompts";
|
|
241
|
-
import
|
|
345
|
+
import pc6 from "picocolors";
|
|
242
346
|
|
|
243
347
|
// src/installers/detect.ts
|
|
244
348
|
import { access } from "fs/promises";
|
|
@@ -425,8 +529,8 @@ async function promptInstall(install) {
|
|
|
425
529
|
}
|
|
426
530
|
await installToClient(client.id, client.configPath, install);
|
|
427
531
|
process.stdout.write(
|
|
428
|
-
`${
|
|
429
|
-
${
|
|
532
|
+
`${pc6.green("Installed")} ${client.label}
|
|
533
|
+
${pc6.dim(client.configPath)}
|
|
430
534
|
`
|
|
431
535
|
);
|
|
432
536
|
}
|
|
@@ -436,7 +540,7 @@ async function runInstallCommand(projectId) {
|
|
|
436
540
|
await ensureLoggedIn();
|
|
437
541
|
const detail = await apiFetch(`/api/cli/projects/${projectId}`);
|
|
438
542
|
if (!detail.install) {
|
|
439
|
-
process.stderr.write(`${
|
|
543
|
+
process.stderr.write(`${pc6.red("Project is not ready or missing install bundle.")}
|
|
440
544
|
`);
|
|
441
545
|
process.exitCode = 1;
|
|
442
546
|
return;
|
|
@@ -457,18 +561,18 @@ function sleep2(ms) {
|
|
|
457
561
|
function printStatus(detail) {
|
|
458
562
|
const { project } = detail;
|
|
459
563
|
process.stdout.write(
|
|
460
|
-
`\r${
|
|
564
|
+
`\r${pc7.cyan("Status:")} ${project.status.padEnd(12)} ${pc7.dim(project.name)}`
|
|
461
565
|
);
|
|
462
566
|
}
|
|
463
567
|
async function convertUrlToProject(sourceUrl, options = { offerInstall: true }) {
|
|
464
568
|
await ensureLoggedIn();
|
|
465
|
-
process.stdout.write(`${
|
|
569
|
+
process.stdout.write(`${pc7.bold("Converting")} ${sourceUrl}
|
|
466
570
|
`);
|
|
467
571
|
const created = await apiFetch("/api/cli/convert", {
|
|
468
572
|
method: "POST",
|
|
469
573
|
body: JSON.stringify({ sourceUrl })
|
|
470
574
|
});
|
|
471
|
-
process.stdout.write(`${
|
|
575
|
+
process.stdout.write(`${pc7.dim("Project:")} ${created.id}
|
|
472
576
|
`);
|
|
473
577
|
let delayMs = 2e3;
|
|
474
578
|
const terminal = /* @__PURE__ */ new Set(["ready", "error"]);
|
|
@@ -490,29 +594,29 @@ async function convertUrlToProject(sourceUrl, options = { offerInstall: true })
|
|
|
490
594
|
if (finalDetail.project.status === "error") {
|
|
491
595
|
const lastLog = finalDetail.project.logs.at(-1);
|
|
492
596
|
process.stderr.write(
|
|
493
|
-
`${
|
|
597
|
+
`${pc7.red("Conversion failed.")}${lastLog ? ` ${lastLog.message}` : ""}
|
|
494
598
|
`
|
|
495
599
|
);
|
|
496
600
|
process.exitCode = 1;
|
|
497
601
|
return null;
|
|
498
602
|
}
|
|
499
603
|
if (!finalDetail.mcp || !finalDetail.install) {
|
|
500
|
-
process.stderr.write(`${
|
|
604
|
+
process.stderr.write(`${pc7.red("MCP ready but missing install bundle.")}
|
|
501
605
|
`);
|
|
502
606
|
process.exitCode = 1;
|
|
503
607
|
return null;
|
|
504
608
|
}
|
|
505
609
|
process.stdout.write(`
|
|
506
|
-
${
|
|
610
|
+
${pc7.green("MCP ready")}
|
|
507
611
|
`);
|
|
508
|
-
process.stdout.write(`${
|
|
612
|
+
process.stdout.write(`${pc7.bold("Server:")} ${finalDetail.mcp.serverName}
|
|
509
613
|
`);
|
|
510
|
-
process.stdout.write(`${
|
|
614
|
+
process.stdout.write(`${pc7.bold("URL:")} ${finalDetail.mcp.url}
|
|
511
615
|
`);
|
|
512
|
-
process.stdout.write(`${
|
|
616
|
+
process.stdout.write(`${pc7.bold("Token:")} ${finalDetail.mcp.token}
|
|
513
617
|
`);
|
|
514
618
|
process.stdout.write(
|
|
515
|
-
`${
|
|
619
|
+
`${pc7.dim("Also listed in the doc2mcp marketplace when ready.")}
|
|
516
620
|
`
|
|
517
621
|
);
|
|
518
622
|
if (options.offerInstall) {
|
|
@@ -533,16 +637,16 @@ async function runList() {
|
|
|
533
637
|
await ensureLoggedIn();
|
|
534
638
|
const data = await apiFetch("/api/cli/projects");
|
|
535
639
|
if (data.projects.length === 0) {
|
|
536
|
-
process.stdout.write(`${
|
|
640
|
+
process.stdout.write(`${pc7.dim("No projects yet.")}
|
|
537
641
|
`);
|
|
538
642
|
return;
|
|
539
643
|
}
|
|
540
644
|
for (const project of data.projects) {
|
|
541
645
|
process.stdout.write(
|
|
542
|
-
`${
|
|
646
|
+
`${pc7.bold(project.name)} ${pc7.dim(`[${project.status}]`)} ${project.source}
|
|
543
647
|
`
|
|
544
648
|
);
|
|
545
|
-
process.stdout.write(` ${
|
|
649
|
+
process.stdout.write(` ${pc7.dim(project.id)} ${project.sourceUrl ?? ""}
|
|
546
650
|
`);
|
|
547
651
|
}
|
|
548
652
|
} catch (error) {
|
|
@@ -584,27 +688,27 @@ async function pickExistingProject() {
|
|
|
584
688
|
const ready = await listReadyProjects();
|
|
585
689
|
if (ready.length === 0) {
|
|
586
690
|
process.stdout.write(
|
|
587
|
-
`${
|
|
691
|
+
`${pc8.yellow("No ready MCP projects yet.")} Paste a docs URL to create one.
|
|
588
692
|
`
|
|
589
693
|
);
|
|
590
694
|
return null;
|
|
591
695
|
}
|
|
592
|
-
process.stdout.write(`${
|
|
696
|
+
process.stdout.write(`${pc8.dim("Ready MCPs")}
|
|
593
697
|
`);
|
|
594
698
|
ready.forEach((p, index) => {
|
|
595
699
|
process.stdout.write(
|
|
596
|
-
` ${
|
|
700
|
+
` ${pc8.cyan(String(index + 1).padStart(2, " "))}. ${pc8.bold(p.name)} ${pc8.dim(p.sourceUrl ?? p.id)}
|
|
597
701
|
`
|
|
598
702
|
);
|
|
599
703
|
});
|
|
600
704
|
const choice = await readLine(
|
|
601
|
-
`${
|
|
705
|
+
`${pc8.bold(">")} choose number, paste URL, or paste project id: `
|
|
602
706
|
);
|
|
603
707
|
if (!choice) {
|
|
604
708
|
return null;
|
|
605
709
|
}
|
|
606
710
|
if (isDocsUrl(choice)) {
|
|
607
|
-
return await convertUrlToProject(choice, { offerInstall:
|
|
711
|
+
return await convertUrlToProject(choice, { offerInstall: true });
|
|
608
712
|
}
|
|
609
713
|
const chosenIndex = Number(choice);
|
|
610
714
|
if (Number.isInteger(chosenIndex) && chosenIndex > 0) {
|
|
@@ -618,23 +722,21 @@ async function pickExistingProject() {
|
|
|
618
722
|
async function resolveProject(target) {
|
|
619
723
|
if (target) {
|
|
620
724
|
if (isDocsUrl(target)) {
|
|
621
|
-
return await convertUrlToProject(target, { offerInstall:
|
|
725
|
+
return await convertUrlToProject(target, { offerInstall: true });
|
|
622
726
|
}
|
|
623
727
|
return await apiFetch(`/api/cli/projects/${target}`);
|
|
624
728
|
}
|
|
625
|
-
process.stdout.write(`${pc6.bold("doc2mcp chat")}
|
|
626
|
-
`);
|
|
627
729
|
process.stdout.write(
|
|
628
|
-
`${
|
|
730
|
+
`${pc8.dim("Paste a docs URL to create a new MCP, a project id, or press Enter to pick an existing one.")}
|
|
629
731
|
|
|
630
732
|
`
|
|
631
733
|
);
|
|
632
|
-
const first = await readLine(`${
|
|
734
|
+
const first = await readLine(`${pc8.cyan("\u203A")} docs url or project id: `);
|
|
633
735
|
if (!first) {
|
|
634
736
|
return await pickExistingProject();
|
|
635
737
|
}
|
|
636
738
|
if (isDocsUrl(first)) {
|
|
637
|
-
return await convertUrlToProject(first, { offerInstall:
|
|
739
|
+
return await convertUrlToProject(first, { offerInstall: true });
|
|
638
740
|
}
|
|
639
741
|
return await apiFetch(`/api/cli/projects/${first}`);
|
|
640
742
|
}
|
|
@@ -669,26 +771,24 @@ async function askDocs(mcp, question) {
|
|
|
669
771
|
}
|
|
670
772
|
function renderAnswer(answer) {
|
|
671
773
|
process.stdout.write(`
|
|
672
|
-
${
|
|
774
|
+
${pc8.green("\u25CF")} ${pc8.bold("doc2mcp")}
|
|
775
|
+
|
|
673
776
|
`);
|
|
674
|
-
|
|
675
|
-
process.stdout.write(`${pc6.cyan("\u2502")} ${line}
|
|
777
|
+
process.stdout.write(`${renderMarkdown(answer.answer.trim())}
|
|
676
778
|
`);
|
|
677
|
-
}
|
|
678
779
|
if (answer.sources && answer.sources.length > 0) {
|
|
679
|
-
process.stdout.write(
|
|
680
|
-
${
|
|
780
|
+
process.stdout.write(`
|
|
781
|
+
${pc8.dim("Sources")}
|
|
681
782
|
`);
|
|
682
783
|
for (const source of answer.sources.slice(0, 6)) {
|
|
683
784
|
process.stdout.write(
|
|
684
|
-
|
|
785
|
+
` ${pc8.cyan("\u2022")} ${source.title}
|
|
786
|
+
${pc8.dim(source.url)}
|
|
685
787
|
`
|
|
686
788
|
);
|
|
687
789
|
}
|
|
688
790
|
}
|
|
689
|
-
process.stdout.write(
|
|
690
|
-
|
|
691
|
-
`);
|
|
791
|
+
process.stdout.write("\n");
|
|
692
792
|
}
|
|
693
793
|
async function answerOnce(mcp, question) {
|
|
694
794
|
const spinner = ora2("Thinking\u2026").start();
|
|
@@ -710,7 +810,7 @@ async function runChat(target, options = {}) {
|
|
|
710
810
|
}
|
|
711
811
|
if (!detail.mcp) {
|
|
712
812
|
process.stderr.write(
|
|
713
|
-
`${
|
|
813
|
+
`${pc8.red("That project is not ready yet.")} Check: ${pc8.bold("doc2mcp list")}
|
|
714
814
|
`
|
|
715
815
|
);
|
|
716
816
|
process.exitCode = 1;
|
|
@@ -721,21 +821,24 @@ async function runChat(target, options = {}) {
|
|
|
721
821
|
await answerOnce(mcp, options.message);
|
|
722
822
|
return;
|
|
723
823
|
}
|
|
824
|
+
printBanner();
|
|
825
|
+
const title = ` doc2mcp chat \xB7 ${detail.project.name} `;
|
|
826
|
+
const bar = "\u2500".repeat(title.length);
|
|
827
|
+
process.stdout.write(`
|
|
828
|
+
${pc8.cyan(`\u256D${bar}\u256E`)}
|
|
829
|
+
`);
|
|
830
|
+
process.stdout.write(`${pc8.cyan("\u2502")}${pc8.bold(title)}${pc8.cyan("\u2502")}
|
|
831
|
+
`);
|
|
832
|
+
process.stdout.write(`${pc8.cyan(`\u2570${bar}\u256F`)}
|
|
833
|
+
`);
|
|
724
834
|
process.stdout.write(
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
`
|
|
728
|
-
);
|
|
729
|
-
process.stdout.write(
|
|
730
|
-
`${pc6.cyan("\u2502")} ${pc6.dim("Ask anything about these docs. Type /exit to leave.")}
|
|
835
|
+
`${pc8.dim("Ask anything about these docs. Type /exit to quit.")}
|
|
836
|
+
|
|
731
837
|
`
|
|
732
838
|
);
|
|
733
|
-
process.stdout.write(`${pc6.cyan("\u2570")}
|
|
734
|
-
|
|
735
|
-
`);
|
|
736
839
|
let active = true;
|
|
737
840
|
while (active) {
|
|
738
|
-
const question = await readLine(`${
|
|
841
|
+
const question = await readLine(`${pc8.cyan("\u203A")} `);
|
|
739
842
|
if (question === null) {
|
|
740
843
|
active = false;
|
|
741
844
|
break;
|
|
@@ -750,8 +853,11 @@ ${pc6.cyan("\u256D\u2500")} ${pc6.bold(`Chatting with ${detail.project.name}`)}
|
|
|
750
853
|
}
|
|
751
854
|
await answerOnce(mcp, trimmed);
|
|
752
855
|
}
|
|
753
|
-
process.stdout.write(
|
|
754
|
-
`
|
|
856
|
+
process.stdout.write(
|
|
857
|
+
`
|
|
858
|
+
${pc8.dim("Bye \u2014 your docs MCP stays live for your editor.")}
|
|
859
|
+
`
|
|
860
|
+
);
|
|
755
861
|
} catch (error) {
|
|
756
862
|
printError(error);
|
|
757
863
|
process.exitCode = 1;
|
|
@@ -760,7 +866,7 @@ ${pc6.cyan("\u256D\u2500")} ${pc6.bold(`Chatting with ${detail.project.name}`)}
|
|
|
760
866
|
|
|
761
867
|
// src/index.ts
|
|
762
868
|
var program = new Command();
|
|
763
|
-
program.name("doc2mcp").description("Generate documentation MCP servers from your terminal").version("0.1.
|
|
869
|
+
program.name("doc2mcp").description("Generate documentation MCP servers from your terminal").version("0.1.20", "-v, --version", "Print the installed CLI version");
|
|
764
870
|
program.command("login").description("Authorize the CLI via browser").action(async () => {
|
|
765
871
|
await runLogin();
|
|
766
872
|
});
|
|
@@ -791,7 +897,7 @@ program.argument("[url]", "Documentation URL to convert").action(async (url) =>
|
|
|
791
897
|
}
|
|
792
898
|
} catch {
|
|
793
899
|
process.stderr.write(
|
|
794
|
-
`${
|
|
900
|
+
`${pc9.red("Error:")} Invalid URL. Example: doc2mcp https://docs.example.com
|
|
795
901
|
`
|
|
796
902
|
);
|
|
797
903
|
process.exitCode = 1;
|
|
@@ -801,7 +907,7 @@ program.argument("[url]", "Documentation URL to convert").action(async (url) =>
|
|
|
801
907
|
});
|
|
802
908
|
program.parseAsync(process.argv).catch((error) => {
|
|
803
909
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
804
|
-
process.stderr.write(`${
|
|
910
|
+
process.stderr.write(`${pc9.red("Error:")} ${message}
|
|
805
911
|
`);
|
|
806
912
|
process.exit(1);
|
|
807
913
|
});
|
package/package.json
CHANGED