mobbdev 1.1.19 → 1.1.23
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/args/commands/upload_ai_blame.d.mts +4 -2
- package/dist/args/commands/upload_ai_blame.mjs +60 -101
- package/dist/index.mjs +111 -107
- package/package.json +1 -2
|
@@ -8,13 +8,12 @@ declare enum AiBlameInferenceType {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
type SanitizationCounts = {
|
|
11
|
-
|
|
11
|
+
detections: {
|
|
12
12
|
total: number;
|
|
13
13
|
high: number;
|
|
14
14
|
medium: number;
|
|
15
15
|
low: number;
|
|
16
16
|
};
|
|
17
|
-
secrets: number;
|
|
18
17
|
};
|
|
19
18
|
|
|
20
19
|
declare const PromptItemZ: z.ZodObject<{
|
|
@@ -190,9 +189,11 @@ type UploadAiBlameOptions = {
|
|
|
190
189
|
model?: string[];
|
|
191
190
|
toolName?: string[];
|
|
192
191
|
blameType?: AiBlameInferenceType[];
|
|
192
|
+
sessionId?: string[];
|
|
193
193
|
'ai-response-at'?: string[];
|
|
194
194
|
'tool-name'?: string[];
|
|
195
195
|
'blame-type'?: AiBlameInferenceType[];
|
|
196
|
+
'session-id'?: string[];
|
|
196
197
|
};
|
|
197
198
|
declare function uploadAiBlameBuilder(args: Yargs.Argv<unknown>): Yargs.Argv<UploadAiBlameOptions>;
|
|
198
199
|
type UploadAiBlameResult = {
|
|
@@ -208,6 +209,7 @@ declare function uploadAiBlameHandlerFromExtension(args: {
|
|
|
208
209
|
tool: string;
|
|
209
210
|
responseTime: string;
|
|
210
211
|
blameType?: AiBlameInferenceType;
|
|
212
|
+
sessionId?: string;
|
|
211
213
|
}): Promise<UploadAiBlameResult>;
|
|
212
214
|
declare function uploadAiBlameHandler(args: UploadAiBlameOptions, exitOnError?: boolean): Promise<void>;
|
|
213
215
|
|
|
@@ -79,7 +79,7 @@ var init_FileUtils = __esm({
|
|
|
79
79
|
import fs4 from "fs";
|
|
80
80
|
import ignore from "ignore";
|
|
81
81
|
import * as path5 from "path";
|
|
82
|
-
import { simpleGit } from "simple-git";
|
|
82
|
+
import { simpleGit as simpleGit2 } from "simple-git";
|
|
83
83
|
var init_GitService = __esm({
|
|
84
84
|
"src/features/analysis/scm/services/GitService.ts"() {
|
|
85
85
|
"use strict";
|
|
@@ -2203,6 +2203,7 @@ function getDirName() {
|
|
|
2203
2203
|
var debug = Debug("mobbdev:constants");
|
|
2204
2204
|
dotenv.config({ path: path2.join(getModuleRootDir(), ".env") });
|
|
2205
2205
|
var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
|
|
2206
|
+
var DEFAULT_WEB_APP_URL = "https://app.mobb.ai";
|
|
2206
2207
|
var scmFriendlyText = {
|
|
2207
2208
|
["Ado" /* Ado */]: "Azure DevOps",
|
|
2208
2209
|
["Bitbucket" /* Bitbucket */]: "Bitbucket",
|
|
@@ -2229,13 +2230,16 @@ var scannerToVulnerabilityReportVendorEnum = {
|
|
|
2229
2230
|
};
|
|
2230
2231
|
var SupportedScannersZ = z8.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
|
|
2231
2232
|
var envVariablesSchema = z8.object({
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2233
|
+
// These have safe defaults for production - the VS Code extension passes explicit URLs
|
|
2234
|
+
WEB_APP_URL: z8.string().optional().default(DEFAULT_WEB_APP_URL),
|
|
2235
|
+
API_URL: z8.string().optional().default(DEFAULT_API_URL),
|
|
2236
|
+
// These are only needed for local development with Hasura
|
|
2237
|
+
HASURA_ACCESS_KEY: z8.string().optional().default(""),
|
|
2238
|
+
LOCAL_GRAPHQL_ENDPOINT: z8.string().optional().default(""),
|
|
2239
|
+
// Proxy settings
|
|
2236
2240
|
HTTP_PROXY: z8.string().optional().default(""),
|
|
2237
2241
|
HTTPS_PROXY: z8.string().optional().default("")
|
|
2238
|
-
})
|
|
2242
|
+
});
|
|
2239
2243
|
var envVariables = envVariablesSchema.parse(process.env);
|
|
2240
2244
|
debug("config %o", envVariables);
|
|
2241
2245
|
var WEB_APP_URL = envVariables.WEB_APP_URL;
|
|
@@ -2371,6 +2375,9 @@ if (!semver.satisfies(process.version, packageJson.engines.node)) {
|
|
|
2371
2375
|
process.exit(1);
|
|
2372
2376
|
}
|
|
2373
2377
|
|
|
2378
|
+
// src/utils/gitUtils.ts
|
|
2379
|
+
import simpleGit from "simple-git";
|
|
2380
|
+
|
|
2374
2381
|
// src/utils/index.ts
|
|
2375
2382
|
var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
|
|
2376
2383
|
var CliError = class extends Error {
|
|
@@ -4722,10 +4729,12 @@ var GQLClient = class {
|
|
|
4722
4729
|
constructor(args) {
|
|
4723
4730
|
__publicField(this, "_client");
|
|
4724
4731
|
__publicField(this, "_clientSdk");
|
|
4732
|
+
__publicField(this, "_apiUrl");
|
|
4725
4733
|
__publicField(this, "_auth");
|
|
4726
4734
|
debug6(`init with ${args}`);
|
|
4727
4735
|
this._auth = args;
|
|
4728
|
-
this.
|
|
4736
|
+
this._apiUrl = args.apiUrl || API_URL;
|
|
4737
|
+
this._client = new GraphQLClient(this._apiUrl, {
|
|
4729
4738
|
headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
|
|
4730
4739
|
Authorization: `Bearer ${args.token}`
|
|
4731
4740
|
},
|
|
@@ -5023,12 +5032,12 @@ var GQLClient = class {
|
|
|
5023
5032
|
apiKey: this._auth.apiKey,
|
|
5024
5033
|
type: "apiKey",
|
|
5025
5034
|
timeoutInMs: params.timeoutInMs,
|
|
5026
|
-
proxyAgent: getProxyAgent(
|
|
5035
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
5027
5036
|
} : {
|
|
5028
5037
|
token: this._auth.token,
|
|
5029
5038
|
type: "token",
|
|
5030
5039
|
timeoutInMs: params.timeoutInMs,
|
|
5031
|
-
proxyAgent: getProxyAgent(
|
|
5040
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
5032
5041
|
}
|
|
5033
5042
|
);
|
|
5034
5043
|
}
|
|
@@ -5114,29 +5123,37 @@ var configStore = getConfigStore();
|
|
|
5114
5123
|
var debug7 = Debug6("mobbdev:commands");
|
|
5115
5124
|
var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
|
|
5116
5125
|
var LOGIN_CHECK_DELAY = 5 * 1e3;
|
|
5117
|
-
var webLoginUrl = `${WEB_APP_URL}/cli-login`;
|
|
5118
5126
|
var MOBB_LOGIN_REQUIRED_MSG = `\u{1F513} Login to Mobb is Required, you will be redirected to our login page, once the authorization is complete return to this prompt, ${chalk2.bgBlue(
|
|
5119
5127
|
"press any key to continue"
|
|
5120
5128
|
)};`;
|
|
5121
5129
|
async function getAuthenticatedGQLClient({
|
|
5122
5130
|
inputApiKey = "",
|
|
5123
|
-
isSkipPrompts = true
|
|
5131
|
+
isSkipPrompts = true,
|
|
5132
|
+
apiUrl,
|
|
5133
|
+
webAppUrl
|
|
5124
5134
|
}) {
|
|
5125
5135
|
let gqlClient = new GQLClient({
|
|
5126
5136
|
apiKey: inputApiKey || configStore.get("apiToken") || "",
|
|
5127
|
-
type: "apiKey"
|
|
5137
|
+
type: "apiKey",
|
|
5138
|
+
apiUrl
|
|
5128
5139
|
});
|
|
5129
5140
|
gqlClient = await handleMobbLogin({
|
|
5130
5141
|
inGqlClient: gqlClient,
|
|
5131
|
-
skipPrompts: isSkipPrompts
|
|
5142
|
+
skipPrompts: isSkipPrompts,
|
|
5143
|
+
apiUrl,
|
|
5144
|
+
webAppUrl
|
|
5132
5145
|
});
|
|
5133
5146
|
return gqlClient;
|
|
5134
5147
|
}
|
|
5135
5148
|
async function handleMobbLogin({
|
|
5136
5149
|
inGqlClient,
|
|
5137
5150
|
apiKey,
|
|
5138
|
-
skipPrompts
|
|
5151
|
+
skipPrompts,
|
|
5152
|
+
apiUrl,
|
|
5153
|
+
webAppUrl
|
|
5139
5154
|
}) {
|
|
5155
|
+
const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
|
|
5156
|
+
const resolvedApiUrl = apiUrl || API_URL;
|
|
5140
5157
|
const { createSpinner } = Spinner({ ci: skipPrompts });
|
|
5141
5158
|
const isConnected = await inGqlClient.verifyApiConnection();
|
|
5142
5159
|
if (!isConnected) {
|
|
@@ -5178,7 +5195,7 @@ async function handleMobbLogin({
|
|
|
5178
5195
|
const loginId = await inGqlClient.createCliLogin({
|
|
5179
5196
|
publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
|
|
5180
5197
|
});
|
|
5181
|
-
const browserUrl = `${
|
|
5198
|
+
const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
|
|
5182
5199
|
!skipPrompts && console.log(
|
|
5183
5200
|
`If the page does not open automatically, kindly access it through ${browserUrl}.`
|
|
5184
5201
|
);
|
|
@@ -5203,7 +5220,11 @@ async function handleMobbLogin({
|
|
|
5203
5220
|
});
|
|
5204
5221
|
throw new CliError();
|
|
5205
5222
|
}
|
|
5206
|
-
const newGqlClient = new GQLClient({
|
|
5223
|
+
const newGqlClient = new GQLClient({
|
|
5224
|
+
apiKey: newApiToken,
|
|
5225
|
+
type: "apiKey",
|
|
5226
|
+
apiUrl: resolvedApiUrl
|
|
5227
|
+
});
|
|
5207
5228
|
const loginSuccess = await newGqlClient.validateUserToken();
|
|
5208
5229
|
if (loginSuccess) {
|
|
5209
5230
|
debug7(`set api token ${newApiToken}`);
|
|
@@ -5272,8 +5293,6 @@ async function uploadFile({
|
|
|
5272
5293
|
|
|
5273
5294
|
// src/utils/sanitize-sensitive-data.ts
|
|
5274
5295
|
import { OpenRedaction } from "@openredaction/openredaction";
|
|
5275
|
-
import { spawn } from "child_process";
|
|
5276
|
-
import { installGitleaks } from "gitleaks-secret-scanner/lib/installer.js";
|
|
5277
5296
|
var openRedaction = new OpenRedaction({
|
|
5278
5297
|
patterns: [
|
|
5279
5298
|
// Core Personal Data
|
|
@@ -5291,42 +5310,36 @@ var openRedaction = new OpenRedaction({
|
|
|
5291
5310
|
"VISA_NUMBER",
|
|
5292
5311
|
"VISA_MRZ",
|
|
5293
5312
|
"TAX_ID",
|
|
5294
|
-
// Financial Data
|
|
5313
|
+
// Financial Data (removed SWIFT_BIC - too broad, matches bank code formats in variables)
|
|
5295
5314
|
"CREDIT_CARD",
|
|
5296
5315
|
"IBAN",
|
|
5297
5316
|
"BANK_ACCOUNT_UK",
|
|
5298
5317
|
"ROUTING_NUMBER_US",
|
|
5299
|
-
"SWIFT_BIC",
|
|
5300
5318
|
"CARD_TRACK1_DATA",
|
|
5301
5319
|
"CARD_TRACK2_DATA",
|
|
5302
5320
|
"CARD_EXPIRY",
|
|
5303
5321
|
"CARD_AUTH_CODE",
|
|
5304
|
-
// Cryptocurrency
|
|
5305
|
-
"BITCOIN_ADDRESS",
|
|
5322
|
+
// Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
|
|
5306
5323
|
"ETHEREUM_ADDRESS",
|
|
5307
5324
|
"LITECOIN_ADDRESS",
|
|
5308
5325
|
"CARDANO_ADDRESS",
|
|
5309
5326
|
"SOLANA_ADDRESS",
|
|
5310
5327
|
"MONERO_ADDRESS",
|
|
5311
5328
|
"RIPPLE_ADDRESS",
|
|
5312
|
-
// Medical Data
|
|
5329
|
+
// Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
|
|
5313
5330
|
"NHS_NUMBER",
|
|
5314
5331
|
"MEDICAL_RECORD_NUMBER",
|
|
5315
5332
|
"AUSTRALIAN_MEDICARE",
|
|
5316
5333
|
"HEALTH_PLAN_NUMBER",
|
|
5317
|
-
"PRESCRIPTION_NUMBER",
|
|
5318
5334
|
"PATIENT_ID",
|
|
5319
|
-
// Communications
|
|
5335
|
+
// Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US - too broad)
|
|
5320
5336
|
"PHONE_US",
|
|
5321
5337
|
"PHONE_UK",
|
|
5322
5338
|
"PHONE_UK_MOBILE",
|
|
5323
5339
|
"PHONE_INTERNATIONAL",
|
|
5324
5340
|
"PHONE_LINE_NUMBER",
|
|
5325
|
-
"EMERGENCY_CONTACT",
|
|
5326
5341
|
"ADDRESS_STREET",
|
|
5327
|
-
"ADDRESS_PO_BOX",
|
|
5328
5342
|
"POSTCODE_UK",
|
|
5329
|
-
"ZIP_CODE_US",
|
|
5330
5343
|
// Network & Technical
|
|
5331
5344
|
"IPV4",
|
|
5332
5345
|
"IPV6",
|
|
@@ -5367,63 +5380,6 @@ var openRedaction = new OpenRedaction({
|
|
|
5367
5380
|
"CLIENT_ID"
|
|
5368
5381
|
]
|
|
5369
5382
|
});
|
|
5370
|
-
var gitleaksBinaryPath = null;
|
|
5371
|
-
async function initializeGitleaks() {
|
|
5372
|
-
try {
|
|
5373
|
-
gitleaksBinaryPath = await installGitleaks({ version: "8.27.2" });
|
|
5374
|
-
return gitleaksBinaryPath;
|
|
5375
|
-
} catch {
|
|
5376
|
-
return null;
|
|
5377
|
-
}
|
|
5378
|
-
}
|
|
5379
|
-
var gitleaksInitPromise = initializeGitleaks();
|
|
5380
|
-
async function detectSecretsWithGitleaks(text) {
|
|
5381
|
-
const secrets = /* @__PURE__ */ new Set();
|
|
5382
|
-
const binaryPath = gitleaksBinaryPath || await gitleaksInitPromise;
|
|
5383
|
-
if (!binaryPath) {
|
|
5384
|
-
return secrets;
|
|
5385
|
-
}
|
|
5386
|
-
return new Promise((resolve) => {
|
|
5387
|
-
const gitleaks = spawn(
|
|
5388
|
-
binaryPath,
|
|
5389
|
-
[
|
|
5390
|
-
"detect",
|
|
5391
|
-
"--pipe",
|
|
5392
|
-
"--no-banner",
|
|
5393
|
-
"--exit-code",
|
|
5394
|
-
"0",
|
|
5395
|
-
"--report-format",
|
|
5396
|
-
"json"
|
|
5397
|
-
],
|
|
5398
|
-
{
|
|
5399
|
-
stdio: ["pipe", "pipe", "ignore"]
|
|
5400
|
-
}
|
|
5401
|
-
);
|
|
5402
|
-
let output = "";
|
|
5403
|
-
gitleaks.stdout.on("data", (data) => {
|
|
5404
|
-
output += data.toString();
|
|
5405
|
-
});
|
|
5406
|
-
gitleaks.on("close", () => {
|
|
5407
|
-
try {
|
|
5408
|
-
const findings = JSON.parse(output);
|
|
5409
|
-
if (Array.isArray(findings)) {
|
|
5410
|
-
for (const finding of findings) {
|
|
5411
|
-
if (finding.Secret) {
|
|
5412
|
-
secrets.add(finding.Secret);
|
|
5413
|
-
}
|
|
5414
|
-
}
|
|
5415
|
-
}
|
|
5416
|
-
} catch {
|
|
5417
|
-
}
|
|
5418
|
-
resolve(secrets);
|
|
5419
|
-
});
|
|
5420
|
-
gitleaks.on("error", () => {
|
|
5421
|
-
resolve(secrets);
|
|
5422
|
-
});
|
|
5423
|
-
gitleaks.stdin.write(text);
|
|
5424
|
-
gitleaks.stdin.end();
|
|
5425
|
-
});
|
|
5426
|
-
}
|
|
5427
5383
|
function maskString(str, showStart = 2, showEnd = 2) {
|
|
5428
5384
|
if (str.length <= showStart + showEnd) {
|
|
5429
5385
|
return "*".repeat(str.length);
|
|
@@ -5432,8 +5388,7 @@ function maskString(str, showStart = 2, showEnd = 2) {
|
|
|
5432
5388
|
}
|
|
5433
5389
|
async function sanitizeDataWithCounts(obj) {
|
|
5434
5390
|
const counts = {
|
|
5435
|
-
|
|
5436
|
-
secrets: 0
|
|
5391
|
+
detections: { total: 0, high: 0, medium: 0, low: 0 }
|
|
5437
5392
|
};
|
|
5438
5393
|
const sanitizeString = async (str) => {
|
|
5439
5394
|
let result = str;
|
|
@@ -5445,20 +5400,14 @@ async function sanitizeDataWithCounts(obj) {
|
|
|
5445
5400
|
...piiDetections.low
|
|
5446
5401
|
];
|
|
5447
5402
|
for (const detection of allDetections) {
|
|
5448
|
-
counts.
|
|
5449
|
-
if (detection.severity === "high") counts.
|
|
5450
|
-
else if (detection.severity === "medium") counts.
|
|
5451
|
-
else if (detection.severity === "low") counts.
|
|
5403
|
+
counts.detections.total++;
|
|
5404
|
+
if (detection.severity === "high") counts.detections.high++;
|
|
5405
|
+
else if (detection.severity === "medium") counts.detections.medium++;
|
|
5406
|
+
else if (detection.severity === "low") counts.detections.low++;
|
|
5452
5407
|
const masked = maskString(detection.value);
|
|
5453
5408
|
result = result.replaceAll(detection.value, masked);
|
|
5454
5409
|
}
|
|
5455
5410
|
}
|
|
5456
|
-
const secrets = await detectSecretsWithGitleaks(result);
|
|
5457
|
-
counts.secrets += secrets.size;
|
|
5458
|
-
for (const secret of secrets) {
|
|
5459
|
-
const masked = maskString(secret);
|
|
5460
|
-
result = result.replaceAll(secret, masked);
|
|
5461
|
-
}
|
|
5462
5411
|
return result;
|
|
5463
5412
|
};
|
|
5464
5413
|
const sanitizeRecursive = async (data) => {
|
|
@@ -5569,7 +5518,8 @@ async function uploadAiBlameHandlerFromExtension(args) {
|
|
|
5569
5518
|
model: [],
|
|
5570
5519
|
toolName: [],
|
|
5571
5520
|
aiResponseAt: [],
|
|
5572
|
-
blameType: []
|
|
5521
|
+
blameType: [],
|
|
5522
|
+
sessionId: []
|
|
5573
5523
|
};
|
|
5574
5524
|
let promptsCounts;
|
|
5575
5525
|
let inferenceCounts;
|
|
@@ -5602,6 +5552,9 @@ async function uploadAiBlameHandlerFromExtension(args) {
|
|
|
5602
5552
|
uploadArgs.toolName.push(args.tool);
|
|
5603
5553
|
uploadArgs.aiResponseAt.push(args.responseTime);
|
|
5604
5554
|
uploadArgs.blameType.push(args.blameType || "CHAT" /* Chat */);
|
|
5555
|
+
if (args.sessionId) {
|
|
5556
|
+
uploadArgs.sessionId.push(args.sessionId);
|
|
5557
|
+
}
|
|
5605
5558
|
await uploadAiBlameHandler(uploadArgs, false);
|
|
5606
5559
|
});
|
|
5607
5560
|
});
|
|
@@ -5619,6 +5572,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
|
|
|
5619
5572
|
const tools = args.toolName || args["tool-name"] || [];
|
|
5620
5573
|
const responseTimes = args.aiResponseAt || args["ai-response-at"] || [];
|
|
5621
5574
|
const blameTypes = args.blameType || args["blame-type"] || [];
|
|
5575
|
+
const sessionIds = args.sessionId || args["session-id"] || [];
|
|
5622
5576
|
if (prompts.length !== inferences.length) {
|
|
5623
5577
|
const errorMsg = "prompt and inference must have the same number of entries";
|
|
5624
5578
|
console.error(chalk3.red(errorMsg));
|
|
@@ -5654,14 +5608,18 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
|
|
|
5654
5608
|
toolName: tools[i],
|
|
5655
5609
|
blameType: blameTypes[i] || "CHAT" /* Chat */,
|
|
5656
5610
|
computerName,
|
|
5657
|
-
userName
|
|
5611
|
+
userName,
|
|
5612
|
+
sessionId: sessionIds[i]
|
|
5658
5613
|
});
|
|
5659
5614
|
}
|
|
5660
5615
|
const authenticatedClient = await getAuthenticatedGQLClient({
|
|
5661
5616
|
isSkipPrompts: true
|
|
5662
5617
|
});
|
|
5618
|
+
const initSessions = sessions.map(
|
|
5619
|
+
({ sessionId: _sessionId, ...rest }) => rest
|
|
5620
|
+
);
|
|
5663
5621
|
const sanitizedSessions = await sanitizeData(
|
|
5664
|
-
|
|
5622
|
+
initSessions
|
|
5665
5623
|
);
|
|
5666
5624
|
const initRes = await authenticatedClient.uploadAIBlameInferencesInitRaw({
|
|
5667
5625
|
sessions: sanitizedSessions
|
|
@@ -5707,7 +5665,8 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
|
|
|
5707
5665
|
toolName: s.toolName,
|
|
5708
5666
|
blameType: s.blameType,
|
|
5709
5667
|
computerName: s.computerName,
|
|
5710
|
-
userName: s.userName
|
|
5668
|
+
userName: s.userName,
|
|
5669
|
+
sessionId: s.sessionId
|
|
5711
5670
|
};
|
|
5712
5671
|
});
|
|
5713
5672
|
const sanitizedFinalizeSessions = await sanitizeData(
|
package/dist/index.mjs
CHANGED
|
@@ -9863,6 +9863,7 @@ var utils_exports = {};
|
|
|
9863
9863
|
__export(utils_exports, {
|
|
9864
9864
|
CliError: () => CliError,
|
|
9865
9865
|
Spinner: () => Spinner,
|
|
9866
|
+
createGitWithLogging: () => createGitWithLogging,
|
|
9866
9867
|
getDirName: () => getDirName,
|
|
9867
9868
|
getModuleRootDir: () => getModuleRootDir,
|
|
9868
9869
|
getTopLevelDirName: () => getTopLevelDirName,
|
|
@@ -9990,6 +9991,53 @@ if (!semver.satisfies(process.version, packageJson.engines.node)) {
|
|
|
9990
9991
|
process.exit(1);
|
|
9991
9992
|
}
|
|
9992
9993
|
|
|
9994
|
+
// src/utils/gitUtils.ts
|
|
9995
|
+
import simpleGit2 from "simple-git";
|
|
9996
|
+
var defaultLogger = {
|
|
9997
|
+
info: (data, msg) => {
|
|
9998
|
+
if (msg) {
|
|
9999
|
+
const sanitizedMsg = String(msg).replace(/\n|\r/g, "");
|
|
10000
|
+
console.log(`[GIT] ${sanitizedMsg}`, data);
|
|
10001
|
+
} else {
|
|
10002
|
+
console.log("[GIT]", data);
|
|
10003
|
+
}
|
|
10004
|
+
}
|
|
10005
|
+
};
|
|
10006
|
+
function createGitWithLogging(dirName, logger2 = defaultLogger) {
|
|
10007
|
+
return simpleGit2(dirName, {
|
|
10008
|
+
maxConcurrentProcesses: 6
|
|
10009
|
+
}).outputHandler((bin, stdout2, stderr2) => {
|
|
10010
|
+
const callID = Math.random();
|
|
10011
|
+
logger2.info({ callID, bin }, "Start git CLI call");
|
|
10012
|
+
const errChunks = [];
|
|
10013
|
+
const outChunks = [];
|
|
10014
|
+
let isStdoutClosed = false;
|
|
10015
|
+
let isStderrClosed = false;
|
|
10016
|
+
stderr2.on("data", (data) => errChunks.push(data.toString("utf8")));
|
|
10017
|
+
stdout2.on("data", (data) => outChunks.push(data.toString("utf8")));
|
|
10018
|
+
function logData() {
|
|
10019
|
+
if (!isStderrClosed || !isStdoutClosed) {
|
|
10020
|
+
return;
|
|
10021
|
+
}
|
|
10022
|
+
const logObj = {
|
|
10023
|
+
callID,
|
|
10024
|
+
bin,
|
|
10025
|
+
err: `${errChunks.join("").slice(0, 200)}...`,
|
|
10026
|
+
out: `${outChunks.join("").slice(0, 200)}...`
|
|
10027
|
+
};
|
|
10028
|
+
logger2.info(logObj, "git log output");
|
|
10029
|
+
}
|
|
10030
|
+
stderr2.on("close", () => {
|
|
10031
|
+
isStderrClosed = true;
|
|
10032
|
+
logData();
|
|
10033
|
+
});
|
|
10034
|
+
stdout2.on("close", () => {
|
|
10035
|
+
isStdoutClosed = true;
|
|
10036
|
+
logData();
|
|
10037
|
+
});
|
|
10038
|
+
});
|
|
10039
|
+
}
|
|
10040
|
+
|
|
9993
10041
|
// src/utils/index.ts
|
|
9994
10042
|
var sleep = (ms = 2e3) => new Promise((r) => setTimeout(r, ms));
|
|
9995
10043
|
var CliError = class extends Error {
|
|
@@ -10390,6 +10438,7 @@ import { z as z24 } from "zod";
|
|
|
10390
10438
|
var debug5 = Debug4("mobbdev:constants");
|
|
10391
10439
|
dotenv.config({ path: path6.join(getModuleRootDir(), ".env") });
|
|
10392
10440
|
var DEFAULT_API_URL = "https://api.mobb.ai/v1/graphql";
|
|
10441
|
+
var DEFAULT_WEB_APP_URL = "https://app.mobb.ai";
|
|
10393
10442
|
var scmFriendlyText = {
|
|
10394
10443
|
["Ado" /* Ado */]: "Azure DevOps",
|
|
10395
10444
|
["Bitbucket" /* Bitbucket */]: "Bitbucket",
|
|
@@ -10416,13 +10465,16 @@ var scannerToVulnerabilityReportVendorEnum = {
|
|
|
10416
10465
|
};
|
|
10417
10466
|
var SupportedScannersZ = z24.enum([SCANNERS.Checkmarx, SCANNERS.Snyk]);
|
|
10418
10467
|
var envVariablesSchema = z24.object({
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10468
|
+
// These have safe defaults for production - the VS Code extension passes explicit URLs
|
|
10469
|
+
WEB_APP_URL: z24.string().optional().default(DEFAULT_WEB_APP_URL),
|
|
10470
|
+
API_URL: z24.string().optional().default(DEFAULT_API_URL),
|
|
10471
|
+
// These are only needed for local development with Hasura
|
|
10472
|
+
HASURA_ACCESS_KEY: z24.string().optional().default(""),
|
|
10473
|
+
LOCAL_GRAPHQL_ENDPOINT: z24.string().optional().default(""),
|
|
10474
|
+
// Proxy settings
|
|
10423
10475
|
HTTP_PROXY: z24.string().optional().default(""),
|
|
10424
10476
|
HTTPS_PROXY: z24.string().optional().default("")
|
|
10425
|
-
})
|
|
10477
|
+
});
|
|
10426
10478
|
var envVariables = envVariablesSchema.parse(process.env);
|
|
10427
10479
|
debug5("config %o", envVariables);
|
|
10428
10480
|
var mobbAscii = `
|
|
@@ -10475,9 +10527,9 @@ var errorMessages = {
|
|
|
10475
10527
|
)} is needed if you're adding an SCM token`
|
|
10476
10528
|
};
|
|
10477
10529
|
var progressMassages = {
|
|
10478
|
-
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report
|
|
10479
|
-
processingVulnerabilityReport: "\u2699\uFE0F
|
|
10480
|
-
processingVulnerabilityReportFailed: "\u2699\uFE0F Error
|
|
10530
|
+
processingVulnerabilityReportSuccess: "\u2699\uFE0F Vulnerability report processed successfully",
|
|
10531
|
+
processingVulnerabilityReport: "\u2699\uFE0F Processing vulnerability report",
|
|
10532
|
+
processingVulnerabilityReportFailed: "\u2699\uFE0F Error Processing vulnerability report"
|
|
10481
10533
|
};
|
|
10482
10534
|
var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
|
|
10483
10535
|
|
|
@@ -10977,10 +11029,12 @@ var GQLClient = class {
|
|
|
10977
11029
|
constructor(args) {
|
|
10978
11030
|
__publicField(this, "_client");
|
|
10979
11031
|
__publicField(this, "_clientSdk");
|
|
11032
|
+
__publicField(this, "_apiUrl");
|
|
10980
11033
|
__publicField(this, "_auth");
|
|
10981
11034
|
debug6(`init with ${args}`);
|
|
10982
11035
|
this._auth = args;
|
|
10983
|
-
this.
|
|
11036
|
+
this._apiUrl = args.apiUrl || API_URL;
|
|
11037
|
+
this._client = new GraphQLClient(this._apiUrl, {
|
|
10984
11038
|
headers: args.type === "apiKey" ? { [API_KEY_HEADER_NAME]: args.apiKey || "" } : {
|
|
10985
11039
|
Authorization: `Bearer ${args.token}`
|
|
10986
11040
|
},
|
|
@@ -11278,12 +11332,12 @@ var GQLClient = class {
|
|
|
11278
11332
|
apiKey: this._auth.apiKey,
|
|
11279
11333
|
type: "apiKey",
|
|
11280
11334
|
timeoutInMs: params.timeoutInMs,
|
|
11281
|
-
proxyAgent: getProxyAgent(
|
|
11335
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
11282
11336
|
} : {
|
|
11283
11337
|
token: this._auth.token,
|
|
11284
11338
|
type: "token",
|
|
11285
11339
|
timeoutInMs: params.timeoutInMs,
|
|
11286
|
-
proxyAgent: getProxyAgent(
|
|
11340
|
+
proxyAgent: getProxyAgent(this._apiUrl)
|
|
11287
11341
|
}
|
|
11288
11342
|
);
|
|
11289
11343
|
}
|
|
@@ -11369,29 +11423,37 @@ var configStore = getConfigStore();
|
|
|
11369
11423
|
var debug7 = Debug6("mobbdev:commands");
|
|
11370
11424
|
var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
|
|
11371
11425
|
var LOGIN_CHECK_DELAY = 5 * 1e3;
|
|
11372
|
-
var webLoginUrl = `${WEB_APP_URL}/cli-login`;
|
|
11373
11426
|
var MOBB_LOGIN_REQUIRED_MSG = `\u{1F513} Login to Mobb is Required, you will be redirected to our login page, once the authorization is complete return to this prompt, ${chalk3.bgBlue(
|
|
11374
11427
|
"press any key to continue"
|
|
11375
11428
|
)};`;
|
|
11376
11429
|
async function getAuthenticatedGQLClient({
|
|
11377
11430
|
inputApiKey = "",
|
|
11378
|
-
isSkipPrompts = true
|
|
11431
|
+
isSkipPrompts = true,
|
|
11432
|
+
apiUrl,
|
|
11433
|
+
webAppUrl
|
|
11379
11434
|
}) {
|
|
11380
11435
|
let gqlClient = new GQLClient({
|
|
11381
11436
|
apiKey: inputApiKey || configStore.get("apiToken") || "",
|
|
11382
|
-
type: "apiKey"
|
|
11437
|
+
type: "apiKey",
|
|
11438
|
+
apiUrl
|
|
11383
11439
|
});
|
|
11384
11440
|
gqlClient = await handleMobbLogin({
|
|
11385
11441
|
inGqlClient: gqlClient,
|
|
11386
|
-
skipPrompts: isSkipPrompts
|
|
11442
|
+
skipPrompts: isSkipPrompts,
|
|
11443
|
+
apiUrl,
|
|
11444
|
+
webAppUrl
|
|
11387
11445
|
});
|
|
11388
11446
|
return gqlClient;
|
|
11389
11447
|
}
|
|
11390
11448
|
async function handleMobbLogin({
|
|
11391
11449
|
inGqlClient,
|
|
11392
11450
|
apiKey,
|
|
11393
|
-
skipPrompts
|
|
11451
|
+
skipPrompts,
|
|
11452
|
+
apiUrl,
|
|
11453
|
+
webAppUrl
|
|
11394
11454
|
}) {
|
|
11455
|
+
const resolvedWebAppUrl = webAppUrl || WEB_APP_URL;
|
|
11456
|
+
const resolvedApiUrl = apiUrl || API_URL;
|
|
11395
11457
|
const { createSpinner: createSpinner5 } = Spinner({ ci: skipPrompts });
|
|
11396
11458
|
const isConnected = await inGqlClient.verifyApiConnection();
|
|
11397
11459
|
if (!isConnected) {
|
|
@@ -11433,7 +11495,7 @@ async function handleMobbLogin({
|
|
|
11433
11495
|
const loginId = await inGqlClient.createCliLogin({
|
|
11434
11496
|
publicKey: publicKey.export({ format: "pem", type: "pkcs1" }).toString()
|
|
11435
11497
|
});
|
|
11436
|
-
const browserUrl = `${
|
|
11498
|
+
const browserUrl = `${resolvedWebAppUrl}/cli-login/${loginId}?hostname=${os.hostname()}`;
|
|
11437
11499
|
!skipPrompts && console.log(
|
|
11438
11500
|
`If the page does not open automatically, kindly access it through ${browserUrl}.`
|
|
11439
11501
|
);
|
|
@@ -11458,7 +11520,11 @@ async function handleMobbLogin({
|
|
|
11458
11520
|
});
|
|
11459
11521
|
throw new CliError();
|
|
11460
11522
|
}
|
|
11461
|
-
const newGqlClient = new GQLClient({
|
|
11523
|
+
const newGqlClient = new GQLClient({
|
|
11524
|
+
apiKey: newApiToken,
|
|
11525
|
+
type: "apiKey",
|
|
11526
|
+
apiUrl: resolvedApiUrl
|
|
11527
|
+
});
|
|
11462
11528
|
const loginSuccess = await newGqlClient.validateUserToken();
|
|
11463
11529
|
if (loginSuccess) {
|
|
11464
11530
|
debug7(`set api token ${newApiToken}`);
|
|
@@ -12141,7 +12207,7 @@ import AdmZip from "adm-zip";
|
|
|
12141
12207
|
import Debug13 from "debug";
|
|
12142
12208
|
import { globby } from "globby";
|
|
12143
12209
|
import { isBinary as isBinary2 } from "istextorbinary";
|
|
12144
|
-
import { simpleGit as
|
|
12210
|
+
import { simpleGit as simpleGit3 } from "simple-git";
|
|
12145
12211
|
import { parseStringPromise } from "xml2js";
|
|
12146
12212
|
import { z as z28 } from "zod";
|
|
12147
12213
|
var debug14 = Debug13("mobbdev:pack");
|
|
@@ -12169,7 +12235,7 @@ async function pack(srcDirPath, vulnFiles, isIncludeAllFiles = false) {
|
|
|
12169
12235
|
debug14("pack folder %s", srcDirPath);
|
|
12170
12236
|
let git = void 0;
|
|
12171
12237
|
try {
|
|
12172
|
-
git =
|
|
12238
|
+
git = simpleGit3({
|
|
12173
12239
|
baseDir: srcDirPath,
|
|
12174
12240
|
maxConcurrentProcesses: 1,
|
|
12175
12241
|
trimmed: true
|
|
@@ -13561,8 +13627,6 @@ import z31 from "zod";
|
|
|
13561
13627
|
|
|
13562
13628
|
// src/utils/sanitize-sensitive-data.ts
|
|
13563
13629
|
import { OpenRedaction } from "@openredaction/openredaction";
|
|
13564
|
-
import { spawn } from "child_process";
|
|
13565
|
-
import { installGitleaks } from "gitleaks-secret-scanner/lib/installer.js";
|
|
13566
13630
|
var openRedaction = new OpenRedaction({
|
|
13567
13631
|
patterns: [
|
|
13568
13632
|
// Core Personal Data
|
|
@@ -13580,42 +13644,36 @@ var openRedaction = new OpenRedaction({
|
|
|
13580
13644
|
"VISA_NUMBER",
|
|
13581
13645
|
"VISA_MRZ",
|
|
13582
13646
|
"TAX_ID",
|
|
13583
|
-
// Financial Data
|
|
13647
|
+
// Financial Data (removed SWIFT_BIC - too broad, matches bank code formats in variables)
|
|
13584
13648
|
"CREDIT_CARD",
|
|
13585
13649
|
"IBAN",
|
|
13586
13650
|
"BANK_ACCOUNT_UK",
|
|
13587
13651
|
"ROUTING_NUMBER_US",
|
|
13588
|
-
"SWIFT_BIC",
|
|
13589
13652
|
"CARD_TRACK1_DATA",
|
|
13590
13653
|
"CARD_TRACK2_DATA",
|
|
13591
13654
|
"CARD_EXPIRY",
|
|
13592
13655
|
"CARD_AUTH_CODE",
|
|
13593
|
-
// Cryptocurrency
|
|
13594
|
-
"BITCOIN_ADDRESS",
|
|
13656
|
+
// Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
|
|
13595
13657
|
"ETHEREUM_ADDRESS",
|
|
13596
13658
|
"LITECOIN_ADDRESS",
|
|
13597
13659
|
"CARDANO_ADDRESS",
|
|
13598
13660
|
"SOLANA_ADDRESS",
|
|
13599
13661
|
"MONERO_ADDRESS",
|
|
13600
13662
|
"RIPPLE_ADDRESS",
|
|
13601
|
-
// Medical Data
|
|
13663
|
+
// Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
|
|
13602
13664
|
"NHS_NUMBER",
|
|
13603
13665
|
"MEDICAL_RECORD_NUMBER",
|
|
13604
13666
|
"AUSTRALIAN_MEDICARE",
|
|
13605
13667
|
"HEALTH_PLAN_NUMBER",
|
|
13606
|
-
"PRESCRIPTION_NUMBER",
|
|
13607
13668
|
"PATIENT_ID",
|
|
13608
|
-
// Communications
|
|
13669
|
+
// Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US - too broad)
|
|
13609
13670
|
"PHONE_US",
|
|
13610
13671
|
"PHONE_UK",
|
|
13611
13672
|
"PHONE_UK_MOBILE",
|
|
13612
13673
|
"PHONE_INTERNATIONAL",
|
|
13613
13674
|
"PHONE_LINE_NUMBER",
|
|
13614
|
-
"EMERGENCY_CONTACT",
|
|
13615
13675
|
"ADDRESS_STREET",
|
|
13616
|
-
"ADDRESS_PO_BOX",
|
|
13617
13676
|
"POSTCODE_UK",
|
|
13618
|
-
"ZIP_CODE_US",
|
|
13619
13677
|
// Network & Technical
|
|
13620
13678
|
"IPV4",
|
|
13621
13679
|
"IPV6",
|
|
@@ -13656,63 +13714,6 @@ var openRedaction = new OpenRedaction({
|
|
|
13656
13714
|
"CLIENT_ID"
|
|
13657
13715
|
]
|
|
13658
13716
|
});
|
|
13659
|
-
var gitleaksBinaryPath = null;
|
|
13660
|
-
async function initializeGitleaks() {
|
|
13661
|
-
try {
|
|
13662
|
-
gitleaksBinaryPath = await installGitleaks({ version: "8.27.2" });
|
|
13663
|
-
return gitleaksBinaryPath;
|
|
13664
|
-
} catch {
|
|
13665
|
-
return null;
|
|
13666
|
-
}
|
|
13667
|
-
}
|
|
13668
|
-
var gitleaksInitPromise = initializeGitleaks();
|
|
13669
|
-
async function detectSecretsWithGitleaks(text) {
|
|
13670
|
-
const secrets = /* @__PURE__ */ new Set();
|
|
13671
|
-
const binaryPath = gitleaksBinaryPath || await gitleaksInitPromise;
|
|
13672
|
-
if (!binaryPath) {
|
|
13673
|
-
return secrets;
|
|
13674
|
-
}
|
|
13675
|
-
return new Promise((resolve) => {
|
|
13676
|
-
const gitleaks = spawn(
|
|
13677
|
-
binaryPath,
|
|
13678
|
-
[
|
|
13679
|
-
"detect",
|
|
13680
|
-
"--pipe",
|
|
13681
|
-
"--no-banner",
|
|
13682
|
-
"--exit-code",
|
|
13683
|
-
"0",
|
|
13684
|
-
"--report-format",
|
|
13685
|
-
"json"
|
|
13686
|
-
],
|
|
13687
|
-
{
|
|
13688
|
-
stdio: ["pipe", "pipe", "ignore"]
|
|
13689
|
-
}
|
|
13690
|
-
);
|
|
13691
|
-
let output = "";
|
|
13692
|
-
gitleaks.stdout.on("data", (data) => {
|
|
13693
|
-
output += data.toString();
|
|
13694
|
-
});
|
|
13695
|
-
gitleaks.on("close", () => {
|
|
13696
|
-
try {
|
|
13697
|
-
const findings = JSON.parse(output);
|
|
13698
|
-
if (Array.isArray(findings)) {
|
|
13699
|
-
for (const finding of findings) {
|
|
13700
|
-
if (finding.Secret) {
|
|
13701
|
-
secrets.add(finding.Secret);
|
|
13702
|
-
}
|
|
13703
|
-
}
|
|
13704
|
-
}
|
|
13705
|
-
} catch {
|
|
13706
|
-
}
|
|
13707
|
-
resolve(secrets);
|
|
13708
|
-
});
|
|
13709
|
-
gitleaks.on("error", () => {
|
|
13710
|
-
resolve(secrets);
|
|
13711
|
-
});
|
|
13712
|
-
gitleaks.stdin.write(text);
|
|
13713
|
-
gitleaks.stdin.end();
|
|
13714
|
-
});
|
|
13715
|
-
}
|
|
13716
13717
|
function maskString(str, showStart = 2, showEnd = 2) {
|
|
13717
13718
|
if (str.length <= showStart + showEnd) {
|
|
13718
13719
|
return "*".repeat(str.length);
|
|
@@ -13721,8 +13722,7 @@ function maskString(str, showStart = 2, showEnd = 2) {
|
|
|
13721
13722
|
}
|
|
13722
13723
|
async function sanitizeDataWithCounts(obj) {
|
|
13723
13724
|
const counts = {
|
|
13724
|
-
|
|
13725
|
-
secrets: 0
|
|
13725
|
+
detections: { total: 0, high: 0, medium: 0, low: 0 }
|
|
13726
13726
|
};
|
|
13727
13727
|
const sanitizeString = async (str) => {
|
|
13728
13728
|
let result = str;
|
|
@@ -13734,20 +13734,14 @@ async function sanitizeDataWithCounts(obj) {
|
|
|
13734
13734
|
...piiDetections.low
|
|
13735
13735
|
];
|
|
13736
13736
|
for (const detection of allDetections) {
|
|
13737
|
-
counts.
|
|
13738
|
-
if (detection.severity === "high") counts.
|
|
13739
|
-
else if (detection.severity === "medium") counts.
|
|
13740
|
-
else if (detection.severity === "low") counts.
|
|
13737
|
+
counts.detections.total++;
|
|
13738
|
+
if (detection.severity === "high") counts.detections.high++;
|
|
13739
|
+
else if (detection.severity === "medium") counts.detections.medium++;
|
|
13740
|
+
else if (detection.severity === "low") counts.detections.low++;
|
|
13741
13741
|
const masked = maskString(detection.value);
|
|
13742
13742
|
result = result.replaceAll(detection.value, masked);
|
|
13743
13743
|
}
|
|
13744
13744
|
}
|
|
13745
|
-
const secrets = await detectSecretsWithGitleaks(result);
|
|
13746
|
-
counts.secrets += secrets.size;
|
|
13747
|
-
for (const secret of secrets) {
|
|
13748
|
-
const masked = maskString(secret);
|
|
13749
|
-
result = result.replaceAll(secret, masked);
|
|
13750
|
-
}
|
|
13751
13745
|
return result;
|
|
13752
13746
|
};
|
|
13753
13747
|
const sanitizeRecursive = async (data) => {
|
|
@@ -13858,7 +13852,8 @@ async function uploadAiBlameHandlerFromExtension(args) {
|
|
|
13858
13852
|
model: [],
|
|
13859
13853
|
toolName: [],
|
|
13860
13854
|
aiResponseAt: [],
|
|
13861
|
-
blameType: []
|
|
13855
|
+
blameType: [],
|
|
13856
|
+
sessionId: []
|
|
13862
13857
|
};
|
|
13863
13858
|
let promptsCounts;
|
|
13864
13859
|
let inferenceCounts;
|
|
@@ -13891,6 +13886,9 @@ async function uploadAiBlameHandlerFromExtension(args) {
|
|
|
13891
13886
|
uploadArgs.toolName.push(args.tool);
|
|
13892
13887
|
uploadArgs.aiResponseAt.push(args.responseTime);
|
|
13893
13888
|
uploadArgs.blameType.push(args.blameType || "CHAT" /* Chat */);
|
|
13889
|
+
if (args.sessionId) {
|
|
13890
|
+
uploadArgs.sessionId.push(args.sessionId);
|
|
13891
|
+
}
|
|
13894
13892
|
await uploadAiBlameHandler(uploadArgs, false);
|
|
13895
13893
|
});
|
|
13896
13894
|
});
|
|
@@ -13908,6 +13906,7 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
|
|
|
13908
13906
|
const tools = args.toolName || args["tool-name"] || [];
|
|
13909
13907
|
const responseTimes = args.aiResponseAt || args["ai-response-at"] || [];
|
|
13910
13908
|
const blameTypes = args.blameType || args["blame-type"] || [];
|
|
13909
|
+
const sessionIds = args.sessionId || args["session-id"] || [];
|
|
13911
13910
|
if (prompts.length !== inferences.length) {
|
|
13912
13911
|
const errorMsg = "prompt and inference must have the same number of entries";
|
|
13913
13912
|
console.error(chalk9.red(errorMsg));
|
|
@@ -13943,14 +13942,18 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
|
|
|
13943
13942
|
toolName: tools[i],
|
|
13944
13943
|
blameType: blameTypes[i] || "CHAT" /* Chat */,
|
|
13945
13944
|
computerName,
|
|
13946
|
-
userName
|
|
13945
|
+
userName,
|
|
13946
|
+
sessionId: sessionIds[i]
|
|
13947
13947
|
});
|
|
13948
13948
|
}
|
|
13949
13949
|
const authenticatedClient = await getAuthenticatedGQLClient({
|
|
13950
13950
|
isSkipPrompts: true
|
|
13951
13951
|
});
|
|
13952
|
+
const initSessions = sessions.map(
|
|
13953
|
+
({ sessionId: _sessionId, ...rest }) => rest
|
|
13954
|
+
);
|
|
13952
13955
|
const sanitizedSessions = await sanitizeData(
|
|
13953
|
-
|
|
13956
|
+
initSessions
|
|
13954
13957
|
);
|
|
13955
13958
|
const initRes = await authenticatedClient.uploadAIBlameInferencesInitRaw({
|
|
13956
13959
|
sessions: sanitizedSessions
|
|
@@ -13996,7 +13999,8 @@ async function uploadAiBlameHandler(args, exitOnError = true) {
|
|
|
13996
13999
|
toolName: s.toolName,
|
|
13997
14000
|
blameType: s.blameType,
|
|
13998
14001
|
computerName: s.computerName,
|
|
13999
|
-
userName: s.userName
|
|
14002
|
+
userName: s.userName,
|
|
14003
|
+
sessionId: s.sessionId
|
|
14000
14004
|
};
|
|
14001
14005
|
});
|
|
14002
14006
|
const sanitizedFinalizeSessions = await sanitizeData(
|
|
@@ -14799,8 +14803,8 @@ var McpAuthService = class {
|
|
|
14799
14803
|
throw new CliLoginError("Error: createCliLogin failed");
|
|
14800
14804
|
}
|
|
14801
14805
|
logDebug(`cli login created ${loginId}`);
|
|
14802
|
-
const
|
|
14803
|
-
const browserUrl = `${
|
|
14806
|
+
const webLoginUrl = `${WEB_APP_URL}/mvs-login`;
|
|
14807
|
+
const browserUrl = `${webLoginUrl}/${loginId}?hostname=${os4.hostname()}`;
|
|
14804
14808
|
await this.openBrowser(browserUrl, isBackgoundCall);
|
|
14805
14809
|
logDebug(`waiting for login to complete`);
|
|
14806
14810
|
let newApiToken = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobbdev",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.23",
|
|
4
4
|
"description": "Automated secure code remediation tool",
|
|
5
5
|
"repository": "git+https://github.com/mobb-dev/bugsy.git",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
"debug": "4.4.3",
|
|
69
69
|
"dotenv": "16.6.1",
|
|
70
70
|
"extract-zip": "2.0.1",
|
|
71
|
-
"gitleaks-secret-scanner": "1.2.2",
|
|
72
71
|
"globby": "14.1.0",
|
|
73
72
|
"graphql": "16.12.0",
|
|
74
73
|
"graphql-request": "6.1.0",
|