@debugg-ai/debugg-ai-mcp 1.0.50 → 1.0.52

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.
@@ -15,7 +15,7 @@ export function detectRepoName() {
15
15
  try {
16
16
  const raw = execSync('git remote get-url origin', {
17
17
  encoding: 'utf-8',
18
- timeout: 5000,
18
+ timeout: 2000,
19
19
  stdio: ['ignore', 'pipe', 'ignore'],
20
20
  }).trim();
21
21
  cached = parseRepoName(raw);
@@ -23,14 +23,16 @@ const createLogger = () => {
23
23
  stderrLevels: ['error', 'warn', 'info', 'debug'],
24
24
  }),
25
25
  ],
26
- // Ensure uncaught exceptions and rejections are logged
26
+ // Ensure uncaught exceptions and rejections go to stderr (NOT stdout — stdout is the MCP transport)
27
27
  exceptionHandlers: [
28
28
  new winston.transports.Console({
29
+ stderrLevels: ['error', 'warn', 'info', 'debug'],
29
30
  format: winston.format.combine(winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json()),
30
31
  }),
31
32
  ],
32
33
  rejectionHandlers: [
33
34
  new winston.transports.Console({
35
+ stderrLevels: ['error', 'warn', 'info', 'debug'],
34
36
  format: winston.format.combine(winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json()),
35
37
  }),
36
38
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@debugg-ai/debugg-ai-mcp",
3
- "version": "1.0.50",
3
+ "version": "1.0.52",
4
4
  "description": "Zero-Config, Fully AI-Managed End-to-End Testing for all code gen platforms.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,198 +0,0 @@
1
- import { existsSync, promises } from 'fs';
2
- import { join, dirname } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { isError } from './error.js';
5
- const { readFile } = promises;
6
- import { mkdirp } from 'mkdirp';
7
- import { authtoken, connect, disconnect, getApi, kill } from 'ngrok';
8
- import download from 'ngrok/download';
9
- import { parse } from 'yaml';
10
- // ES module compatible __dirname
11
- const __filename = fileURLToPath(import.meta.url);
12
- const __dirname = dirname(__filename);
13
- // Use empty string to let ngrok use its default binary location
14
- const basePath = '';
15
- export const binPath = () => basePath;
16
- const DEFAULT_CONFIG_PATH = join(__dirname, 'ngrok-config.yml');
17
- const getConfigPath = () => {
18
- return DEFAULT_CONFIG_PATH;
19
- };
20
- const getConfig = async () => {
21
- const configPath = getConfigPath();
22
- try {
23
- const config = parse(await readFile(configPath, 'utf8'));
24
- if (config && typeof config.authtoken !== 'undefined') {
25
- await authtoken({ authtoken: config.authtoken, binPath });
26
- }
27
- return config;
28
- }
29
- catch (error) {
30
- if (isError(error) && error.code === 'ENOENT') {
31
- if (configPath !== DEFAULT_CONFIG_PATH) {
32
- console.error(`Could not find config file at ${configPath}.`);
33
- error.message = `Could not find config file at ${configPath}`;
34
- throw error;
35
- }
36
- }
37
- else {
38
- console.error(`Could not parse config file at ${configPath}.`);
39
- throw error;
40
- }
41
- }
42
- };
43
- const tunnelsFromConfig = (tunnels) => {
44
- return Object.keys(tunnels).map((tunnelName) => {
45
- return {
46
- label: tunnelName,
47
- tunnelOptions: { name: tunnelName, ...tunnels[tunnelName] },
48
- };
49
- });
50
- };
51
- const getActiveTunnels = async (api) => {
52
- const response = await api.listTunnels();
53
- return response.tunnels;
54
- };
55
- export const start = async (options) => {
56
- const config = await getConfig();
57
- const tunnel = options;
58
- if (typeof tunnel !== 'undefined') {
59
- const configPath = getConfigPath();
60
- if (existsSync(configPath)) {
61
- tunnel.configPath = configPath;
62
- }
63
- try {
64
- // Let ngrok use default binPath if ours is empty
65
- if (basePath) {
66
- tunnel.binPath = binPath;
67
- }
68
- try {
69
- const url = await connect(tunnel);
70
- return url;
71
- }
72
- catch (error) {
73
- if (isError(error)) {
74
- error.message = `There was an error starting your tunnel.`;
75
- }
76
- console.error(`There was an error starting your tunnel.`);
77
- throw error;
78
- }
79
- }
80
- catch (error) {
81
- if (isError(error)) {
82
- error.message = `There was an error finding the bin path.`;
83
- }
84
- console.error(`There was an error finding the bin path.`);
85
- throw error;
86
- }
87
- }
88
- return null;
89
- };
90
- export const stop = async (tunnel) => {
91
- const api = getApi();
92
- if (!api) {
93
- console.error('ngrok is not currently running.');
94
- return;
95
- }
96
- try {
97
- const tunnels = await getActiveTunnels(api);
98
- console.log('tunnels', tunnels);
99
- console.log('attempting to stop tunnel', tunnel);
100
- if (tunnels.length > 0) {
101
- if (tunnel === 'All') {
102
- await closeAllTunnels();
103
- }
104
- else if (typeof tunnel !== 'undefined') {
105
- let tunnelUrl = tunnel.includes("http") ? tunnel : `https://${tunnel}`;
106
- await closeTunnel(tunnelUrl, api);
107
- }
108
- }
109
- else {
110
- console.error('There are no active ngrok tunnels.');
111
- }
112
- }
113
- catch (error) {
114
- console.error('Could not get active tunnels from ngrok.');
115
- }
116
- };
117
- const closeTunnel = async (tunnel, api) => {
118
- try {
119
- await disconnect(tunnel);
120
- let message = `Debugg AI tunnel disconnected.`;
121
- if ((await getActiveTunnels(api)).length === 0) {
122
- await kill();
123
- message = `${message} DebuggAI test runner completed.`;
124
- }
125
- }
126
- catch (error) {
127
- console.error(error);
128
- }
129
- };
130
- const closeAllTunnels = async () => {
131
- try {
132
- await disconnect();
133
- await kill();
134
- }
135
- catch (error) {
136
- console.error(error);
137
- }
138
- };
139
- export const setAuthToken = async (token) => {
140
- if (typeof token !== 'undefined') {
141
- await authtoken({
142
- authtoken: token,
143
- configPath: getConfigPath(),
144
- });
145
- }
146
- };
147
- export async function downloadBinary() {
148
- const binaryLocations = [
149
- join(basePath, 'ngrok'),
150
- join(basePath, 'ngrok.exe'),
151
- ];
152
- if (binaryLocations.some((path) => existsSync(path))) {
153
- console.info('ngrok binary is already downloaded');
154
- }
155
- else {
156
- async function runDownload() {
157
- await mkdirp(basePath);
158
- try {
159
- await new Promise((resolve, reject) => download((error) => (error ? reject(error) : resolve())));
160
- }
161
- catch (error) {
162
- console.error(`Can't update local tunnel configuration. The tests may not work correctly.`);
163
- console.error(error);
164
- }
165
- }
166
- await runDownload();
167
- }
168
- }
169
- ;
170
- export class NgrokTunnelClient {
171
- api = null;
172
- constructor() {
173
- this.api = getApi();
174
- }
175
- start = async (options) => {
176
- return await start(options);
177
- };
178
- stop = async (tunnel) => {
179
- await stop(tunnel);
180
- };
181
- getActiveTunnels = async (api) => {
182
- return await getActiveTunnels(api);
183
- };
184
- getUrl = async (api) => {
185
- const tunnels = await getActiveTunnels(api);
186
- return tunnels.map((tunnel) => tunnel.public_url).join(', ');
187
- };
188
- getApi = async () => {
189
- if (!this.api)
190
- throw new Error('ngrok is not currently running.');
191
- return this.api;
192
- };
193
- downloadBinary = async () => {
194
- await downloadBinary();
195
- };
196
- }
197
- // Export tunnel manager for high-level API
198
- export { tunnelManager } from './tunnelManager.js';
@@ -1,35 +0,0 @@
1
- import axios from "axios";
2
- const axiosServices = axios.create({
3
- baseURL: process.env.REACT_APP_API_URL || "http://localhost:81",
4
- headers: {
5
- "Content-Type": "application/json",
6
- "Accept": "application/json",
7
- "Authorization": "Token 6f960ed60c88b5af7d1d7ecfabeee53f5068dc4d",
8
- },
9
- });
10
- // ==============================|| AXIOS - FOR MOCK SERVICES ||============================== //
11
- axiosServices.interceptors.response.use((response) => {
12
- //console.error(`Response data....${response.data}`)
13
- if (response.data) {
14
- // response.data = objToCamelCase(response.data);
15
- // response.data = response.data;
16
- }
17
- return response;
18
- }, (error) => {
19
- // let host = window.location.host;
20
- // let parts = host.split(".");
21
- // let subdomain = parts[0];
22
- // if (error.response.status === 401 && subdomain == 'app' && !window.location.href.includes('/login')) {
23
- // window.location = '/login';
24
- // }
25
- if (error) {
26
- // error = objToCamelCase(error);
27
- }
28
- return Promise.reject((error.response && error.response.data) || "Wrong Services");
29
- });
30
- axiosServices.interceptors.request.use(async (config) => {
31
- // Update naming convention from CamelCase to the underscored type
32
- return config;
33
- }, (error) => error);
34
- export default axiosServices;
35
- export const { get, post, put, delete: destroy } = axiosServices;
@@ -1,31 +0,0 @@
1
- import { objToCamelCase, objToSnakeCase } from "./objectNaming.js";
2
- import { destroy as destroyAxios, get as getAxios, post as postAxios, put as putAxios } from "./axios.js";
3
- export async function get(url, params) {
4
- const fmtdParams = objToSnakeCase(params);
5
- return getAxios(url, fmtdParams).then((response) => {
6
- console.error("response", response);
7
- const fmtdData = objToCamelCase(response.data);
8
- response.data = fmtdData;
9
- return response;
10
- });
11
- }
12
- export async function post(url, data, config) {
13
- const fmtdData = objToSnakeCase(data);
14
- return postAxios(url, fmtdData, config).then((response) => {
15
- response.data = objToCamelCase(response.data);
16
- return response;
17
- });
18
- }
19
- export async function put(url, data, config) {
20
- const fmtdData = objToSnakeCase(data);
21
- return putAxios(url, fmtdData, config).then((response) => {
22
- response.data = objToCamelCase(response.data);
23
- return response;
24
- });
25
- }
26
- export async function destroy(url, config) {
27
- return destroyAxios(url, config).then((response) => {
28
- response.data = objToCamelCase(response.data);
29
- return response;
30
- });
31
- }
@@ -1 +0,0 @@
1
- export {};