@bike4mind/cli 0.2.13 → 0.2.14-feat-cli-mcp-management.17477

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.
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- Logger
4
- } from "./chunk-OCYRD7D6.js";
5
2
  import {
6
3
  BedrockEmbeddingModel,
7
4
  ChatModels,
@@ -17,6 +14,9 @@ import {
17
14
  extractSnippetMeta,
18
15
  settingsMap
19
16
  } from "./chunk-A7POWM75.js";
17
+ import {
18
+ Logger
19
+ } from "./chunk-OCYRD7D6.js";
20
20
 
21
21
  // ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
22
22
  import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
@@ -8069,7 +8069,7 @@ function extractQuestMasterData(reply, options = {}) {
8069
8069
  }
8070
8070
 
8071
8071
  // ../../b4m-core/packages/utils/dist/src/questMasterToolSchema.js
8072
- var MAX_GOAL_LENGTH = 500;
8072
+ var MAX_GOAL_LENGTH = 1e3;
8073
8073
  var MAX_TITLE_LENGTH = 200;
8074
8074
  var MAX_DESCRIPTION_LENGTH = 2e3;
8075
8075
  var MAX_TAG_LENGTH = 50;
@@ -8093,11 +8093,22 @@ var createQuestPlanToolSchema = {
8093
8093
  GUIDELINES:
8094
8094
  - Analyze the user's request and create 3-7 main quests
8095
8095
  - Each quest must have 2-5 specific, actionable subquests
8096
- - Quest titles should be clear and action-oriented (e.g., "Set up database schema" not "Step 1")
8096
+ - Quest titles should be clear and action-oriented
8097
8097
  - Provide detailed descriptions for each quest
8098
8098
  - Assess complexity accurately: Easy (< 1 hour), Medium (1-4 hours), Hard (> 4 hours)
8099
8099
  - Generate 2-5 relevant tags categorizing the work (e.g., "web-development", "database", "api")
8100
8100
 
8101
+ TITLE REQUIREMENTS (CRITICAL):
8102
+ - NEVER use generic titles like "Step 1", "Step 2", "Task 1", "Subtask 1", "Part A"
8103
+ - ALWAYS use descriptive, action-oriented titles
8104
+ - Good: "Configure authentication middleware", "Set up database connection pooling"
8105
+ - Bad: "Step 1", "Subtask 2", "Task A"
8106
+
8107
+ HANDLING VERBOSE INPUT:
8108
+ - Extract the core objective and key requirements from detailed input
8109
+ - Summarize and structure appropriately rather than incorporating every detail
8110
+ - Focus on actionable steps
8111
+
8101
8112
  ALWAYS call this function to respond. Do NOT respond with plain text.`,
8102
8113
  parameters: {
8103
8114
  type: "object",
@@ -8377,8 +8388,7 @@ var QuestMaster = class {
8377
8388
  if (extracted.length > 0) {
8378
8389
  this.logger.log("Successfully extracted QuestMaster data:", extracted);
8379
8390
  await this.onStatusUpdate(this.quest, "Extracted QuestMaster data");
8380
- const validQuests = extracted.filter((quest) => quest !== null && typeof quest === "object" && quest.id && quest.title && quest.title !== "Step 1" && // Explicitly filter out generic Step 1
8381
- quest.description && quest.description !== "No description available");
8391
+ const validQuests = extracted.filter((quest) => quest !== null && typeof quest === "object" && quest.id && quest.title && quest.description);
8382
8392
  if (validQuests.length === 0) {
8383
8393
  throw new Error("No valid quests found after filtering");
8384
8394
  }
@@ -8398,7 +8408,8 @@ var QuestMaster = class {
8398
8408
  // No fallback - we filtered for valid descriptions
8399
8409
  complexity: quest.complexity || "Medium",
8400
8410
  status: "not_started",
8401
- subQuests: Array.isArray(quest.subQuests) ? quest.subQuests.filter((sub) => sub && sub.id && sub.title && !sub.title.startsWith("Subtask")).map((sub) => ({
8411
+ // Validate basic subquest structure - must have id and title
8412
+ subQuests: Array.isArray(quest.subQuests) ? quest.subQuests.filter((sub) => sub && sub.id && sub.title).map((sub) => ({
8402
8413
  id: sub.id,
8403
8414
  title: sub.title,
8404
8415
  status: "not_started"
@@ -8412,7 +8423,7 @@ var QuestMaster = class {
8412
8423
  try {
8413
8424
  const questPlan = JSON.parse(questPlanText);
8414
8425
  if (questPlan && questPlan.questChain && Array.isArray(questPlan.questChain)) {
8415
- const validQuestChain = questPlan.questChain.filter((item) => item && item.quest && item.quest !== "Step 1" && item.details && item.details !== "No description available");
8426
+ const validQuestChain = questPlan.questChain.filter((item) => item && item.quest && item.details);
8416
8427
  if (validQuestChain.length === 0) {
8417
8428
  throw new Error("No valid quests found in quest chain");
8418
8429
  }
@@ -8433,8 +8444,8 @@ var QuestMaster = class {
8433
8444
  }))
8434
8445
  };
8435
8446
  } else {
8436
- if (!questPlanText.trim() || questPlanText.trim() === "Step 1") {
8437
- throw new Error("Empty or invalid response received");
8447
+ if (!questPlanText.trim()) {
8448
+ throw new Error("Empty response received");
8438
8449
  }
8439
8450
  questResponse = {
8440
8451
  type: "narrative",
@@ -8644,7 +8655,7 @@ var QuestMaster = class {
8644
8655
  {
8645
8656
  "id": "${questId}",
8646
8657
  "title": "Process Request",
8647
- "description": "${text.substring(0, 500).replace(/"/g, '\\"')}",
8658
+ "description": "${text.substring(0, 1e3).replace(/"/g, '\\"')}",
8648
8659
  "complexity": "Medium",
8649
8660
  "status": "Not Started",
8650
8661
  "subQuests": [
@@ -8689,10 +8700,21 @@ Do NOT respond with plain text - ALWAYS use the function call.
8689
8700
  Guidelines:
8690
8701
  - Break down complex tasks into 3-7 main quests
8691
8702
  - Each quest needs 2-5 specific, actionable subquests
8692
- - Make titles clear and action-oriented (e.g., "Set up database schema" not "Step 1")
8703
+ - Make titles clear and action-oriented
8693
8704
  - Provide detailed descriptions explaining what needs to be done
8694
8705
  - Assess complexity accurately: Easy (< 1 hour), Medium (1-4 hours), Hard (> 4 hours)
8695
- - Generate 2-5 relevant tags categorizing the work`
8706
+ - Generate 2-5 relevant tags categorizing the work
8707
+
8708
+ TITLE REQUIREMENTS (CRITICAL):
8709
+ - NEVER use generic titles like "Step 1", "Step 2", "Task 1", "Subtask 1", "Part A"
8710
+ - ALWAYS use descriptive, action-oriented titles that explain what the step accomplishes
8711
+ - Good examples: "Configure authentication middleware", "Set up database connection pooling"
8712
+ - Bad examples: "Step 1", "Subtask 2", "Task A", "Part 1"
8713
+
8714
+ HANDLING VERBOSE INPUT:
8715
+ - When given detailed or verbose input, extract the core objective and key requirements
8716
+ - Do not try to incorporate every detail verbatim - summarize and structure appropriately
8717
+ - Focus on actionable steps rather than preserving all user context`
8696
8718
  },
8697
8719
  { role: "user", content: prompt }
8698
8720
  ];
@@ -8818,9 +8840,19 @@ IMPORTANT GUIDELINES:
8818
8840
  6. ALWAYS include relevant subquests - do not create empty subQuests arrays
8819
8841
  7. Maintain exact JSON structure
8820
8842
  8. No text between comment tags and JSON
8821
- 9. Never create generic "Step 1" quests - be specific and descriptive
8822
- 10. Each quest should have 2-5 concrete subquests that break down the work
8823
- 11. Generate 2-5 relevant tags that categorize this quest (e.g., "web-development", "react", "database", "ui-design", "api", "testing", "documentation")
8843
+ 9. Each quest should have 2-5 concrete subquests that break down the work
8844
+ 10. Generate 2-5 relevant tags that categorize this quest (e.g., "web-development", "react", "database", "ui-design", "api", "testing", "documentation")
8845
+
8846
+ TITLE REQUIREMENTS (CRITICAL):
8847
+ - NEVER use generic titles like "Step 1", "Step 2", "Task 1", "Subtask 1", "Part A"
8848
+ - ALWAYS use descriptive, action-oriented titles that explain what the step accomplishes
8849
+ - Good examples: "Configure authentication middleware", "Set up database connection pooling"
8850
+ - Bad examples: "Step 1", "Subtask 2", "Task A", "Part 1"
8851
+
8852
+ HANDLING VERBOSE INPUT:
8853
+ - When given detailed or verbose input, extract the core objective and key requirements
8854
+ - Do not try to incorporate every detail verbatim - summarize and structure appropriately
8855
+ - Focus on actionable steps rather than preserving all user context
8824
8856
 
8825
8857
  Remember:
8826
8858
  - The goal field in QuestMasterMeta is crucial for UI display
@@ -10868,6 +10900,13 @@ export {
10868
10900
  sendToConnection,
10869
10901
  ClientMessageSender,
10870
10902
  OpenaiModerationsService,
10903
+ MAX_GOAL_LENGTH,
10904
+ MAX_TITLE_LENGTH,
10905
+ MAX_DESCRIPTION_LENGTH,
10906
+ MAX_TAG_LENGTH,
10907
+ MAX_QUESTS,
10908
+ MAX_SUBQUESTS_PER_QUEST,
10909
+ MAX_TAGS,
10871
10910
  isGPT5ModelWithToolSupport,
10872
10911
  createQuestPlanToolSchema,
10873
10912
  parseQuestPlanFunctionCall,
File without changes
@@ -6,7 +6,7 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-SZXO7HOF.js";
9
+ } from "./chunk-GFL7CMSL.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BadRequestError,
4
4
  secureParameters
5
- } from "./chunk-SZXO7HOF.js";
5
+ } from "./chunk-GFL7CMSL.js";
6
6
  import {
7
7
  CompletionApiUsageTransaction,
8
8
  GenericCreditDeductTransaction,
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ConfigStore
4
+ } from "../chunk-FFJX3FF3.js";
5
+
6
+ // src/commands/mcpCommand.ts
7
+ async function handleMcpCommand(subcommand, argv) {
8
+ const configStore = new ConfigStore();
9
+ const config = await configStore.load();
10
+ switch (subcommand) {
11
+ case "list":
12
+ await handleList(config);
13
+ break;
14
+ case "add": {
15
+ if (!argv.name) {
16
+ console.error("\u274C Usage: b4m mcp add <name> -- <command> [args...]");
17
+ console.error("");
18
+ console.error("The -- separator is required to separate the server name from the command.");
19
+ console.error("");
20
+ console.error("Examples:");
21
+ console.error(" b4m mcp add context7 -- npx -y @upstash/context7-mcp");
22
+ console.error(" b4m mcp add github -- docker run -i ghcr.io/modelcontextprotocol/servers/github");
23
+ process.exit(1);
24
+ }
25
+ const dashDashIndex = process.argv.indexOf("--");
26
+ if (dashDashIndex === -1) {
27
+ console.error("\u274C Missing -- separator");
28
+ console.error("");
29
+ console.error("Usage: b4m mcp add <name> -- <command> [args...]");
30
+ console.error("");
31
+ console.error("The -- separator is required to separate the server name from the command.");
32
+ process.exit(1);
33
+ }
34
+ const commandParts = process.argv.slice(dashDashIndex + 1);
35
+ if (commandParts.length === 0) {
36
+ console.error("\u274C No command specified after --");
37
+ console.error("");
38
+ console.error("Usage: b4m mcp add <name> -- <command> [args...]");
39
+ process.exit(1);
40
+ }
41
+ const command = commandParts[0];
42
+ const args = commandParts.slice(1);
43
+ await handleAdd(config, argv.name, command, args, configStore);
44
+ break;
45
+ }
46
+ case "remove":
47
+ if (!argv.name) {
48
+ console.error("\u274C Usage: b4m mcp remove <name>");
49
+ process.exit(1);
50
+ }
51
+ await handleRemove(config, argv.name, configStore);
52
+ break;
53
+ case "enable":
54
+ if (!argv.name) {
55
+ console.error("\u274C Usage: b4m mcp enable <name>");
56
+ process.exit(1);
57
+ }
58
+ await handleEnable(config, argv.name, configStore);
59
+ break;
60
+ case "disable":
61
+ if (!argv.name) {
62
+ console.error("\u274C Usage: b4m mcp disable <name>");
63
+ process.exit(1);
64
+ }
65
+ await handleDisable(config, argv.name, configStore);
66
+ break;
67
+ default:
68
+ console.error(`\u274C Unknown MCP subcommand: ${subcommand}`);
69
+ console.error("");
70
+ console.error("Available commands:");
71
+ console.error(" b4m mcp list - List configured MCP servers");
72
+ console.error(" b4m mcp add <name> -- <command> - Add a new MCP server");
73
+ console.error(" b4m mcp remove <name> - Remove an MCP server");
74
+ console.error(" b4m mcp enable <name> - Enable an MCP server");
75
+ console.error(" b4m mcp disable <name> - Disable an MCP server");
76
+ process.exit(1);
77
+ }
78
+ }
79
+ async function handleList(config) {
80
+ if (config.mcpServers.length === 0) {
81
+ console.log("\u{1F4E1} No MCP servers configured.");
82
+ console.log("");
83
+ console.log("To add an MCP server:");
84
+ console.log(" b4m mcp add <name> -- <command> [args...]");
85
+ console.log("");
86
+ console.log("Examples:");
87
+ console.log(" b4m mcp add context7 -- npx -y @upstash/context7-mcp");
88
+ console.log(" b4m mcp add github -- docker run -i ghcr.io/modelcontextprotocol/servers/github");
89
+ return;
90
+ }
91
+ console.log("\u{1F4E1} Configured MCP Servers:\n");
92
+ for (const server of config.mcpServers) {
93
+ const status = server.enabled ? "\u2705 Enabled" : "\u23F8\uFE0F Disabled";
94
+ const commandInfo = server.command ? `${server.command} ${(server.args || []).join(" ")}` : "(internal)";
95
+ console.log(`\u2022 ${server.name} - ${status}`);
96
+ console.log(` Command: ${commandInfo}`);
97
+ if (Object.keys(server.env).length > 0) {
98
+ const envKeys = Object.keys(server.env).join(", ");
99
+ console.log(` Env vars: ${envKeys}`);
100
+ }
101
+ console.log("");
102
+ }
103
+ console.log("To manage servers:");
104
+ console.log(" b4m mcp add <name> -- <command> [args...] - Add server");
105
+ console.log(" b4m mcp remove <name> - Remove server");
106
+ console.log(" b4m mcp enable <name> - Enable server");
107
+ console.log(" b4m mcp disable <name> - Disable server");
108
+ }
109
+ async function handleAdd(config, name, command, args, configStore) {
110
+ const existing = config.mcpServers.find((s) => s.name === name);
111
+ if (existing) {
112
+ console.error(`\u274C MCP server "${name}" already exists.`);
113
+ console.error(' Use "b4m mcp remove" first to replace it.');
114
+ process.exit(1);
115
+ }
116
+ if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
117
+ console.error("\u274C Server name must contain only alphanumeric characters, dashes, and underscores.");
118
+ process.exit(1);
119
+ }
120
+ const newServer = {
121
+ name,
122
+ command,
123
+ args,
124
+ env: {},
125
+ enabled: true
126
+ };
127
+ config.mcpServers.push(newServer);
128
+ try {
129
+ await configStore.save(config);
130
+ console.log(`\u2705 Added MCP server "${name}"`);
131
+ console.log("");
132
+ console.log("Configuration saved to: ~/.bike4mind/config.json");
133
+ console.log("");
134
+ console.log("The server will be available next time you start the CLI.");
135
+ } catch (error) {
136
+ console.error(`\u274C Failed to save configuration:`, error instanceof Error ? error.message : String(error));
137
+ process.exit(1);
138
+ }
139
+ }
140
+ async function handleRemove(config, name, configStore) {
141
+ const index = config.mcpServers.findIndex((s) => s.name === name);
142
+ if (index === -1) {
143
+ console.error(`\u274C MCP server "${name}" not found.`);
144
+ process.exit(1);
145
+ }
146
+ config.mcpServers.splice(index, 1);
147
+ try {
148
+ await configStore.save(config);
149
+ console.log(`\u2705 Removed MCP server "${name}"`);
150
+ console.log("");
151
+ console.log("Configuration saved to: ~/.bike4mind/config.json");
152
+ } catch (error) {
153
+ console.error(`\u274C Failed to save configuration:`, error instanceof Error ? error.message : String(error));
154
+ process.exit(1);
155
+ }
156
+ }
157
+ async function handleEnable(config, name, configStore) {
158
+ const server = config.mcpServers.find((s) => s.name === name);
159
+ if (!server) {
160
+ console.error(`\u274C MCP server "${name}" not found.`);
161
+ process.exit(1);
162
+ }
163
+ if (server.enabled) {
164
+ console.log(`\u2139\uFE0F MCP server "${name}" is already enabled.`);
165
+ return;
166
+ }
167
+ server.enabled = true;
168
+ try {
169
+ await configStore.save(config);
170
+ console.log(`\u2705 Enabled MCP server "${name}"`);
171
+ console.log("");
172
+ console.log("The server will connect next time you start the CLI.");
173
+ } catch (error) {
174
+ console.error(`\u274C Failed to save configuration:`, error instanceof Error ? error.message : String(error));
175
+ process.exit(1);
176
+ }
177
+ }
178
+ async function handleDisable(config, name, configStore) {
179
+ const server = config.mcpServers.find((s) => s.name === name);
180
+ if (!server) {
181
+ console.error(`\u274C MCP server "${name}" not found.`);
182
+ process.exit(1);
183
+ }
184
+ if (!server.enabled) {
185
+ console.log(`\u2139\uFE0F MCP server "${name}" is already disabled.`);
186
+ return;
187
+ }
188
+ server.enabled = false;
189
+ try {
190
+ await configStore.save(config);
191
+ console.log(`\u2705 Disabled MCP server "${name}"`);
192
+ console.log("");
193
+ console.log("The server will not connect next time you start the CLI.");
194
+ } catch (error) {
195
+ console.error(`\u274C Failed to save configuration:`, error instanceof Error ? error.message : String(error));
196
+ process.exit(1);
197
+ }
198
+ }
199
+ export {
200
+ handleMcpCommand
201
+ };
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-K44CDTQN.js";
6
- import "./chunk-SZXO7HOF.js";
7
- import "./chunk-OCYRD7D6.js";
5
+ } from "./chunk-B6HTF2IE.js";
6
+ import "./chunk-GFL7CMSL.js";
8
7
  import "./chunk-A7POWM75.js";
8
+ import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  createFabFile,
11
11
  createFabFileSchema
File without changes