bobs-workshop 0.3.2 → 3.1.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.
Files changed (200) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +199 -210
  3. package/bin/bobs-workshop.js +109 -0
  4. package/config/agents.json +27 -0
  5. package/dist/plugins/bobs-workshop.js +34 -0
  6. package/dist/tools/background-agent/cancel.d.ts +3 -0
  7. package/dist/tools/background-agent/cancel.d.ts.map +1 -0
  8. package/dist/tools/background-agent/cancel.js +52 -0
  9. package/dist/tools/background-agent/concurrency.d.ts +15 -0
  10. package/dist/tools/background-agent/concurrency.d.ts.map +1 -0
  11. package/dist/tools/background-agent/concurrency.js +61 -0
  12. package/dist/tools/background-agent/index.d.ts +8 -0
  13. package/dist/tools/background-agent/index.d.ts.map +1 -0
  14. package/dist/tools/background-agent/index.js +7 -0
  15. package/dist/tools/background-agent/launch.d.ts +6 -0
  16. package/dist/tools/background-agent/launch.d.ts.map +1 -0
  17. package/dist/tools/background-agent/launch.js +33 -0
  18. package/dist/tools/background-agent/list.d.ts +7 -0
  19. package/dist/tools/background-agent/list.d.ts.map +1 -0
  20. package/dist/tools/background-agent/list.js +40 -0
  21. package/dist/tools/background-agent/manager.d.ts +29 -0
  22. package/dist/tools/background-agent/manager.d.ts.map +1 -0
  23. package/dist/tools/background-agent/manager.js +377 -0
  24. package/dist/tools/background-agent/output.d.ts +3 -0
  25. package/dist/tools/background-agent/output.d.ts.map +1 -0
  26. package/dist/tools/background-agent/output.js +41 -0
  27. package/dist/tools/background-agent/types.d.ts +46 -0
  28. package/dist/tools/background-agent/types.d.ts.map +1 -0
  29. package/dist/tools/background-agent/types.js +1 -0
  30. package/dist/tools/index.d.ts +9 -0
  31. package/dist/tools/index.d.ts.map +1 -0
  32. package/dist/tools/index.js +8 -0
  33. package/dist/tools/manual/index.d.ts +3 -0
  34. package/dist/tools/manual/index.d.ts.map +1 -0
  35. package/dist/tools/manual/index.js +2 -0
  36. package/dist/tools/manual/manual-update.d.ts +4 -0
  37. package/dist/tools/manual/manual-update.d.ts.map +1 -0
  38. package/dist/tools/manual/manual-update.js +190 -0
  39. package/dist/tools/manual/verify-manual.d.ts +4 -0
  40. package/dist/tools/manual/verify-manual.d.ts.map +1 -0
  41. package/dist/tools/manual/verify-manual.js +46 -0
  42. package/package.json +35 -67
  43. package/postinstall.js +190 -0
  44. package/src/agents/alice.md +466 -0
  45. package/src/agents/bob-rev.md +493 -0
  46. package/src/agents/bob-send.md +277 -0
  47. package/src/agents/bob.md +442 -0
  48. package/src/agents/trace.md +451 -0
  49. package/src/plugins/bobs-workshop.ts +45 -0
  50. package/src/skills/api-patterns/SKILL.md +376 -0
  51. package/src/skills/architecture/SKILL.md +271 -0
  52. package/src/skills/bobs-workshop/performance/icon.svg +3 -0
  53. package/src/skills/brainstorming/SKILL.md +210 -0
  54. package/src/skills/clean-code/SKILL.md +151 -0
  55. package/src/skills/code-review-checklist/SKILL.md +220 -0
  56. package/src/skills/database-design/SKILL.md +271 -0
  57. package/src/skills/exploration/SKILL.md +257 -0
  58. package/src/skills/frontend-ui-ux/SKILL.md +78 -0
  59. package/src/skills/git-master/SKILL.md +1105 -0
  60. package/src/skills/performance/SKILL.md +144 -0
  61. package/src/skills/performance/icon.svg +3 -0
  62. package/src/skills/plan-writing/SKILL.md +225 -0
  63. package/src/skills/security/SKILL.md +410 -0
  64. package/src/skills/simplification/SKILL.md +238 -0
  65. package/src/skills/systematic-debugging/SKILL.md +175 -0
  66. package/src/skills/testing-patterns/SKILL.md +305 -0
  67. package/src/skills/verification/SKILL.md +286 -0
  68. package/src/tools/background-agent/cancel.ts +67 -0
  69. package/src/tools/background-agent/concurrency.ts +71 -0
  70. package/src/tools/background-agent/index.ts +7 -0
  71. package/src/tools/background-agent/launch.ts +39 -0
  72. package/src/tools/background-agent/list.ts +50 -0
  73. package/src/tools/background-agent/manager.ts +455 -0
  74. package/src/tools/background-agent/output.ts +57 -0
  75. package/src/tools/background-agent/types.ts +55 -0
  76. package/src/tools/index.ts +8 -0
  77. package/src/tools/manual/index.ts +2 -0
  78. package/src/tools/manual/manual-update.ts +197 -0
  79. package/src/tools/manual/verify-manual.ts +55 -0
  80. package/uninstall.js +64 -0
  81. package/Claude.md +0 -162
  82. package/bin/bobs-mcp-server.js +0 -11
  83. package/bin/bobs-mcp.js +0 -130
  84. package/dist/api/taskLogger.js +0 -106
  85. package/dist/api/taskLogger.js.map +0 -1
  86. package/dist/cli/checker.js +0 -401
  87. package/dist/cli/checker.js.map +0 -1
  88. package/dist/cli/cleanup.js +0 -131
  89. package/dist/cli/cleanup.js.map +0 -1
  90. package/dist/cli/debug.js +0 -157
  91. package/dist/cli/debug.js.map +0 -1
  92. package/dist/cli/health.js +0 -97
  93. package/dist/cli/health.js.map +0 -1
  94. package/dist/cli/setup.js +0 -81
  95. package/dist/cli/setup.js.map +0 -1
  96. package/dist/cli/workshop.js +0 -42
  97. package/dist/cli/workshop.js.map +0 -1
  98. package/dist/dashboard/server.js +0 -1203
  99. package/dist/dashboard/server.js.map +0 -1
  100. package/dist/index.js +0 -960
  101. package/dist/index.js.map +0 -1
  102. package/dist/prompts/architect.js +0 -221
  103. package/dist/prompts/architect.js.map +0 -1
  104. package/dist/prompts/debugger.js +0 -257
  105. package/dist/prompts/debugger.js.map +0 -1
  106. package/dist/prompts/engineer.js +0 -249
  107. package/dist/prompts/engineer.js.map +0 -1
  108. package/dist/prompts/orchestrator.js +0 -304
  109. package/dist/prompts/orchestrator.js.map +0 -1
  110. package/dist/prompts/reviewer.js +0 -289
  111. package/dist/prompts/reviewer.js.map +0 -1
  112. package/dist/services/activitySummarizer.js +0 -388
  113. package/dist/services/activitySummarizer.js.map +0 -1
  114. package/dist/services/changeValidator.js +0 -396
  115. package/dist/services/changeValidator.js.map +0 -1
  116. package/dist/services/claudeOrchestrator.js +0 -343
  117. package/dist/services/claudeOrchestrator.js.map +0 -1
  118. package/dist/services/fileMonitor.js +0 -250
  119. package/dist/services/fileMonitor.js.map +0 -1
  120. package/dist/services/implementationSummarizer.js +0 -306
  121. package/dist/services/implementationSummarizer.js.map +0 -1
  122. package/dist/services/liveMonitor.js +0 -315
  123. package/dist/services/liveMonitor.js.map +0 -1
  124. package/dist/services/mcpAuditLogger.js +0 -104
  125. package/dist/services/mcpAuditLogger.js.map +0 -1
  126. package/dist/services/mcpLogger.js +0 -223
  127. package/dist/services/mcpLogger.js.map +0 -1
  128. package/dist/services/tmuxManager.js +0 -541
  129. package/dist/services/tmuxManager.js.map +0 -1
  130. package/dist/tools/approvalTools.js +0 -244
  131. package/dist/tools/approvalTools.js.map +0 -1
  132. package/dist/tools/autoDebugger.js +0 -147
  133. package/dist/tools/autoDebugger.js.map +0 -1
  134. package/dist/tools/cleanupService.js +0 -221
  135. package/dist/tools/cleanupService.js.map +0 -1
  136. package/dist/tools/dashboardTools.js +0 -342
  137. package/dist/tools/dashboardTools.js.map +0 -1
  138. package/dist/tools/developmentNudges.js +0 -336
  139. package/dist/tools/developmentNudges.js.map +0 -1
  140. package/dist/tools/gitTools.js +0 -741
  141. package/dist/tools/gitTools.js.map +0 -1
  142. package/dist/tools/orchestratorTools.js +0 -832
  143. package/dist/tools/orchestratorTools.js.map +0 -1
  144. package/dist/tools/searchCache.js +0 -64
  145. package/dist/tools/searchCache.js.map +0 -1
  146. package/dist/tools/searchTools.js +0 -1107
  147. package/dist/tools/searchTools.js.map +0 -1
  148. package/dist/tools/semgrep-patterns.js +0 -296
  149. package/dist/tools/semgrep-patterns.js.map +0 -1
  150. package/dist/tools/specTools.js +0 -332
  151. package/dist/tools/specTools.js.map +0 -1
  152. package/dist/tools/structural/__tests__/orchestrator.test.js +0 -61
  153. package/dist/tools/structural/__tests__/orchestrator.test.js.map +0 -1
  154. package/dist/tools/structural/cache.js +0 -226
  155. package/dist/tools/structural/cache.js.map +0 -1
  156. package/dist/tools/structural/engines/python/index.js +0 -118
  157. package/dist/tools/structural/engines/python/index.js.map +0 -1
  158. package/dist/tools/structural/engines/typescript/__tests__/typescript-engine.test.js +0 -97
  159. package/dist/tools/structural/engines/typescript/__tests__/typescript-engine.test.js.map +0 -1
  160. package/dist/tools/structural/engines/typescript/analyzer.js +0 -433
  161. package/dist/tools/structural/engines/typescript/analyzer.js.map +0 -1
  162. package/dist/tools/structural/engines/typescript/index.js +0 -381
  163. package/dist/tools/structural/engines/typescript/index.js.map +0 -1
  164. package/dist/tools/structural/engines/typescript/utils.js +0 -279
  165. package/dist/tools/structural/engines/typescript/utils.js.map +0 -1
  166. package/dist/tools/structural/index.js +0 -248
  167. package/dist/tools/structural/index.js.map +0 -1
  168. package/dist/tools/structural/types.js +0 -18
  169. package/dist/tools/structural/types.js.map +0 -1
  170. package/dist/tools/tmuxTools.js +0 -100
  171. package/dist/tools/tmuxTools.js.map +0 -1
  172. package/dist/tools/workRecorder.js +0 -215
  173. package/dist/tools/workRecorder.js.map +0 -1
  174. package/dist/tools/worktreeTools.js +0 -705
  175. package/dist/tools/worktreeTools.js.map +0 -1
  176. package/dist/utils/__tests__/integration.test.js +0 -57
  177. package/dist/utils/__tests__/integration.test.js.map +0 -1
  178. package/dist/utils/__tests__/serverDetection.test.js +0 -151
  179. package/dist/utils/__tests__/serverDetection.test.js.map +0 -1
  180. package/dist/utils/errorHandling.js +0 -336
  181. package/dist/utils/errorHandling.js.map +0 -1
  182. package/dist/utils/processManager.js +0 -172
  183. package/dist/utils/processManager.js.map +0 -1
  184. package/dist/utils/reliability.js +0 -263
  185. package/dist/utils/reliability.js.map +0 -1
  186. package/dist/utils/responseFormatter.js +0 -250
  187. package/dist/utils/responseFormatter.js.map +0 -1
  188. package/dist/utils/serverDetection.js +0 -133
  189. package/dist/utils/serverDetection.js.map +0 -1
  190. package/dist/utils/specMigration.js +0 -105
  191. package/dist/utils/specMigration.js.map +0 -1
  192. package/dist/validation/schemas.js +0 -299
  193. package/dist/validation/schemas.js.map +0 -1
  194. package/public/.well-known/mcp/manifest.json +0 -473
  195. package/public/index.html +0 -3157
  196. package/public/index.html.backup +0 -2805
  197. package/public/index.html.backup2 +0 -1292
  198. package/scripts/cleanup-system-logs.ts +0 -121
  199. package/scripts/init-workspace.js +0 -63
  200. package/scripts/install-search-tools.js +0 -116
