@dosu/cli 0.51.1 → 0.52.1

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.
Files changed (3) hide show
  1. package/README.md +0 -1
  2. package/bin/dosu.js +39 -153
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -115,7 +115,6 @@ Once authenticated against a deployment, you can drive the Dosu platform without
115
115
  | `dosu ask` | Ask a question and get an AI-generated answer |
116
116
  | `dosu knowledge` | Search and browse your knowledge base |
117
117
  | `dosu docs` | Manage documents (list, create, update, import, publish, AI-generate) |
118
- | `dosu suggest` | Review and manage AI document suggestions |
119
118
  | `dosu threads` | List and manage conversation threads |
120
119
  | `dosu review` | Document review workflow |
121
120
  | `dosu sources` | Manage connected data sources (list, sync, update) |
package/bin/dosu.js CHANGED
@@ -5000,7 +5000,7 @@ function isNpxInvocation(channel = INSTALL_CHANNEL, env = process.env) {
5000
5000
  function getVersionString() {
5001
5001
  return `v${VERSION}`;
5002
5002
  }
5003
- var VERSION = "0.51.1", INSTALL_CHANNEL = "npm";
5003
+ var VERSION = "0.52.1", INSTALL_CHANNEL = "npm";
5004
5004
 
5005
5005
  // src/debug/logger.ts
5006
5006
  import {
@@ -5134,7 +5134,7 @@ var init_logger = __esm(() => {
5134
5134
  });
5135
5135
 
5136
5136
  // src/client/contract.ts
5137
- var CLI_CONTRACT_HASH = "ac90a31489e1";
5137
+ var CLI_CONTRACT_HASH = "85b07f7689e2";
5138
5138
 
5139
5139
  // src/client/trpc.ts
5140
5140
  var exports_trpc = {};
@@ -11444,7 +11444,7 @@ var init_settings = __esm(() => {
11444
11444
  });
11445
11445
 
11446
11446
  // src/telemetry/debug-id.ts
11447
- var BUNDLE_DEBUG_ID_PLACEHOLDER = "06fcd05b-5d4d-0298-6475-6e2164756e21";
11447
+ var BUNDLE_DEBUG_ID_PLACEHOLDER = "61606b23-6c2b-78a9-6475-6e2164756e21";
11448
11448
 
11449
11449
  // src/telemetry/telemetry.ts
11450
11450
  import { randomUUID as randomUUID3 } from "node:crypto";
@@ -12401,9 +12401,6 @@ function binOnPath(bin) {
12401
12401
  return false;
12402
12402
  }
12403
12403
  }
12404
- function kickoffAgentLabel(agent) {
12405
- return AGENT_LABELS[agent];
12406
- }
12407
12404
  function cursorAgentBin() {
12408
12405
  if (binOnPath("agent"))
12409
12406
  return "agent";
@@ -12483,15 +12480,10 @@ function launchKickoffAgent(agent, prompt, options = {}) {
12483
12480
  logger.warn("setup", "No Cursor kickoff binary found");
12484
12481
  return false;
12485
12482
  }
12486
- var KICKOFF_AGENTS, AGENT_LABELS;
12483
+ var KICKOFF_AGENTS;
12487
12484
  var init_agent_kickoff = __esm(() => {
12488
12485
  init_logger();
12489
12486
  KICKOFF_AGENTS = ["cursor", "claude", "codex"];
12490
- AGENT_LABELS = {
12491
- cursor: "Cursor",
12492
- claude: "Claude Code",
12493
- codex: "Codex"
12494
- };
12495
12487
  });
12496
12488
 
12497
12489
  // src/setup/logs-handoff.ts
@@ -12587,8 +12579,8 @@ function printManualLogsNudge(opts = {}) {
12587
12579
  log.message(info(prompt));
12588
12580
  }
12589
12581
  function confirmLogsHandoffMessage(agent) {
12590
- const lead = agent === "cursor" && !cursorAgentBin() ? "We'll print a prompt to paste into Agent to mine these into Dosu. Cursor CLI isn't on PATH, so nothing runs until you send it." : `We'll hand off to ${kickoffAgentLabel(agent)} to mine these into Dosu.`;
12591
- return `${lead} ${LOGS_HANDOFF_PRIVACY}`;
12582
+ const lead = agent === "cursor" && !cursorAgentBin() ? "We'll print a prompt to paste into Agent to mine these into Dosu. Cursor CLI isn't on PATH, so nothing runs until you send it." : null;
12583
+ return lead ? `${lead} ${LOGS_HANDOFF_PRIVACY}` : LOGS_HANDOFF_PRIVACY;
12592
12584
  }
12593
12585
  async function offerLogsHandoff(options = {}) {
12594
12586
  const hits = detectLogSources(options.home);
@@ -14047,7 +14039,7 @@ __export(exports_tui, {
14047
14039
  handleLogout: () => handleLogout
14048
14040
  });
14049
14041
  async function runTUI() {
14050
- console.log(import_picocolors29.default.magenta(LOGO));
14042
+ console.log(import_picocolors28.default.magenta(LOGO));
14051
14043
  const cfg = loadConfig();
14052
14044
  while (true) {
14053
14045
  const insightsReady = Boolean(cfg.active_account?.target?.space_id && cfg.active_account?.target?.deployment_id && cfg.active_account?.target?.api_key);
@@ -14161,7 +14153,7 @@ function handleLogout(cfg) {
14161
14153
  saveConfig(cfg);
14162
14154
  log.success("Credentials cleared.");
14163
14155
  }
14164
- var import_picocolors29, LOGO = `
14156
+ var import_picocolors28, LOGO = `
14165
14157
  /$$$$$$$
14166
14158
  | $$__ $$
14167
14159
  | $$ \\ $$ /$$$$$$ /$$$$$$$ /$$ /$$
@@ -14178,7 +14170,7 @@ var init_tui = __esm(() => {
14178
14170
  init_config();
14179
14171
  init_flow2();
14180
14172
  init_styles();
14181
- import_picocolors29 = __toESM(require_picocolors(), 1);
14173
+ import_picocolors28 = __toESM(require_picocolors(), 1);
14182
14174
  });
14183
14175
 
14184
14176
  // src/auth/ticket.ts
@@ -16494,7 +16486,6 @@ var LIBRARY_VISIBILITIES = ["public", "internal", "private"];
16494
16486
  var CONFIG_SETTINGS = {
16495
16487
  commit_to_trigger_pr: true,
16496
16488
  default_accept_review: true,
16497
- default_save_publish: true,
16498
16489
  review_timeout_days: true
16499
16490
  };
16500
16491
  var CONFIG_SETTING_NAMES = Object.keys(CONFIG_SETTINGS);
@@ -17232,110 +17223,6 @@ function sourcesCommand() {
17232
17223
  return cmd;
17233
17224
  }
17234
17225
 
17235
- // src/commands/suggest.ts
17236
- init_commander();
17237
- var import_picocolors24 = __toESM(require_picocolors(), 1);
17238
-
17239
- // src/client/supabase.ts
17240
- async function listSpaceDataSourceIds(config, spaceId) {
17241
- const accessToken = config.active_account?.session.access_token;
17242
- if (!accessToken)
17243
- throw new Error("Not logged in. Run 'dosu login' first.");
17244
- const endpoint = new URL("/rest/v1/space_data_source", getSupabaseURL());
17245
- endpoint.searchParams.set("select", "data_source_id");
17246
- endpoint.searchParams.set("space_id", `eq.${spaceId}`);
17247
- const response = await fetch(endpoint, {
17248
- headers: {
17249
- apikey: getSupabaseAnonKey(),
17250
- Authorization: `Bearer ${accessToken}`
17251
- }
17252
- });
17253
- if (!response.ok) {
17254
- throw new Error(`Failed to list this deployment's data sources (status ${response.status}).`);
17255
- }
17256
- const rows = await response.json();
17257
- if (!Array.isArray(rows) || rows.some((row) => !isDataSourceLink(row))) {
17258
- throw new Error("Supabase returned an invalid space_data_source response.");
17259
- }
17260
- return rows.map((row) => row.data_source_id);
17261
- }
17262
- function isDataSourceLink(value) {
17263
- return value !== null && typeof value === "object" && "data_source_id" in value && typeof value.data_source_id === "string";
17264
- }
17265
-
17266
- // src/commands/suggest.ts
17267
- init_trpc();
17268
- function requireConfig12() {
17269
- const cfg = requireLoginConfig();
17270
- if (!cfg.active_account?.target?.space_id) {
17271
- console.error(import_picocolors24.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
17272
- process.exit(1);
17273
- }
17274
- return cfg;
17275
- }
17276
- async function getKnowledgeStoreId3(client, spaceId) {
17277
- const store = await client.knowledgeStore.getBySpaceId.query({
17278
- space_id: spaceId
17279
- });
17280
- if (!store) {
17281
- console.error(import_picocolors24.default.red("No knowledge store found for this deployment."));
17282
- process.exit(1);
17283
- }
17284
- return store.id;
17285
- }
17286
- function suggestCommand() {
17287
- const cmd = new Command("suggest").description("AI document suggestions");
17288
- cmd.command("list").description("List pending document suggestions").option("--json", "Output as JSON").action(async (opts) => {
17289
- const cfg = requireConfig12();
17290
- const client = createTypedClient(cfg);
17291
- const ksId = await getKnowledgeStoreId3(client, cfg.active_account.target.space_id);
17292
- const suggestions = await client.suggestedDoc.listForKnowledgeStore.query({
17293
- knowledgeStoreId: ksId
17294
- });
17295
- if (opts.json) {
17296
- printResult(suggestions, opts);
17297
- return;
17298
- }
17299
- if (!suggestions || suggestions.length === 0) {
17300
- console.log(import_picocolors24.default.dim("No pending suggestions."));
17301
- return;
17302
- }
17303
- printTable(["ID", "Title"], suggestions.map((s) => [
17304
- s.id.slice(0, 8),
17305
- s.title ?? "(untitled)"
17306
- ]), { rawData: suggestions });
17307
- });
17308
- cmd.command("generate").description("Generate new document suggestions from data sources").option("--json", "Output as JSON").action(async (opts) => {
17309
- const cfg = requireConfig12();
17310
- const client = createTypedClient(cfg);
17311
- const ksId = await getKnowledgeStoreId3(client, cfg.active_account.target.space_id);
17312
- const dataSourceIds = await listSpaceDataSourceIds(cfg, cfg.active_account.target.space_id);
17313
- if (dataSourceIds.length === 0) {
17314
- throw new Error("No data sources are connected to the active deployment.");
17315
- }
17316
- const result = await client.suggestedDoc.generate.mutate({
17317
- knowledgeStoreId: ksId,
17318
- dataSourceIds
17319
- });
17320
- if (opts.json) {
17321
- printResult(result, opts);
17322
- return;
17323
- }
17324
- console.log(import_picocolors24.default.green("Document suggestions are being generated."));
17325
- });
17326
- cmd.command("reject").description("Reject a suggestion").argument("<id>", "Suggestion ID").option("--json", "Output as JSON").action(async (id, opts) => {
17327
- const cfg = requireConfig12();
17328
- const client = createTypedClient(cfg);
17329
- await client.suggestedDoc.delete.mutate({ id });
17330
- if (opts.json) {
17331
- printResult({ success: true, id }, opts);
17332
- return;
17333
- }
17334
- console.log(import_picocolors24.default.green("Suggestion rejected."));
17335
- });
17336
- return cmd;
17337
- }
17338
-
17339
17226
  // src/commands/telemetry.ts
17340
17227
  init_commander();
17341
17228
  init_settings();
@@ -17404,11 +17291,11 @@ function telemetryCommand() {
17404
17291
  // src/commands/threads.ts
17405
17292
  init_commander();
17406
17293
  init_trpc();
17407
- var import_picocolors25 = __toESM(require_picocolors(), 1);
17408
- function requireConfig13() {
17294
+ var import_picocolors24 = __toESM(require_picocolors(), 1);
17295
+ function requireConfig12() {
17409
17296
  const cfg = requireLoginConfig();
17410
17297
  if (!cfg.active_account?.target?.space_id) {
17411
- console.error(import_picocolors25.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
17298
+ console.error(import_picocolors24.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
17412
17299
  process.exit(1);
17413
17300
  }
17414
17301
  return cfg;
@@ -17420,7 +17307,7 @@ function threadsCommand() {
17420
17307
  "resolved",
17421
17308
  "archived"
17422
17309
  ])).option("--search <query>", "Search threads").addOption(new Option("--limit <n>", "Maximum results (default: 20; max: 100)").argParser(positiveIntegerAtMost(100)).default(20)).option("--json", "Output as JSON").action(async (opts) => {
17423
- const cfg = requireConfig13();
17310
+ const cfg = requireConfig12();
17424
17311
  const client = createTypedClient(cfg);
17425
17312
  const input = {
17426
17313
  __testing_scope__: undefined,
@@ -17459,7 +17346,7 @@ function threadsCommand() {
17459
17346
  return;
17460
17347
  }
17461
17348
  if (!threads || threads.length === 0) {
17462
- console.log(import_picocolors25.default.dim("No threads found."));
17349
+ console.log(import_picocolors24.default.dim("No threads found."));
17463
17350
  return;
17464
17351
  }
17465
17352
  printTable(["ID", "Title", "Status", "Created"], threads.map((t2) => [
@@ -17470,7 +17357,7 @@ function threadsCommand() {
17470
17357
  ]), { rawData: threads });
17471
17358
  });
17472
17359
  cmd.command("get").description("View a thread and its messages").argument("<id>", "Thread ID").addOption(new Option("--limit <n>", "Number of messages to show (default: 20; -1 for all)").argParser(messageLimit).default(20)).option("--json", "Output as JSON").action(async (id, opts) => {
17473
- const cfg = requireConfig13();
17360
+ const cfg = requireConfig12();
17474
17361
  const client = createTypedClient(cfg);
17475
17362
  const [thread, messagesData] = await Promise.all([
17476
17363
  client.thread.get.query(id),
@@ -17484,10 +17371,10 @@ function threadsCommand() {
17484
17371
  return;
17485
17372
  }
17486
17373
  if (!thread) {
17487
- console.log(import_picocolors25.default.dim("Thread not found."));
17374
+ console.log(import_picocolors24.default.dim("Thread not found."));
17488
17375
  return;
17489
17376
  }
17490
- console.log(import_picocolors25.default.bold(thread.generated_title ?? "(untitled thread)"));
17377
+ console.log(import_picocolors24.default.bold(thread.generated_title ?? "(untitled thread)"));
17491
17378
  printInfo([
17492
17379
  ["ID", thread.id],
17493
17380
  ["Created", formatDate(thread.created_at)],
@@ -17498,13 +17385,13 @@ function threadsCommand() {
17498
17385
  if (messages && messages.length > 0) {
17499
17386
  const allMessages = messages.flatMap((group) => group.messages);
17500
17387
  console.log(`
17501
- ${import_picocolors25.default.bold("Messages")} (${allMessages.length})`);
17502
- console.log(import_picocolors25.default.dim("─".repeat(60)));
17388
+ ${import_picocolors24.default.bold("Messages")} (${allMessages.length})`);
17389
+ console.log(import_picocolors24.default.dim("─".repeat(60)));
17503
17390
  for (const msg of allMessages) {
17504
17391
  const role = msg.author_role ?? "unknown";
17505
17392
  const date = formatDate(msg.created_at);
17506
17393
  console.log(`
17507
- ${import_picocolors25.default.bold(role)} ${import_picocolors25.default.dim(date)}`);
17394
+ ${import_picocolors24.default.bold(role)} ${import_picocolors24.default.dim(date)}`);
17508
17395
  if (msg.body) {
17509
17396
  console.log(truncate(msg.body, 500));
17510
17397
  }
@@ -17512,14 +17399,14 @@ ${import_picocolors25.default.bold(role)} ${import_picocolors25.default.dim(date
17512
17399
  }
17513
17400
  });
17514
17401
  cmd.command("archive").description("Archive a thread").argument("<id>", "Thread ID").option("--json", "Output as JSON").action(async (id, opts) => {
17515
- const cfg = requireConfig13();
17402
+ const cfg = requireConfig12();
17516
17403
  const client = createTypedClient(cfg);
17517
17404
  await client.thread.archive.mutate({ threadId: id, archived: true });
17518
17405
  if (opts.json) {
17519
17406
  printResult({ success: true, id }, opts);
17520
17407
  return;
17521
17408
  }
17522
- console.log(import_picocolors25.default.green(`Thread ${id.slice(0, 8)} archived.`));
17409
+ console.log(import_picocolors24.default.green(`Thread ${id.slice(0, 8)} archived.`));
17523
17410
  });
17524
17411
  return cmd;
17525
17412
  }
@@ -17527,21 +17414,21 @@ ${import_picocolors25.default.bold(role)} ${import_picocolors25.default.dim(date
17527
17414
  // src/commands/topics.ts
17528
17415
  init_commander();
17529
17416
  init_trpc();
17530
- var import_picocolors26 = __toESM(require_picocolors(), 1);
17531
- function requireConfig14() {
17417
+ var import_picocolors25 = __toESM(require_picocolors(), 1);
17418
+ function requireConfig13() {
17532
17419
  const cfg = requireLoginConfig();
17533
17420
  if (!cfg.active_account?.target?.space_id) {
17534
- console.error(import_picocolors26.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
17421
+ console.error(import_picocolors25.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
17535
17422
  process.exit(1);
17536
17423
  }
17537
17424
  return cfg;
17538
17425
  }
17539
- async function getKnowledgeStoreId4(client, spaceId) {
17426
+ async function getKnowledgeStoreId3(client, spaceId) {
17540
17427
  const store = await client.knowledgeStore.getBySpaceId.query({
17541
17428
  space_id: spaceId
17542
17429
  });
17543
17430
  if (!store) {
17544
- console.error(import_picocolors26.default.red("No knowledge store found for this deployment."));
17431
+ console.error(import_picocolors25.default.red("No knowledge store found for this deployment."));
17545
17432
  process.exit(1);
17546
17433
  }
17547
17434
  return store.id;
@@ -17549,9 +17436,9 @@ async function getKnowledgeStoreId4(client, spaceId) {
17549
17436
  function topicsCommand() {
17550
17437
  const cmd = new Command("topics").description("Browse Topics in your knowledge base");
17551
17438
  cmd.command("list").description("List all topics").option("--json", "Output as JSON").action(async (opts) => {
17552
- const cfg = requireConfig14();
17439
+ const cfg = requireConfig13();
17553
17440
  const client = createTypedClient(cfg);
17554
- const ksId = await getKnowledgeStoreId4(client, cfg.active_account.target.space_id);
17441
+ const ksId = await getKnowledgeStoreId3(client, cfg.active_account.target.space_id);
17555
17442
  const topics = await client.topic.listTopicsByKnowledgeStore.query({
17556
17443
  knowledge_store_id: ksId
17557
17444
  });
@@ -17560,7 +17447,7 @@ function topicsCommand() {
17560
17447
  return;
17561
17448
  }
17562
17449
  if (!topics || topics.length === 0) {
17563
- console.log(import_picocolors26.default.dim("No topics found."));
17450
+ console.log(import_picocolors25.default.dim("No topics found."));
17564
17451
  return;
17565
17452
  }
17566
17453
  printTable(["ID", "Name", "Description"], topics.map((t2) => [
@@ -17570,9 +17457,9 @@ function topicsCommand() {
17570
17457
  ]), { rawData: topics });
17571
17458
  });
17572
17459
  cmd.command("pages").description("List pages with a specific topic").argument("<topic-id>", "Topic ID").option("--search <query>", "Search within the topic's pages").addOption(new Option("--limit <n>", "Maximum results").argParser(positiveInteger).default(10)).option("--json", "Output as JSON").action(async (topicId, opts) => {
17573
- const cfg = requireConfig14();
17460
+ const cfg = requireConfig13();
17574
17461
  const client = createTypedClient(cfg);
17575
- const ksId = await getKnowledgeStoreId4(client, cfg.active_account.target.space_id);
17462
+ const ksId = await getKnowledgeStoreId3(client, cfg.active_account.target.space_id);
17576
17463
  const result = await client.topic.getPagesByTopicId.query({
17577
17464
  knowledge_store_id: ksId,
17578
17465
  topic_id: topicId,
@@ -17585,7 +17472,7 @@ function topicsCommand() {
17585
17472
  return;
17586
17473
  }
17587
17474
  if (!pages || pages.length === 0) {
17588
- console.log(import_picocolors26.default.dim("No pages found with this topic."));
17475
+ console.log(import_picocolors25.default.dim("No pages found with this topic."));
17589
17476
  return;
17590
17477
  }
17591
17478
  printTable(["ID", "Title"], pages.map((p2) => [
@@ -17599,7 +17486,7 @@ function topicsCommand() {
17599
17486
  // src/commands/upgrade.ts
17600
17487
  init_commander();
17601
17488
  init_skill();
17602
- var import_picocolors27 = __toESM(require_picocolors(), 1);
17489
+ var import_picocolors26 = __toESM(require_picocolors(), 1);
17603
17490
  import { spawnSync as spawnSync2 } from "node:child_process";
17604
17491
  import { realpathSync } from "node:fs";
17605
17492
  import { homedir as homedir6 } from "node:os";
@@ -17768,7 +17655,7 @@ Could not update Dosu automatically.`);
17768
17655
  ${plan.manualCommand}`);
17769
17656
  return result.status && result.status > 0 ? result.status : 1;
17770
17657
  }
17771
- console.log(import_picocolors27.default.green(`
17658
+ console.log(import_picocolors26.default.green(`
17772
17659
  ✓ Update command completed.`));
17773
17660
  console.log('Run "dosu --version" to verify.');
17774
17661
  return 0;
@@ -17781,7 +17668,7 @@ async function completeUpgrade(channel = INSTALL_CHANNEL, options = {}) {
17781
17668
  try {
17782
17669
  const result = await installSkill();
17783
17670
  if (result.success) {
17784
- console.log(import_picocolors27.default.green("✓ Skills updated."));
17671
+ console.log(import_picocolors26.default.green("✓ Skills updated."));
17785
17672
  } else {
17786
17673
  console.error('Skills could not be refreshed. Run "dosu skill update" to retry.');
17787
17674
  }
@@ -17810,7 +17697,7 @@ init_skill_update_check();
17810
17697
  // src/version/update-check.ts
17811
17698
  init_config();
17812
17699
  init_logger();
17813
- var import_picocolors28 = __toESM(require_picocolors(), 1);
17700
+ var import_picocolors27 = __toESM(require_picocolors(), 1);
17814
17701
  import { existsSync as existsSync17, mkdirSync as mkdirSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "node:fs";
17815
17702
  import { join as join28 } from "node:path";
17816
17703
  var CACHE_FILENAME3 = "update-check.json";
@@ -17903,7 +17790,7 @@ function buildUpdateNotice(current, latest, channel, interactive, npx = false) {
17903
17790
  `└${horizontal}┘`
17904
17791
  ];
17905
17792
  return `
17906
- ${frameLines.map((line) => import_picocolors28.default.yellow(line)).join(`
17793
+ ${frameLines.map((line) => import_picocolors27.default.yellow(line)).join(`
17907
17794
  `)}
17908
17795
  `;
17909
17796
  }
@@ -18332,7 +18219,6 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
18332
18219
  program2.addCommand(orgCommand());
18333
18220
  program2.addCommand(reviewCommand());
18334
18221
  program2.addCommand(sourcesCommand());
18335
- program2.addCommand(suggestCommand());
18336
18222
  program2.addCommand(telemetryCommand());
18337
18223
  program2.addCommand(topicsCommand());
18338
18224
  program2.addCommand(threadsCommand());
@@ -18453,4 +18339,4 @@ execute().catch((err) => {
18453
18339
  process.exit(1);
18454
18340
  });
18455
18341
 
18456
- //# debugId=06fcd05b-5d4d-0298-6475-6e2164756e21
18342
+ //# debugId=61606b23-6c2b-78a9-6475-6e2164756e21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.51.1",
3
+ "version": "0.52.1",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",