mobbdev 1.2.33 → 1.2.34
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 +15 -1
- package/dist/args/commands/upload_ai_blame.mjs +264 -203
- package/dist/index.mjs +3019 -2962
- package/package.json +1 -1
|
@@ -206,6 +206,20 @@ declare const PromptItemArrayZ: z.ZodArray<z.ZodObject<{
|
|
|
206
206
|
} | undefined;
|
|
207
207
|
}>, "many">;
|
|
208
208
|
type PromptItemArray = z.infer<typeof PromptItemArrayZ>;
|
|
209
|
+
/**
|
|
210
|
+
* Gets the normalized GitHub repository URL from the current working directory.
|
|
211
|
+
* Returns null if not in a git repository or if not a GitHub repository.
|
|
212
|
+
*/
|
|
213
|
+
declare function getRepositoryUrl(): Promise<string | null>;
|
|
214
|
+
/**
|
|
215
|
+
* Get system information for tracking inference source.
|
|
216
|
+
* Works cross-platform (Windows, macOS, Linux).
|
|
217
|
+
* Handles errors gracefully for containerized environments where user info may not be available.
|
|
218
|
+
*/
|
|
219
|
+
declare function getSystemInfo(): {
|
|
220
|
+
computerName: string;
|
|
221
|
+
userName: string | undefined;
|
|
222
|
+
};
|
|
209
223
|
type UploadAiBlameOptions = {
|
|
210
224
|
prompt: string[];
|
|
211
225
|
inference: string[];
|
|
@@ -249,4 +263,4 @@ type UploadAiBlameHandlerOptions = {
|
|
|
249
263
|
declare function uploadAiBlameHandler(options: UploadAiBlameHandlerOptions): Promise<void>;
|
|
250
264
|
declare function uploadAiBlameCommandHandler(args: UploadAiBlameOptions): Promise<void>;
|
|
251
265
|
|
|
252
|
-
export { type PromptItem, type PromptItemArray, type UploadAiBlameOptions, type UploadAiBlameResult, uploadAiBlameBuilder, uploadAiBlameCommandHandler, uploadAiBlameHandler, uploadAiBlameHandlerFromExtension };
|
|
266
|
+
export { type PromptItem, type PromptItemArray, type UploadAiBlameOptions, type UploadAiBlameResult, getRepositoryUrl, getSystemInfo, uploadAiBlameBuilder, uploadAiBlameCommandHandler, uploadAiBlameHandler, uploadAiBlameHandlerFromExtension };
|
|
@@ -73,6 +73,12 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
73
73
|
FinalizeAIBlameInferencesUpload(variables, requestHeaders, signal) {
|
|
74
74
|
return withWrapper((wrappedRequestHeaders) => client.request({ document: FinalizeAiBlameInferencesUploadDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "FinalizeAIBlameInferencesUpload", "mutation", variables);
|
|
75
75
|
},
|
|
76
|
+
UploadTracyRecords(variables, requestHeaders, signal) {
|
|
77
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: UploadTracyRecordsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "UploadTracyRecords", "mutation", variables);
|
|
78
|
+
},
|
|
79
|
+
GetTracyRawDataUploadUrls(variables, requestHeaders, signal) {
|
|
80
|
+
return withWrapper((wrappedRequestHeaders) => client.request({ document: GetTracyRawDataUploadUrlsDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "GetTracyRawDataUploadUrls", "mutation", variables);
|
|
81
|
+
},
|
|
76
82
|
DigestVulnerabilityReport(variables, requestHeaders, signal) {
|
|
77
83
|
return withWrapper((wrappedRequestHeaders) => client.request({ document: DigestVulnerabilityReportDocument, variables, requestHeaders: { ...requestHeaders, ...wrappedRequestHeaders }, signal }), "DigestVulnerabilityReport", "mutation", variables);
|
|
78
84
|
},
|
|
@@ -126,7 +132,7 @@ function getSdk(client, withWrapper = defaultWrapper) {
|
|
|
126
132
|
}
|
|
127
133
|
};
|
|
128
134
|
}
|
|
129
|
-
var AiBlameInferenceType, FixQuestionInputType, Language, ManifestAction, Effort_To_Apply_Fix_Enum, Fix_Rating_Tag_Enum, Fix_Report_State_Enum, Fix_State_Enum, IssueLanguage_Enum, IssueType_Enum, Pr_Status_Enum, Project_Role_Type_Enum, Vulnerability_Report_Issue_Category_Enum, Vulnerability_Report_Issue_State_Enum, Vulnerability_Report_Issue_Tag_Enum, Vulnerability_Report_Vendor_Enum, Vulnerability_Severity_Enum, FixDetailsFragmentDoc, FixReportSummaryFieldsFragmentDoc, MeDocument, GetLastOrgAndNamedProjectDocument, GetLastOrgDocument, GetEncryptedApiTokenDocument, FixReportStateDocument, GetVulnerabilityReportPathsDocument, GetAnalysisSubscriptionDocument, GetAnalysisDocument, GetFixesDocument, GetVulByNodesMetadataDocument, GetFalsePositiveDocument, UpdateScmTokenDocument, UploadS3BucketInfoDocument, GetTracyDiffUploadUrlDocument, AnalyzeCommitForExtensionAiBlameDocument, GetAiBlameInferenceDocument, GetAiBlameAttributionPromptDocument, GetPromptSummaryDocument, UploadAiBlameInferencesInitDocument, FinalizeAiBlameInferencesUploadDocument, DigestVulnerabilityReportDocument, SubmitVulnerabilityReportDocument, CreateCommunityUserDocument, CreateCliLoginDocument, PerformCliLoginDocument, CreateProjectDocument, ValidateRepoUrlDocument, GitReferenceDocument, AutoPrAnalysisDocument, GetFixReportsByRepoUrlDocument, GetReportFixesDocument, GetLatestReportByRepoUrlDocument, UpdateDownloadedFixDataDocument, GetUserMvsAutoFixDocument, StreamBlameAiAnalysisRequestsDocument, StreamCommitBlameRequestsDocument, ScanSkillDocument, defaultWrapper;
|
|
135
|
+
var AiBlameInferenceType, FixQuestionInputType, Language, ManifestAction, Effort_To_Apply_Fix_Enum, Fix_Rating_Tag_Enum, Fix_Report_State_Enum, Fix_State_Enum, IssueLanguage_Enum, IssueType_Enum, Pr_Status_Enum, Project_Role_Type_Enum, Vulnerability_Report_Issue_Category_Enum, Vulnerability_Report_Issue_State_Enum, Vulnerability_Report_Issue_Tag_Enum, Vulnerability_Report_Vendor_Enum, Vulnerability_Severity_Enum, FixDetailsFragmentDoc, FixReportSummaryFieldsFragmentDoc, MeDocument, GetLastOrgAndNamedProjectDocument, GetLastOrgDocument, GetEncryptedApiTokenDocument, FixReportStateDocument, GetVulnerabilityReportPathsDocument, GetAnalysisSubscriptionDocument, GetAnalysisDocument, GetFixesDocument, GetVulByNodesMetadataDocument, GetFalsePositiveDocument, UpdateScmTokenDocument, UploadS3BucketInfoDocument, GetTracyDiffUploadUrlDocument, AnalyzeCommitForExtensionAiBlameDocument, GetAiBlameInferenceDocument, GetAiBlameAttributionPromptDocument, GetPromptSummaryDocument, UploadAiBlameInferencesInitDocument, FinalizeAiBlameInferencesUploadDocument, UploadTracyRecordsDocument, GetTracyRawDataUploadUrlsDocument, DigestVulnerabilityReportDocument, SubmitVulnerabilityReportDocument, CreateCommunityUserDocument, CreateCliLoginDocument, PerformCliLoginDocument, CreateProjectDocument, ValidateRepoUrlDocument, GitReferenceDocument, AutoPrAnalysisDocument, GetFixReportsByRepoUrlDocument, GetReportFixesDocument, GetLatestReportByRepoUrlDocument, UpdateDownloadedFixDataDocument, GetUserMvsAutoFixDocument, StreamBlameAiAnalysisRequestsDocument, StreamCommitBlameRequestsDocument, ScanSkillDocument, defaultWrapper;
|
|
130
136
|
var init_client_generates = __esm({
|
|
131
137
|
"src/features/analysis/scm/generates/client_generates.ts"() {
|
|
132
138
|
"use strict";
|
|
@@ -962,6 +968,28 @@ var init_client_generates = __esm({
|
|
|
962
968
|
status
|
|
963
969
|
error
|
|
964
970
|
}
|
|
971
|
+
}
|
|
972
|
+
`;
|
|
973
|
+
UploadTracyRecordsDocument = `
|
|
974
|
+
mutation UploadTracyRecords($records: [TracyRecordInput!]!) {
|
|
975
|
+
uploadTracyRecords(records: $records) {
|
|
976
|
+
status
|
|
977
|
+
error
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
`;
|
|
981
|
+
GetTracyRawDataUploadUrlsDocument = `
|
|
982
|
+
mutation GetTracyRawDataUploadUrls($recordIds: [String!]!) {
|
|
983
|
+
getTracyRawDataUploadUrls(recordIds: $recordIds) {
|
|
984
|
+
status
|
|
985
|
+
error
|
|
986
|
+
uploads {
|
|
987
|
+
recordId
|
|
988
|
+
url
|
|
989
|
+
uploadFieldsJSON
|
|
990
|
+
uploadKey
|
|
991
|
+
}
|
|
992
|
+
}
|
|
965
993
|
}
|
|
966
994
|
`;
|
|
967
995
|
DigestVulnerabilityReportDocument = `
|
|
@@ -4082,7 +4110,7 @@ import z27 from "zod";
|
|
|
4082
4110
|
|
|
4083
4111
|
// src/commands/handleMobbLogin.ts
|
|
4084
4112
|
import chalk2 from "chalk";
|
|
4085
|
-
import
|
|
4113
|
+
import Debug10 from "debug";
|
|
4086
4114
|
|
|
4087
4115
|
// src/utils/dirname.ts
|
|
4088
4116
|
import fs from "fs";
|
|
@@ -4211,6 +4239,7 @@ var CliError = class extends Error {
|
|
|
4211
4239
|
// src/commands/AuthManager.ts
|
|
4212
4240
|
import crypto from "crypto";
|
|
4213
4241
|
import os from "os";
|
|
4242
|
+
import Debug9 from "debug";
|
|
4214
4243
|
import open from "open";
|
|
4215
4244
|
|
|
4216
4245
|
// src/constants.ts
|
|
@@ -4374,8 +4403,7 @@ function getProxyAgent(url) {
|
|
|
4374
4403
|
const isHttps = parsedUrl.protocol === "https:";
|
|
4375
4404
|
const proxy = isHttps ? getHttpProxy() : isHttp ? getHttpProxyOnly() : null;
|
|
4376
4405
|
if (proxy) {
|
|
4377
|
-
debug2("Using proxy %s", proxy);
|
|
4378
|
-
debug2("Proxy agent %o", proxy);
|
|
4406
|
+
debug2("Using proxy %s for %s", proxy, url);
|
|
4379
4407
|
return new HttpsProxyAgent(proxy);
|
|
4380
4408
|
}
|
|
4381
4409
|
} catch (err) {
|
|
@@ -7094,6 +7122,12 @@ var GQLClient = class {
|
|
|
7094
7122
|
async finalizeAIBlameInferencesUploadRaw(variables) {
|
|
7095
7123
|
return await this._clientSdk.FinalizeAIBlameInferencesUpload(variables);
|
|
7096
7124
|
}
|
|
7125
|
+
async uploadTracyRecords(variables) {
|
|
7126
|
+
return await this._clientSdk.UploadTracyRecords(variables);
|
|
7127
|
+
}
|
|
7128
|
+
async getTracyRawDataUploadUrls(variables) {
|
|
7129
|
+
return await this._clientSdk.GetTracyRawDataUploadUrls(variables);
|
|
7130
|
+
}
|
|
7097
7131
|
async analyzeCommitForExtensionAIBlame(variables) {
|
|
7098
7132
|
return await this._clientSdk.AnalyzeCommitForExtensionAIBlame(variables);
|
|
7099
7133
|
}
|
|
@@ -7111,6 +7145,209 @@ var GQLClient = class {
|
|
|
7111
7145
|
}
|
|
7112
7146
|
};
|
|
7113
7147
|
|
|
7148
|
+
// src/features/analysis/graphql/tracy-batch-upload.ts
|
|
7149
|
+
import { promisify } from "util";
|
|
7150
|
+
import { gzip } from "zlib";
|
|
7151
|
+
import Debug8 from "debug";
|
|
7152
|
+
|
|
7153
|
+
// src/utils/sanitize-sensitive-data.ts
|
|
7154
|
+
import { OpenRedaction } from "@openredaction/openredaction";
|
|
7155
|
+
var openRedaction = new OpenRedaction({
|
|
7156
|
+
patterns: [
|
|
7157
|
+
// Core Personal Data
|
|
7158
|
+
// Removed EMAIL - causes false positives in code/test snippets (e.g. --author="Eve Author <eve@example.com>")
|
|
7159
|
+
// Prefer false negatives over false positives for this use case.
|
|
7160
|
+
"SSN",
|
|
7161
|
+
"NATIONAL_INSURANCE_UK",
|
|
7162
|
+
"DATE_OF_BIRTH",
|
|
7163
|
+
// Identity Documents
|
|
7164
|
+
"PASSPORT_UK",
|
|
7165
|
+
"PASSPORT_US",
|
|
7166
|
+
"PASSPORT_MRZ_TD1",
|
|
7167
|
+
"PASSPORT_MRZ_TD3",
|
|
7168
|
+
"DRIVING_LICENSE_UK",
|
|
7169
|
+
"DRIVING_LICENSE_US",
|
|
7170
|
+
"VISA_NUMBER",
|
|
7171
|
+
"VISA_MRZ",
|
|
7172
|
+
"TAX_ID",
|
|
7173
|
+
// Financial Data (removed SWIFT_BIC, CARD_AUTH_CODE - too broad, causing false positives with authentication words)
|
|
7174
|
+
// Removed CREDIT_CARD - causes false positives on zero-filled UUIDs (e.g. '00000000-0000-0000-0000-000000000000')
|
|
7175
|
+
// Prefer false negatives over false positives for this use case.
|
|
7176
|
+
"IBAN",
|
|
7177
|
+
"BANK_ACCOUNT_UK",
|
|
7178
|
+
"ROUTING_NUMBER_US",
|
|
7179
|
+
"CARD_TRACK1_DATA",
|
|
7180
|
+
"CARD_TRACK2_DATA",
|
|
7181
|
+
"CARD_EXPIRY",
|
|
7182
|
+
// Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
|
|
7183
|
+
"ETHEREUM_ADDRESS",
|
|
7184
|
+
"LITECOIN_ADDRESS",
|
|
7185
|
+
"CARDANO_ADDRESS",
|
|
7186
|
+
"SOLANA_ADDRESS",
|
|
7187
|
+
"MONERO_ADDRESS",
|
|
7188
|
+
"RIPPLE_ADDRESS",
|
|
7189
|
+
// Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
|
|
7190
|
+
// Removed MEDICAL_RECORD_NUMBER - too broad, "MR" prefix matches "Merge Request" in SCM contexts (e.g. "MR branches" → "MR br****es")
|
|
7191
|
+
"NHS_NUMBER",
|
|
7192
|
+
"AUSTRALIAN_MEDICARE",
|
|
7193
|
+
"HEALTH_PLAN_NUMBER",
|
|
7194
|
+
"PATIENT_ID",
|
|
7195
|
+
// Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US, PHONE_US, PHONE_INTERNATIONAL - too broad, causing false positives)
|
|
7196
|
+
"PHONE_UK",
|
|
7197
|
+
"PHONE_UK_MOBILE",
|
|
7198
|
+
"PHONE_LINE_NUMBER",
|
|
7199
|
+
"ADDRESS_STREET",
|
|
7200
|
+
"POSTCODE_UK",
|
|
7201
|
+
// Network & Technical
|
|
7202
|
+
"IPV4",
|
|
7203
|
+
"IPV6",
|
|
7204
|
+
"MAC_ADDRESS",
|
|
7205
|
+
"URL_WITH_AUTH",
|
|
7206
|
+
// Security Keys & Tokens
|
|
7207
|
+
"PRIVATE_KEY",
|
|
7208
|
+
"SSH_PRIVATE_KEY",
|
|
7209
|
+
"AWS_SECRET_KEY",
|
|
7210
|
+
"AWS_ACCESS_KEY",
|
|
7211
|
+
"AZURE_STORAGE_KEY",
|
|
7212
|
+
"GCP_SERVICE_ACCOUNT",
|
|
7213
|
+
"JWT_TOKEN",
|
|
7214
|
+
"OAUTH_TOKEN",
|
|
7215
|
+
"OAUTH_CLIENT_SECRET",
|
|
7216
|
+
"BEARER_TOKEN",
|
|
7217
|
+
"PAYMENT_TOKEN",
|
|
7218
|
+
"GENERIC_SECRET",
|
|
7219
|
+
"GENERIC_API_KEY",
|
|
7220
|
+
// Platform-Specific API Keys
|
|
7221
|
+
"GITHUB_TOKEN",
|
|
7222
|
+
"SLACK_TOKEN",
|
|
7223
|
+
"STRIPE_API_KEY",
|
|
7224
|
+
"GOOGLE_API_KEY",
|
|
7225
|
+
"FIREBASE_API_KEY",
|
|
7226
|
+
"HEROKU_API_KEY",
|
|
7227
|
+
"MAILGUN_API_KEY",
|
|
7228
|
+
"SENDGRID_API_KEY",
|
|
7229
|
+
"TWILIO_API_KEY",
|
|
7230
|
+
"NPM_TOKEN",
|
|
7231
|
+
"PYPI_TOKEN",
|
|
7232
|
+
"DOCKER_AUTH",
|
|
7233
|
+
"KUBERNETES_SECRET",
|
|
7234
|
+
// Government & Legal
|
|
7235
|
+
// Removed CLIENT_ID - too broad, "client" is ubiquitous in code (npm packages like @scope/client-*, class names like ClientSdkOptions)
|
|
7236
|
+
"POLICE_REPORT_NUMBER",
|
|
7237
|
+
"IMMIGRATION_NUMBER",
|
|
7238
|
+
"COURT_REPORTER_LICENSE"
|
|
7239
|
+
]
|
|
7240
|
+
});
|
|
7241
|
+
function maskString(str, showStart = 2, showEnd = 2) {
|
|
7242
|
+
if (str.length <= showStart + showEnd) {
|
|
7243
|
+
return "*".repeat(str.length);
|
|
7244
|
+
}
|
|
7245
|
+
return str.slice(0, showStart) + "*".repeat(str.length - showStart - showEnd) + str.slice(-showEnd);
|
|
7246
|
+
}
|
|
7247
|
+
async function sanitizeDataWithCounts(obj) {
|
|
7248
|
+
const counts = {
|
|
7249
|
+
detections: { total: 0, high: 0, medium: 0, low: 0 }
|
|
7250
|
+
};
|
|
7251
|
+
const sanitizeString = async (str) => {
|
|
7252
|
+
let result = str;
|
|
7253
|
+
const piiDetections = openRedaction.scan(str);
|
|
7254
|
+
if (piiDetections && piiDetections.total > 0) {
|
|
7255
|
+
const allDetections = [
|
|
7256
|
+
...piiDetections.high,
|
|
7257
|
+
...piiDetections.medium,
|
|
7258
|
+
...piiDetections.low
|
|
7259
|
+
];
|
|
7260
|
+
for (const detection of allDetections) {
|
|
7261
|
+
counts.detections.total++;
|
|
7262
|
+
if (detection.severity === "high") counts.detections.high++;
|
|
7263
|
+
else if (detection.severity === "medium") counts.detections.medium++;
|
|
7264
|
+
else if (detection.severity === "low") counts.detections.low++;
|
|
7265
|
+
const masked = maskString(detection.value);
|
|
7266
|
+
result = result.replaceAll(detection.value, masked);
|
|
7267
|
+
}
|
|
7268
|
+
}
|
|
7269
|
+
return result;
|
|
7270
|
+
};
|
|
7271
|
+
const sanitizeRecursive = async (data) => {
|
|
7272
|
+
if (typeof data === "string") {
|
|
7273
|
+
return sanitizeString(data);
|
|
7274
|
+
} else if (Array.isArray(data)) {
|
|
7275
|
+
return Promise.all(data.map((item) => sanitizeRecursive(item)));
|
|
7276
|
+
} else if (data instanceof Error) {
|
|
7277
|
+
return data;
|
|
7278
|
+
} else if (data instanceof Date) {
|
|
7279
|
+
return data;
|
|
7280
|
+
} else if (typeof data === "object" && data !== null) {
|
|
7281
|
+
const sanitized = {};
|
|
7282
|
+
const record = data;
|
|
7283
|
+
for (const key in record) {
|
|
7284
|
+
if (Object.prototype.hasOwnProperty.call(record, key)) {
|
|
7285
|
+
sanitized[key] = await sanitizeRecursive(record[key]);
|
|
7286
|
+
}
|
|
7287
|
+
}
|
|
7288
|
+
return sanitized;
|
|
7289
|
+
}
|
|
7290
|
+
return data;
|
|
7291
|
+
};
|
|
7292
|
+
const sanitizedData = await sanitizeRecursive(obj);
|
|
7293
|
+
return { sanitizedData, counts };
|
|
7294
|
+
}
|
|
7295
|
+
|
|
7296
|
+
// src/features/analysis/upload-file.ts
|
|
7297
|
+
import Debug7 from "debug";
|
|
7298
|
+
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
7299
|
+
var debug8 = Debug7("mobbdev:upload-file");
|
|
7300
|
+
async function uploadFile({
|
|
7301
|
+
file,
|
|
7302
|
+
url,
|
|
7303
|
+
uploadKey,
|
|
7304
|
+
uploadFields,
|
|
7305
|
+
logger
|
|
7306
|
+
}) {
|
|
7307
|
+
const logInfo = logger || ((_message, _data) => {
|
|
7308
|
+
});
|
|
7309
|
+
logInfo(`FileUpload: upload file start ${url}`);
|
|
7310
|
+
logInfo(`FileUpload: upload fields`, uploadFields);
|
|
7311
|
+
logInfo(`FileUpload: upload key ${uploadKey}`);
|
|
7312
|
+
debug8("upload file start %s", url);
|
|
7313
|
+
debug8("upload fields %o", uploadFields);
|
|
7314
|
+
debug8("upload key %s", uploadKey);
|
|
7315
|
+
const form = new FormData();
|
|
7316
|
+
Object.entries(uploadFields).forEach(([key, value]) => {
|
|
7317
|
+
form.append(key, value);
|
|
7318
|
+
});
|
|
7319
|
+
if (!form.has("key")) {
|
|
7320
|
+
form.append("key", uploadKey);
|
|
7321
|
+
}
|
|
7322
|
+
if (typeof file === "string") {
|
|
7323
|
+
debug8("upload file from path %s", file);
|
|
7324
|
+
logInfo(`FileUpload: upload file from path ${file}`);
|
|
7325
|
+
form.append("file", await fileFrom(file));
|
|
7326
|
+
} else {
|
|
7327
|
+
debug8("upload file from buffer");
|
|
7328
|
+
logInfo(`FileUpload: upload file from buffer`);
|
|
7329
|
+
form.append("file", new File([new Uint8Array(file)], "file"));
|
|
7330
|
+
}
|
|
7331
|
+
const agent = getProxyAgent(url);
|
|
7332
|
+
const response = await fetch3(url, {
|
|
7333
|
+
method: "POST",
|
|
7334
|
+
body: form,
|
|
7335
|
+
agent
|
|
7336
|
+
});
|
|
7337
|
+
if (!response.ok) {
|
|
7338
|
+
debug8("error from S3 %s %s", response.body, response.status);
|
|
7339
|
+
logInfo(`FileUpload: error from S3 ${response.body} ${response.status}`);
|
|
7340
|
+
throw new Error(`Failed to upload the file: ${response.status}`);
|
|
7341
|
+
}
|
|
7342
|
+
debug8("upload file done");
|
|
7343
|
+
logInfo(`FileUpload: upload file done`);
|
|
7344
|
+
}
|
|
7345
|
+
|
|
7346
|
+
// src/features/analysis/graphql/tracy-batch-upload.ts
|
|
7347
|
+
var gzipAsync = promisify(gzip);
|
|
7348
|
+
var debug9 = Debug8("mobbdev:tracy-batch-upload");
|
|
7349
|
+
var MAX_BATCH_PAYLOAD_BYTES = 3 * 1024 * 1024;
|
|
7350
|
+
|
|
7114
7351
|
// src/mcp/services/types.ts
|
|
7115
7352
|
function buildLoginUrl(baseUrl, loginId, hostname, context) {
|
|
7116
7353
|
const url = new URL(`${baseUrl}/${loginId}`);
|
|
@@ -7143,9 +7380,10 @@ function getConfigStore() {
|
|
|
7143
7380
|
var configStore = getConfigStore();
|
|
7144
7381
|
|
|
7145
7382
|
// src/commands/AuthManager.ts
|
|
7383
|
+
var debug10 = Debug9("mobbdev:auth");
|
|
7146
7384
|
var LOGIN_MAX_WAIT = 10 * 60 * 1e3;
|
|
7147
7385
|
var LOGIN_CHECK_DELAY = 5 * 1e3;
|
|
7148
|
-
var
|
|
7386
|
+
var _AuthManager = class _AuthManager {
|
|
7149
7387
|
constructor(webAppUrl, apiUrl) {
|
|
7150
7388
|
__publicField(this, "publicKey");
|
|
7151
7389
|
__publicField(this, "privateKey");
|
|
@@ -7167,7 +7405,7 @@ var AuthManager = class {
|
|
|
7167
7405
|
}
|
|
7168
7406
|
async waitForAuthentication() {
|
|
7169
7407
|
let newApiToken = null;
|
|
7170
|
-
for (let i = 0; i <
|
|
7408
|
+
for (let i = 0; i < _AuthManager.loginMaxWait / LOGIN_CHECK_DELAY; i++) {
|
|
7171
7409
|
newApiToken = await this.getApiToken();
|
|
7172
7410
|
if (newApiToken) {
|
|
7173
7411
|
break;
|
|
@@ -7197,6 +7435,9 @@ var AuthManager = class {
|
|
|
7197
7435
|
if (this.authenticated === null) {
|
|
7198
7436
|
const result = await this.checkAuthentication();
|
|
7199
7437
|
this.authenticated = result.isAuthenticated;
|
|
7438
|
+
if (!result.isAuthenticated) {
|
|
7439
|
+
debug10("isAuthenticated: false \u2014 %s", result.message);
|
|
7440
|
+
}
|
|
7200
7441
|
}
|
|
7201
7442
|
return this.authenticated;
|
|
7202
7443
|
}
|
|
@@ -7273,6 +7514,14 @@ var AuthManager = class {
|
|
|
7273
7514
|
}
|
|
7274
7515
|
return null;
|
|
7275
7516
|
}
|
|
7517
|
+
/**
|
|
7518
|
+
* Returns true if a non-empty API token is stored in the configStore.
|
|
7519
|
+
* Used for diagnostics — does NOT validate the token.
|
|
7520
|
+
*/
|
|
7521
|
+
hasStoredToken() {
|
|
7522
|
+
const token = configStore.get("apiToken");
|
|
7523
|
+
return typeof token === "string" && token.length > 0;
|
|
7524
|
+
}
|
|
7276
7525
|
/**
|
|
7277
7526
|
* Gets the current GQL client (if authenticated)
|
|
7278
7527
|
*/
|
|
@@ -7305,9 +7554,12 @@ var AuthManager = class {
|
|
|
7305
7554
|
this.currentBrowserUrl = null;
|
|
7306
7555
|
}
|
|
7307
7556
|
};
|
|
7557
|
+
/** Maximum time (ms) to wait for login authentication. Override in tests for faster failures. */
|
|
7558
|
+
__publicField(_AuthManager, "loginMaxWait", LOGIN_MAX_WAIT);
|
|
7559
|
+
var AuthManager = _AuthManager;
|
|
7308
7560
|
|
|
7309
7561
|
// src/commands/handleMobbLogin.ts
|
|
7310
|
-
var
|
|
7562
|
+
var debug11 = Debug10("mobbdev:commands");
|
|
7311
7563
|
var LOGIN_MAX_WAIT2 = 10 * 60 * 1e3;
|
|
7312
7564
|
var LOGIN_CHECK_DELAY2 = 5 * 1e3;
|
|
7313
7565
|
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(
|
|
@@ -7319,7 +7571,7 @@ async function getAuthenticatedGQLClient({
|
|
|
7319
7571
|
apiUrl,
|
|
7320
7572
|
webAppUrl
|
|
7321
7573
|
}) {
|
|
7322
|
-
|
|
7574
|
+
debug11(
|
|
7323
7575
|
"getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
|
|
7324
7576
|
apiUrl || "undefined",
|
|
7325
7577
|
webAppUrl || "undefined"
|
|
@@ -7342,7 +7594,7 @@ async function handleMobbLogin({
|
|
|
7342
7594
|
webAppUrl,
|
|
7343
7595
|
loginContext
|
|
7344
7596
|
}) {
|
|
7345
|
-
|
|
7597
|
+
debug11(
|
|
7346
7598
|
"handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
|
|
7347
7599
|
apiUrl || "fallback",
|
|
7348
7600
|
apiUrl || "fallback",
|
|
@@ -7361,7 +7613,7 @@ async function handleMobbLogin({
|
|
|
7361
7613
|
return authManager.getGQLClient();
|
|
7362
7614
|
}
|
|
7363
7615
|
} catch (error) {
|
|
7364
|
-
|
|
7616
|
+
debug11("Authentication check failed:", error);
|
|
7365
7617
|
}
|
|
7366
7618
|
if (apiKey) {
|
|
7367
7619
|
createSpinner().start().error({
|
|
@@ -7412,56 +7664,6 @@ init_client_generates();
|
|
|
7412
7664
|
init_GitService();
|
|
7413
7665
|
init_urlParser2();
|
|
7414
7666
|
|
|
7415
|
-
// src/features/analysis/upload-file.ts
|
|
7416
|
-
import Debug8 from "debug";
|
|
7417
|
-
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
7418
|
-
var debug9 = Debug8("mobbdev:upload-file");
|
|
7419
|
-
async function uploadFile({
|
|
7420
|
-
file,
|
|
7421
|
-
url,
|
|
7422
|
-
uploadKey,
|
|
7423
|
-
uploadFields,
|
|
7424
|
-
logger
|
|
7425
|
-
}) {
|
|
7426
|
-
const logInfo = logger || ((_message, _data) => {
|
|
7427
|
-
});
|
|
7428
|
-
logInfo(`FileUpload: upload file start ${url}`);
|
|
7429
|
-
logInfo(`FileUpload: upload fields`, uploadFields);
|
|
7430
|
-
logInfo(`FileUpload: upload key ${uploadKey}`);
|
|
7431
|
-
debug9("upload file start %s", url);
|
|
7432
|
-
debug9("upload fields %o", uploadFields);
|
|
7433
|
-
debug9("upload key %s", uploadKey);
|
|
7434
|
-
const form = new FormData();
|
|
7435
|
-
Object.entries(uploadFields).forEach(([key, value]) => {
|
|
7436
|
-
form.append(key, value);
|
|
7437
|
-
});
|
|
7438
|
-
if (!form.has("key")) {
|
|
7439
|
-
form.append("key", uploadKey);
|
|
7440
|
-
}
|
|
7441
|
-
if (typeof file === "string") {
|
|
7442
|
-
debug9("upload file from path %s", file);
|
|
7443
|
-
logInfo(`FileUpload: upload file from path ${file}`);
|
|
7444
|
-
form.append("file", await fileFrom(file));
|
|
7445
|
-
} else {
|
|
7446
|
-
debug9("upload file from buffer");
|
|
7447
|
-
logInfo(`FileUpload: upload file from buffer`);
|
|
7448
|
-
form.append("file", new File([new Uint8Array(file)], "file"));
|
|
7449
|
-
}
|
|
7450
|
-
const agent = getProxyAgent(url);
|
|
7451
|
-
const response = await fetch3(url, {
|
|
7452
|
-
method: "POST",
|
|
7453
|
-
body: form,
|
|
7454
|
-
agent
|
|
7455
|
-
});
|
|
7456
|
-
if (!response.ok) {
|
|
7457
|
-
debug9("error from S3 %s %s", response.body, response.status);
|
|
7458
|
-
logInfo(`FileUpload: error from S3 ${response.body} ${response.status}`);
|
|
7459
|
-
throw new Error(`Failed to upload the file: ${response.status}`);
|
|
7460
|
-
}
|
|
7461
|
-
debug9("upload file done");
|
|
7462
|
-
logInfo(`FileUpload: upload file done`);
|
|
7463
|
-
}
|
|
7464
|
-
|
|
7465
7667
|
// src/utils/computerName.ts
|
|
7466
7668
|
import { execSync } from "child_process";
|
|
7467
7669
|
import os2 from "os";
|
|
@@ -7551,149 +7753,6 @@ function getStableComputerName() {
|
|
|
7551
7753
|
return currentName;
|
|
7552
7754
|
}
|
|
7553
7755
|
|
|
7554
|
-
// src/utils/sanitize-sensitive-data.ts
|
|
7555
|
-
import { OpenRedaction } from "@openredaction/openredaction";
|
|
7556
|
-
var openRedaction = new OpenRedaction({
|
|
7557
|
-
patterns: [
|
|
7558
|
-
// Core Personal Data
|
|
7559
|
-
// Removed EMAIL - causes false positives in code/test snippets (e.g. --author="Eve Author <eve@example.com>")
|
|
7560
|
-
// Prefer false negatives over false positives for this use case.
|
|
7561
|
-
"SSN",
|
|
7562
|
-
"NATIONAL_INSURANCE_UK",
|
|
7563
|
-
"DATE_OF_BIRTH",
|
|
7564
|
-
// Identity Documents
|
|
7565
|
-
"PASSPORT_UK",
|
|
7566
|
-
"PASSPORT_US",
|
|
7567
|
-
"PASSPORT_MRZ_TD1",
|
|
7568
|
-
"PASSPORT_MRZ_TD3",
|
|
7569
|
-
"DRIVING_LICENSE_UK",
|
|
7570
|
-
"DRIVING_LICENSE_US",
|
|
7571
|
-
"VISA_NUMBER",
|
|
7572
|
-
"VISA_MRZ",
|
|
7573
|
-
"TAX_ID",
|
|
7574
|
-
// Financial Data (removed SWIFT_BIC, CARD_AUTH_CODE - too broad, causing false positives with authentication words)
|
|
7575
|
-
// Removed CREDIT_CARD - causes false positives on zero-filled UUIDs (e.g. '00000000-0000-0000-0000-000000000000')
|
|
7576
|
-
// Prefer false negatives over false positives for this use case.
|
|
7577
|
-
"IBAN",
|
|
7578
|
-
"BANK_ACCOUNT_UK",
|
|
7579
|
-
"ROUTING_NUMBER_US",
|
|
7580
|
-
"CARD_TRACK1_DATA",
|
|
7581
|
-
"CARD_TRACK2_DATA",
|
|
7582
|
-
"CARD_EXPIRY",
|
|
7583
|
-
// Cryptocurrency (removed BITCOIN_ADDRESS - too broad, matches hash-like strings)
|
|
7584
|
-
"ETHEREUM_ADDRESS",
|
|
7585
|
-
"LITECOIN_ADDRESS",
|
|
7586
|
-
"CARDANO_ADDRESS",
|
|
7587
|
-
"SOLANA_ADDRESS",
|
|
7588
|
-
"MONERO_ADDRESS",
|
|
7589
|
-
"RIPPLE_ADDRESS",
|
|
7590
|
-
// Medical Data (removed PRESCRIPTION_NUMBER - too broad, matches words containing "ription")
|
|
7591
|
-
// Removed MEDICAL_RECORD_NUMBER - too broad, "MR" prefix matches "Merge Request" in SCM contexts (e.g. "MR branches" → "MR br****es")
|
|
7592
|
-
"NHS_NUMBER",
|
|
7593
|
-
"AUSTRALIAN_MEDICARE",
|
|
7594
|
-
"HEALTH_PLAN_NUMBER",
|
|
7595
|
-
"PATIENT_ID",
|
|
7596
|
-
// Communications (removed EMERGENCY_CONTACT, ADDRESS_PO_BOX, ZIP_CODE_US, PHONE_US, PHONE_INTERNATIONAL - too broad, causing false positives)
|
|
7597
|
-
"PHONE_UK",
|
|
7598
|
-
"PHONE_UK_MOBILE",
|
|
7599
|
-
"PHONE_LINE_NUMBER",
|
|
7600
|
-
"ADDRESS_STREET",
|
|
7601
|
-
"POSTCODE_UK",
|
|
7602
|
-
// Network & Technical
|
|
7603
|
-
"IPV4",
|
|
7604
|
-
"IPV6",
|
|
7605
|
-
"MAC_ADDRESS",
|
|
7606
|
-
"URL_WITH_AUTH",
|
|
7607
|
-
// Security Keys & Tokens
|
|
7608
|
-
"PRIVATE_KEY",
|
|
7609
|
-
"SSH_PRIVATE_KEY",
|
|
7610
|
-
"AWS_SECRET_KEY",
|
|
7611
|
-
"AWS_ACCESS_KEY",
|
|
7612
|
-
"AZURE_STORAGE_KEY",
|
|
7613
|
-
"GCP_SERVICE_ACCOUNT",
|
|
7614
|
-
"JWT_TOKEN",
|
|
7615
|
-
"OAUTH_TOKEN",
|
|
7616
|
-
"OAUTH_CLIENT_SECRET",
|
|
7617
|
-
"BEARER_TOKEN",
|
|
7618
|
-
"PAYMENT_TOKEN",
|
|
7619
|
-
"GENERIC_SECRET",
|
|
7620
|
-
"GENERIC_API_KEY",
|
|
7621
|
-
// Platform-Specific API Keys
|
|
7622
|
-
"GITHUB_TOKEN",
|
|
7623
|
-
"SLACK_TOKEN",
|
|
7624
|
-
"STRIPE_API_KEY",
|
|
7625
|
-
"GOOGLE_API_KEY",
|
|
7626
|
-
"FIREBASE_API_KEY",
|
|
7627
|
-
"HEROKU_API_KEY",
|
|
7628
|
-
"MAILGUN_API_KEY",
|
|
7629
|
-
"SENDGRID_API_KEY",
|
|
7630
|
-
"TWILIO_API_KEY",
|
|
7631
|
-
"NPM_TOKEN",
|
|
7632
|
-
"PYPI_TOKEN",
|
|
7633
|
-
"DOCKER_AUTH",
|
|
7634
|
-
"KUBERNETES_SECRET",
|
|
7635
|
-
// Government & Legal
|
|
7636
|
-
// Removed CLIENT_ID - too broad, "client" is ubiquitous in code (npm packages like @scope/client-*, class names like ClientSdkOptions)
|
|
7637
|
-
"POLICE_REPORT_NUMBER",
|
|
7638
|
-
"IMMIGRATION_NUMBER",
|
|
7639
|
-
"COURT_REPORTER_LICENSE"
|
|
7640
|
-
]
|
|
7641
|
-
});
|
|
7642
|
-
function maskString(str, showStart = 2, showEnd = 2) {
|
|
7643
|
-
if (str.length <= showStart + showEnd) {
|
|
7644
|
-
return "*".repeat(str.length);
|
|
7645
|
-
}
|
|
7646
|
-
return str.slice(0, showStart) + "*".repeat(str.length - showStart - showEnd) + str.slice(-showEnd);
|
|
7647
|
-
}
|
|
7648
|
-
async function sanitizeDataWithCounts(obj) {
|
|
7649
|
-
const counts = {
|
|
7650
|
-
detections: { total: 0, high: 0, medium: 0, low: 0 }
|
|
7651
|
-
};
|
|
7652
|
-
const sanitizeString = async (str) => {
|
|
7653
|
-
let result = str;
|
|
7654
|
-
const piiDetections = openRedaction.scan(str);
|
|
7655
|
-
if (piiDetections && piiDetections.total > 0) {
|
|
7656
|
-
const allDetections = [
|
|
7657
|
-
...piiDetections.high,
|
|
7658
|
-
...piiDetections.medium,
|
|
7659
|
-
...piiDetections.low
|
|
7660
|
-
];
|
|
7661
|
-
for (const detection of allDetections) {
|
|
7662
|
-
counts.detections.total++;
|
|
7663
|
-
if (detection.severity === "high") counts.detections.high++;
|
|
7664
|
-
else if (detection.severity === "medium") counts.detections.medium++;
|
|
7665
|
-
else if (detection.severity === "low") counts.detections.low++;
|
|
7666
|
-
const masked = maskString(detection.value);
|
|
7667
|
-
result = result.replaceAll(detection.value, masked);
|
|
7668
|
-
}
|
|
7669
|
-
}
|
|
7670
|
-
return result;
|
|
7671
|
-
};
|
|
7672
|
-
const sanitizeRecursive = async (data) => {
|
|
7673
|
-
if (typeof data === "string") {
|
|
7674
|
-
return sanitizeString(data);
|
|
7675
|
-
} else if (Array.isArray(data)) {
|
|
7676
|
-
return Promise.all(data.map((item) => sanitizeRecursive(item)));
|
|
7677
|
-
} else if (data instanceof Error) {
|
|
7678
|
-
return data;
|
|
7679
|
-
} else if (data instanceof Date) {
|
|
7680
|
-
return data;
|
|
7681
|
-
} else if (typeof data === "object" && data !== null) {
|
|
7682
|
-
const sanitized = {};
|
|
7683
|
-
const record = data;
|
|
7684
|
-
for (const key in record) {
|
|
7685
|
-
if (Object.prototype.hasOwnProperty.call(record, key)) {
|
|
7686
|
-
sanitized[key] = await sanitizeRecursive(record[key]);
|
|
7687
|
-
}
|
|
7688
|
-
}
|
|
7689
|
-
return sanitized;
|
|
7690
|
-
}
|
|
7691
|
-
return data;
|
|
7692
|
-
};
|
|
7693
|
-
const sanitizedData = await sanitizeRecursive(obj);
|
|
7694
|
-
return { sanitizedData, counts };
|
|
7695
|
-
}
|
|
7696
|
-
|
|
7697
7756
|
// src/args/commands/upload_ai_blame.ts
|
|
7698
7757
|
var defaultLogger = {
|
|
7699
7758
|
info: (msg, data) => {
|
|
@@ -8014,6 +8073,8 @@ async function uploadAiBlameCommandHandler(args) {
|
|
|
8014
8073
|
await uploadAiBlameHandler({ args });
|
|
8015
8074
|
}
|
|
8016
8075
|
export {
|
|
8076
|
+
getRepositoryUrl,
|
|
8077
|
+
getSystemInfo,
|
|
8017
8078
|
uploadAiBlameBuilder,
|
|
8018
8079
|
uploadAiBlameCommandHandler,
|
|
8019
8080
|
uploadAiBlameHandler,
|