@@ -1,104 +0,0 @@
1
- // src/services/mcpAuditLogger.ts
2
- import { dashboardUpdateHandler } from "../tools/dashboardTools.js";
3
- export class McpAuditLogger {
4
- constructor() {
5
- this.activeCalls = new Map();
6
- }
7
- /**
8
- * Create a wrapper that automatically logs MCP tool calls to dashboard
9
- */
10
- withMcpAudit(toolName, handler) {
11
- return (async (args, extra) => {
12
- const callId = `${toolName}-${Date.now()}-${Math.random().toString(36).substring(7)}`;
13
- const audit = {
14
- toolName,
15
- startTime: Date.now(),
16
- parameters: args
17
- };
18
- // Extract spec_id if available from parameters
19
- if (args && typeof args === 'object' && 'spec_id' in args && args.spec_id) {
20
- audit.specId = args.spec_id;
21
- }
22
- this.activeCalls.set(callId, audit);
23
- // Log tool call start
24
- await this.sendDashboardUpdate(audit.specId || '', 'tool_call_started', {
25
- tool_name: toolName,
26
- call_id: callId,
27
- parameters: this.sanitizeParameters(audit.parameters)
28
- });
29
- try {
30
- const result = await handler(args, extra);
31
- // Update audit with success
32
- audit.endTime = Date.now();
33
- audit.result = result;
34
- // Log tool call completion
35
- await this.sendDashboardUpdate(audit.specId || '', 'tool_call_completed', {
36
- tool_name: toolName,
37
- call_id: callId,
38
- duration_ms: audit.endTime - audit.startTime,
39
- success: true
40
- });
41
- this.activeCalls.delete(callId);
42
- return result;
43
- }
44
- catch (error) {
45
- // Update audit with error
46
- audit.endTime = Date.now();
47
- audit.error = error instanceof Error ? error.message : String(error);
48
- // Log tool call error
49
- await this.sendDashboardUpdate(audit.specId || '', 'tool_call_failed', {
50
- tool_name: toolName,
51
- call_id: callId,
52
- duration_ms: audit.endTime - audit.startTime,
53
- error: audit.error
54
- });
55
- this.activeCalls.delete(callId);
56
- throw error;
57
- }
58
- });
59
- }
60
- /**
61
- * Get currently active tool calls
62
- */
63
- getActiveCalls() {
64
- return Array.from(this.activeCalls.values());
65
- }
66
- /**
67
- * Send dashboard update (non-blocking)
68
- */
69
- async sendDashboardUpdate(specId, event, data) {
70
- try {
71
- await dashboardUpdateHandler({
72
- spec_id: specId,
73
- event,
74
- data
75
- });
76
- }
77
- catch (error) {
78
- // Don't let dashboard update failures break the main workflow
79
- console.log(`MCP Audit dashboard update failed (non-blocking): [${specId}] ${event}`, error instanceof Error ? error.message : String(error));
80
- }
81
- }
82
- /**
83
- * Remove sensitive information from parameters before logging
84
- */
85
- sanitizeParameters(params) {
86
- if (!params || typeof params !== 'object') {
87
- return params;
88
- }
89
- const sanitized = { ...params };
90
- // Remove potentially sensitive fields
91
- const sensitiveKeys = ['password', 'token', 'secret', 'key', 'credential'];
92
- for (const key of sensitiveKeys) {
93
- if (key in sanitized) {
94
- sanitized[key] = '[REDACTED]';
95
- }
96
- }
97
- return sanitized;
98
- }
99
- }
100
- // Global instance
101
- export const mcpAuditLogger = new McpAuditLogger();
102
- // Export the wrapper function for easy use
103
- export const withMcpAudit = mcpAuditLogger.withMcpAudit.bind(mcpAuditLogger);
104
- //# sourceMappingURL=mcpAuditLogger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcpAuditLogger.js","sourceRoot":"","sources":["../../src/services/mcpAuditLogger.ts"],"names":[],"mappings":"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"}
@@ -1,223 +0,0 @@
1
- // src/services/mcpLogger.ts
2
- import { z } from "zod";
3
- import { EventEmitter } from "events";
4
- export class McpLogger {
5
- constructor() {
6
- this.currentLogLevel = "info";
7
- this.logBuffer = [];
8
- this.maxBufferSize = 1000;
9
- // Logical operations tracking
10
- this.activeOperations = new Map();
11
- this.eventEmitter = new EventEmitter();
12
- }
13
- initialize(server) {
14
- this.server = server;
15
- // Register logging/setLevel request handler using the correct method
16
- if (this.server && typeof this.server.setRequestHandler === 'function') {
17
- try {
18
- const loggingSetLevelSchema = z.object({
19
- method: z.literal("logging/setLevel"),
20
- params: z.object({
21
- level: z.enum(["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"])
22
- })
23
- });
24
- this.server.setRequestHandler(loggingSetLevelSchema, async (request) => {
25
- this.currentLogLevel = request.params.level;
26
- console.log(`MCP logging level set to: ${request.params.level}`);
27
- return {};
28
- });
29
- }
30
- catch (error) {
31
- console.warn("Failed to register MCP logging handler:", error);
32
- }
33
- }
34
- }
35
- shouldLog(level) {
36
- const levels = ["debug", "info", "notice", "warning", "error", "critical", "alert", "emergency"];
37
- const currentIndex = levels.indexOf(this.currentLogLevel);
38
- const messageIndex = levels.indexOf(level);
39
- return messageIndex >= currentIndex;
40
- }
41
- addToBuffer(entry) {
42
- this.logBuffer.push(entry);
43
- if (this.logBuffer.length > this.maxBufferSize) {
44
- this.logBuffer = this.logBuffer.slice(-this.maxBufferSize);
45
- }
46
- }
47
- async log(level, message, data, logger) {
48
- const entry = {
49
- level,
50
- logger,
51
- data: data ? { message, ...data } : { message },
52
- timestamp: new Date().toISOString()
53
- };
54
- // Always add to buffer for dashboard consumption
55
- this.addToBuffer(entry);
56
- // Send MCP notification if level meets threshold
57
- if (this.shouldLog(level) && this.server) {
58
- try {
59
- await this.server.notification({
60
- method: "notifications/message",
61
- params: {
62
- level,
63
- logger,
64
- data: entry.data
65
- }
66
- });
67
- }
68
- catch (error) {
69
- // Fallback to console if MCP notification fails
70
- console.log(`[${level.toUpperCase()}] ${logger || 'MCP'}: ${message}`, data || '');
71
- }
72
- }
73
- // Also log to console for development
74
- console.log(`[${level.toUpperCase()}] ${logger || 'MCP'}: ${message}`, data || '');
75
- }
76
- // Convenience methods for different log levels
77
- debug(message, data, logger) {
78
- return this.log("debug", message, data, logger);
79
- }
80
- info(message, data, logger) {
81
- return this.log("info", message, data, logger);
82
- }
83
- notice(message, data, logger) {
84
- return this.log("notice", message, data, logger);
85
- }
86
- warning(message, data, logger) {
87
- return this.log("warning", message, data, logger);
88
- }
89
- error(message, data, logger) {
90
- return this.log("error", message, data, logger);
91
- }
92
- critical(message, data, logger) {
93
- return this.log("critical", message, data, logger);
94
- }
95
- // Tool call logging helpers
96
- async logToolCall(toolName, params, specId) {
97
- return this.info(`Tool call started: ${toolName}`, {
98
- tool_name: toolName,
99
- spec_id: specId,
100
- parameters: this.sanitizeParams(params),
101
- event_type: 'tool_call_started'
102
- }, 'tool_tracker');
103
- }
104
- async logToolSuccess(toolName, duration, specId) {
105
- return this.info(`Tool call completed: ${toolName}`, {
106
- tool_name: toolName,
107
- spec_id: specId,
108
- duration_ms: duration,
109
- success: true,
110
- event_type: 'tool_call_completed'
111
- }, 'tool_tracker');
112
- }
113
- async logToolError(toolName, error, duration, specId) {
114
- return this.error(`Tool call failed: ${toolName}`, {
115
- tool_name: toolName,
116
- spec_id: specId,
117
- duration_ms: duration,
118
- success: false,
119
- error: error,
120
- event_type: 'tool_call_failed'
121
- }, 'tool_tracker');
122
- }
123
- // Get log buffer for dashboard consumption
124
- getLogs(specId) {
125
- if (specId) {
126
- return this.logBuffer.filter(entry => entry.data &&
127
- typeof entry.data === 'object' &&
128
- 'spec_id' in entry.data &&
129
- entry.data.spec_id === specId);
130
- }
131
- return [...this.logBuffer];
132
- }
133
- sanitizeParams(params) {
134
- if (!params || typeof params !== 'object') {
135
- return params;
136
- }
137
- const sanitized = { ...params };
138
- const sensitiveKeys = ['password', 'token', 'secret', 'key', 'credential'];
139
- for (const key of sensitiveKeys) {
140
- if (key in sanitized) {
141
- sanitized[key] = '[REDACTED]';
142
- }
143
- }
144
- return sanitized;
145
- }
146
- // Logical operation management
147
- async startLogicalOperation(type, specId, operation) {
148
- const operationId = `op_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
149
- const logicalOp = {
150
- id: operationId,
151
- type,
152
- timestamp: new Date().toISOString(),
153
- spec_id: specId,
154
- operation: operation || `Starting ${type}`,
155
- details: {},
156
- sub_events: []
157
- };
158
- this.activeOperations.set(operationId, logicalOp);
159
- this.eventEmitter.emit('logical_operation_start', logicalOp);
160
- // Also log to existing system
161
- await this.info(`🎯 ${logicalOp.operation}`, {
162
- operation_id: operationId,
163
- type,
164
- spec_id: specId,
165
- event_type: 'logical_operation_start'
166
- }, 'orchestrator');
167
- return operationId;
168
- }
169
- async addSubEvent(operationId, subEvent) {
170
- const operation = this.activeOperations.get(operationId);
171
- if (operation) {
172
- operation.sub_events.push(subEvent);
173
- this.eventEmitter.emit('logical_operation_update', operation);
174
- // Log sub-event
175
- await this.info(` └─ ${subEvent.event}`, {
176
- operation_id: operationId,
177
- sub_event: subEvent,
178
- event_type: 'logical_operation_update'
179
- }, 'orchestrator');
180
- }
181
- }
182
- async completeLogicalOperation(operationId, success = true) {
183
- const operation = this.activeOperations.get(operationId);
184
- if (operation) {
185
- operation.details.completed_at = new Date().toISOString();
186
- operation.details.success = success;
187
- this.eventEmitter.emit('logical_operation_complete', operation);
188
- // Log completion
189
- await this.info(`✅ Completed: ${operation.operation}`, {
190
- operation_id: operationId,
191
- success,
192
- duration_ms: new Date().getTime() - new Date(operation.timestamp).getTime(),
193
- event_type: 'logical_operation_complete'
194
- }, 'orchestrator');
195
- this.activeOperations.delete(operationId);
196
- }
197
- }
198
- async logRoleTransition(fromMode, toMode, specId, triggerReason) {
199
- const operationId = await this.startLogicalOperation('role_transition', specId, `🎯 Transitioning from ${fromMode} to ${toMode}`);
200
- await this.addSubEvent(operationId, {
201
- timestamp: new Date().toISOString(),
202
- event: 'mode_switch',
203
- details: {
204
- from_mode: fromMode,
205
- to_mode: toMode,
206
- trigger_reason: triggerReason
207
- }
208
- });
209
- await this.completeLogicalOperation(operationId, true);
210
- }
211
- getActiveOperationsForSpec(specId) {
212
- const activeOps = [];
213
- for (const [operationId, operation] of this.activeOperations.entries()) {
214
- if (operation.spec_id === specId) {
215
- activeOps.push(operationId);
216
- }
217
- }
218
- return activeOps;
219
- }
220
- }
221
- // Global instance
222
- export const mcpLogger = new McpLogger();
223
- //# sourceMappingURL=mcpLogger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcpLogger.js","sourceRoot":"","sources":["../../src/services/mcpLogger.ts"],"names":[],"mappings":"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"}