mobbdev 1.2.28 → 1.2.32
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.mjs +420 -188
- package/dist/index.mjs +694 -477
- package/package.json +1 -1
|
@@ -851,12 +851,15 @@ var init_client_generates = __esm({
|
|
|
851
851
|
}
|
|
852
852
|
`;
|
|
853
853
|
AnalyzeCommitForExtensionAiBlameDocument = `
|
|
854
|
-
mutation AnalyzeCommitForExtensionAIBlame($repositoryURL: String!, $commitSha: String!, $organizationId: String!, $commitTimestamp: Timestamp) {
|
|
854
|
+
mutation AnalyzeCommitForExtensionAIBlame($repositoryURL: String!, $commitSha: String!, $organizationId: String!, $commitTimestamp: Timestamp, $commitAuthor: GitIdentityInput, $commitCommitter: GitIdentityInput, $commitCoAuthors: [GitIdentityInput!]) {
|
|
855
855
|
analyzeCommitForAIBlame(
|
|
856
856
|
repositoryURL: $repositoryURL
|
|
857
857
|
commitSha: $commitSha
|
|
858
858
|
organizationId: $organizationId
|
|
859
859
|
commitTimestamp: $commitTimestamp
|
|
860
|
+
commitAuthor: $commitAuthor
|
|
861
|
+
commitCommitter: $commitCommitter
|
|
862
|
+
commitCoAuthors: $commitCoAuthors
|
|
860
863
|
) {
|
|
861
864
|
__typename
|
|
862
865
|
... on ProcessAIBlameFinalResult {
|
|
@@ -2636,6 +2639,217 @@ var init_configs = __esm({
|
|
|
2636
2639
|
}
|
|
2637
2640
|
});
|
|
2638
2641
|
|
|
2642
|
+
// src/utils/blame/gitBlameTypes.ts
|
|
2643
|
+
import { z as z19 } from "zod";
|
|
2644
|
+
function parseCoAuthorValue(raw) {
|
|
2645
|
+
const trimmed = raw.trim();
|
|
2646
|
+
if (!trimmed) {
|
|
2647
|
+
return null;
|
|
2648
|
+
}
|
|
2649
|
+
const openBracket = trimmed.lastIndexOf("<");
|
|
2650
|
+
const closeBracket = trimmed.lastIndexOf(">");
|
|
2651
|
+
if (openBracket === -1 || closeBracket === -1 || closeBracket < openBracket) {
|
|
2652
|
+
return null;
|
|
2653
|
+
}
|
|
2654
|
+
const name = trimmed.slice(0, openBracket).trim();
|
|
2655
|
+
const email = trimmed.slice(openBracket + 1, closeBracket).trim();
|
|
2656
|
+
if (!name || !email) {
|
|
2657
|
+
return null;
|
|
2658
|
+
}
|
|
2659
|
+
return { name, email };
|
|
2660
|
+
}
|
|
2661
|
+
function parseCommitLine(line) {
|
|
2662
|
+
const parts = line.split("\0");
|
|
2663
|
+
if (parts.length < 7) {
|
|
2664
|
+
return null;
|
|
2665
|
+
}
|
|
2666
|
+
return {
|
|
2667
|
+
sha: parts[0],
|
|
2668
|
+
author: { name: parts[2], email: parts[1] },
|
|
2669
|
+
committer: { name: parts[4], email: parts[3] },
|
|
2670
|
+
coAuthors: parts.slice(7).map(parseCoAuthorValue).filter((v) => v !== null),
|
|
2671
|
+
timestamp: parseInt(parts[5], 10),
|
|
2672
|
+
message: parts[6]
|
|
2673
|
+
};
|
|
2674
|
+
}
|
|
2675
|
+
var PrepareGitBlameMessageZ, PrepareGitBlameResponseMessageZ, CommitMetadataZ, LineToCommitMapZ, CommitMetadataMapZ, BlameInfoZ, LineRangeZ, PrContextZ, PrepareCommitBlameMessageZ, BlameLineInfoZ, FileBlameDataZ, ChunkFetchResultZ, FileBlameResponseEntryZ, CommitBlameDataZ, CommitInfoZ, GitIdentityZ, COMMIT_LOG_FORMAT, CommitDataZ, PrDiffDataZ, PrStatsZ, CommitsManifestZ, BlameLineEntryZ, BlameLinesDataZ, PrepareCommitBlameResponseMessageZ;
|
|
2676
|
+
var init_gitBlameTypes = __esm({
|
|
2677
|
+
"src/utils/blame/gitBlameTypes.ts"() {
|
|
2678
|
+
"use strict";
|
|
2679
|
+
PrepareGitBlameMessageZ = z19.object({
|
|
2680
|
+
reportId: z19.string(),
|
|
2681
|
+
repoArchivePath: z19.string()
|
|
2682
|
+
});
|
|
2683
|
+
PrepareGitBlameResponseMessageZ = z19.object({
|
|
2684
|
+
reportId: z19.string()
|
|
2685
|
+
});
|
|
2686
|
+
CommitMetadataZ = z19.object({
|
|
2687
|
+
author: z19.string().optional(),
|
|
2688
|
+
"author-mail": z19.string().optional(),
|
|
2689
|
+
"author-time": z19.string().optional(),
|
|
2690
|
+
"author-tz": z19.string().optional(),
|
|
2691
|
+
committer: z19.string().optional(),
|
|
2692
|
+
"committer-mail": z19.string().optional(),
|
|
2693
|
+
"committer-time": z19.string().optional(),
|
|
2694
|
+
"committer-tz": z19.string().optional(),
|
|
2695
|
+
summary: z19.string().optional(),
|
|
2696
|
+
filename: z19.string().optional()
|
|
2697
|
+
});
|
|
2698
|
+
LineToCommitMapZ = z19.record(z19.string(), z19.string());
|
|
2699
|
+
CommitMetadataMapZ = z19.record(z19.string(), CommitMetadataZ);
|
|
2700
|
+
BlameInfoZ = z19.object({
|
|
2701
|
+
lineToCommit: LineToCommitMapZ,
|
|
2702
|
+
commitMetadata: CommitMetadataMapZ
|
|
2703
|
+
});
|
|
2704
|
+
LineRangeZ = z19.object({
|
|
2705
|
+
/** First line in chunk (1-indexed) */
|
|
2706
|
+
start: z19.number(),
|
|
2707
|
+
/** Last line in chunk (inclusive) */
|
|
2708
|
+
end: z19.number()
|
|
2709
|
+
});
|
|
2710
|
+
PrContextZ = z19.object({
|
|
2711
|
+
prNumber: z19.number(),
|
|
2712
|
+
repositoryUrl: z19.string(),
|
|
2713
|
+
organizationId: z19.string(),
|
|
2714
|
+
userEmail: z19.string(),
|
|
2715
|
+
source: z19.enum(["pr", "github"]),
|
|
2716
|
+
githubContext: z19.object({
|
|
2717
|
+
prNumber: z19.number(),
|
|
2718
|
+
installationId: z19.number(),
|
|
2719
|
+
repositoryURL: z19.string()
|
|
2720
|
+
}).optional()
|
|
2721
|
+
});
|
|
2722
|
+
PrepareCommitBlameMessageZ = z19.object({
|
|
2723
|
+
/** Commit blame request ID from database (for tracking and updating status) */
|
|
2724
|
+
commitBlameRequestId: z19.string(),
|
|
2725
|
+
/** Organization ID (for org-scoped caching) */
|
|
2726
|
+
organizationId: z19.string(),
|
|
2727
|
+
/** Full repository URL (e.g., https://github.com/org/repo) */
|
|
2728
|
+
repositoryUrl: z19.string(),
|
|
2729
|
+
/** Commit SHA to analyze (typically PR head commit) */
|
|
2730
|
+
commitSha: z19.string(),
|
|
2731
|
+
/** Authentication headers for repository access (e.g., GitHub token) */
|
|
2732
|
+
extraHeaders: z19.record(z19.string(), z19.string()).default({}),
|
|
2733
|
+
// --- PR analysis fields ---
|
|
2734
|
+
/** Target branch name (from getPr() base.ref). When set, enables PR analysis mode. */
|
|
2735
|
+
targetBranch: z19.string().optional(),
|
|
2736
|
+
/** Context for triggering blame attribution analysis after SCM agent completes. */
|
|
2737
|
+
prContext: PrContextZ.optional(),
|
|
2738
|
+
/** User email for blame attribution analysis trigger context (used for both PR and single commit flows). */
|
|
2739
|
+
userEmail: z19.string().optional()
|
|
2740
|
+
});
|
|
2741
|
+
BlameLineInfoZ = z19.object({
|
|
2742
|
+
/** Line number as it appeared in the introducing commit */
|
|
2743
|
+
originalLineNumber: z19.number(),
|
|
2744
|
+
/** Commit SHA that introduced this line */
|
|
2745
|
+
commitSha: z19.string(),
|
|
2746
|
+
/** Author name for this line */
|
|
2747
|
+
authorName: z19.string().optional(),
|
|
2748
|
+
/** Author email for this line */
|
|
2749
|
+
authorEmail: z19.string().optional()
|
|
2750
|
+
}).nullable();
|
|
2751
|
+
FileBlameDataZ = z19.array(BlameLineInfoZ);
|
|
2752
|
+
ChunkFetchResultZ = z19.object({
|
|
2753
|
+
filePath: z19.string(),
|
|
2754
|
+
lines: z19.array(z19.number()),
|
|
2755
|
+
data: FileBlameDataZ.nullable()
|
|
2756
|
+
});
|
|
2757
|
+
FileBlameResponseEntryZ = z19.object({
|
|
2758
|
+
/** Chunk index (0 for small files, 0-N for large file chunks) */
|
|
2759
|
+
chunkIndex: z19.number(),
|
|
2760
|
+
/** Blame data array (1-indexed, index 0 is null) */
|
|
2761
|
+
blameData: FileBlameDataZ
|
|
2762
|
+
});
|
|
2763
|
+
CommitBlameDataZ = z19.record(
|
|
2764
|
+
z19.string(),
|
|
2765
|
+
// fileName
|
|
2766
|
+
z19.array(FileBlameResponseEntryZ)
|
|
2767
|
+
);
|
|
2768
|
+
CommitInfoZ = z19.object({
|
|
2769
|
+
/** Number of parent commits (1 = normal commit, 2+ = merge commit, null = failed to determine) */
|
|
2770
|
+
parentCount: z19.number().nullable()
|
|
2771
|
+
});
|
|
2772
|
+
GitIdentityZ = z19.object({
|
|
2773
|
+
name: z19.string(),
|
|
2774
|
+
email: z19.string()
|
|
2775
|
+
});
|
|
2776
|
+
COMMIT_LOG_FORMAT = "%H%x00%ae%x00%an%x00%ce%x00%cn%x00%at%x00%s%x00%(trailers:key=Co-authored-by,valueonly,separator=%x00)";
|
|
2777
|
+
CommitDataZ = z19.object({
|
|
2778
|
+
diff: z19.string(),
|
|
2779
|
+
author: GitIdentityZ,
|
|
2780
|
+
committer: GitIdentityZ,
|
|
2781
|
+
coAuthors: z19.array(GitIdentityZ),
|
|
2782
|
+
timestamp: z19.number(),
|
|
2783
|
+
// Unix timestamp in seconds
|
|
2784
|
+
message: z19.string().optional(),
|
|
2785
|
+
parentCount: z19.number().nullable()
|
|
2786
|
+
});
|
|
2787
|
+
PrDiffDataZ = z19.object({
|
|
2788
|
+
diff: z19.string()
|
|
2789
|
+
});
|
|
2790
|
+
PrStatsZ = z19.object({
|
|
2791
|
+
additions: z19.number(),
|
|
2792
|
+
deletions: z19.number()
|
|
2793
|
+
});
|
|
2794
|
+
CommitsManifestZ = z19.object({
|
|
2795
|
+
commits: z19.array(z19.string())
|
|
2796
|
+
// Array of commit SHAs in order
|
|
2797
|
+
});
|
|
2798
|
+
BlameLineEntryZ = z19.object({
|
|
2799
|
+
file: z19.string(),
|
|
2800
|
+
line: z19.number(),
|
|
2801
|
+
originalCommitSha: z19.string(),
|
|
2802
|
+
originalLineNumber: z19.number()
|
|
2803
|
+
});
|
|
2804
|
+
BlameLinesDataZ = z19.object({
|
|
2805
|
+
lines: z19.array(BlameLineEntryZ)
|
|
2806
|
+
});
|
|
2807
|
+
PrepareCommitBlameResponseMessageZ = z19.object({
|
|
2808
|
+
/** Commit blame request ID (matches request, used to update specific DB record) */
|
|
2809
|
+
commitBlameRequestId: z19.string(),
|
|
2810
|
+
/** Organization ID (matches request) */
|
|
2811
|
+
organizationId: z19.string(),
|
|
2812
|
+
/** Repository URL (matches request) */
|
|
2813
|
+
repositoryUrl: z19.string(),
|
|
2814
|
+
/** Commit SHA analyzed (matches request) */
|
|
2815
|
+
commitSha: z19.string(),
|
|
2816
|
+
/** Processing status */
|
|
2817
|
+
status: z19.enum(["success", "failure"]),
|
|
2818
|
+
/** Error message (only present if status is 'failure') */
|
|
2819
|
+
error: z19.string().optional(),
|
|
2820
|
+
/**
|
|
2821
|
+
* Blame data for all processed files/chunks.
|
|
2822
|
+
* Empty dictionary if status is 'failure'.
|
|
2823
|
+
* Contains line mappings as arrays if status is 'success'.
|
|
2824
|
+
*/
|
|
2825
|
+
blameData: CommitBlameDataZ,
|
|
2826
|
+
/**
|
|
2827
|
+
* Info about each commit referenced in the blame data plus the head commit.
|
|
2828
|
+
* Keyed by commit SHA, deduplicated.
|
|
2829
|
+
* Empty dictionary if status is 'failure'.
|
|
2830
|
+
*/
|
|
2831
|
+
commits: z19.record(z19.string(), CommitInfoZ).default({}),
|
|
2832
|
+
// --- New PR diff computation response fields ---
|
|
2833
|
+
/** S3 paths for commit-level data (commitSha → S3 key). Present in PR analysis mode and single commit mode. */
|
|
2834
|
+
commitDataS3Paths: z19.record(z19.string(), z19.string()).optional(),
|
|
2835
|
+
/** S3 key for PR diff JSON. Present in PR analysis mode. */
|
|
2836
|
+
prDiffS3Path: z19.string().optional(),
|
|
2837
|
+
/** S3 key for commits manifest. Present in PR analysis mode. */
|
|
2838
|
+
commitsManifestS3Path: z19.string().optional(),
|
|
2839
|
+
/** S3 key for per-line targeted blame data. Present in PR analysis mode. */
|
|
2840
|
+
blameLinesS3Path: z19.string().optional(),
|
|
2841
|
+
/** S3 key for PR stats (additions/deletions). Present in PR analysis mode. */
|
|
2842
|
+
prStatsS3Path: z19.string().optional(),
|
|
2843
|
+
/** PR context passed through from request for response handler. */
|
|
2844
|
+
prContext: PrContextZ.optional(),
|
|
2845
|
+
/** PR title from the request metadata (passed through). */
|
|
2846
|
+
prTitle: z19.string().optional(),
|
|
2847
|
+
/** User email passed through from request for single commit blame attribution analysis trigger. */
|
|
2848
|
+
userEmail: z19.string().optional()
|
|
2849
|
+
});
|
|
2850
|
+
}
|
|
2851
|
+
});
|
|
2852
|
+
|
|
2639
2853
|
// src/features/analysis/scm/services/ExcludedDirs.ts
|
|
2640
2854
|
var EXCLUDED_DIRS;
|
|
2641
2855
|
var init_ExcludedDirs = __esm({
|
|
@@ -3308,6 +3522,7 @@ var init_GitService = __esm({
|
|
|
3308
3522
|
"src/features/analysis/scm/services/GitService.ts"() {
|
|
3309
3523
|
"use strict";
|
|
3310
3524
|
init_configs();
|
|
3525
|
+
init_gitBlameTypes();
|
|
3311
3526
|
init_urlParser2();
|
|
3312
3527
|
init_FileUtils();
|
|
3313
3528
|
MAX_COMMIT_DIFF_SIZE_BYTES = 3 * 1024 * 1024;
|
|
@@ -3804,7 +4019,7 @@ ${rootContent}`;
|
|
|
3804
4019
|
const DIFF_DELIMITER = "---MOBB_DIFF_START---";
|
|
3805
4020
|
const output = await this.git.show([
|
|
3806
4021
|
commitSha,
|
|
3807
|
-
`--format
|
|
4022
|
+
`--format=${COMMIT_LOG_FORMAT}%n${DIFF_DELIMITER}`,
|
|
3808
4023
|
"--patch"
|
|
3809
4024
|
]);
|
|
3810
4025
|
const delimiterIndex = output.indexOf(DIFF_DELIMITER);
|
|
@@ -3825,16 +4040,16 @@ ${rootContent}`;
|
|
|
3825
4040
|
});
|
|
3826
4041
|
return null;
|
|
3827
4042
|
}
|
|
3828
|
-
const
|
|
3829
|
-
|
|
4043
|
+
const metadataLine = metadataOutput.trim();
|
|
4044
|
+
const parsed = parseCommitLine(metadataLine);
|
|
4045
|
+
if (!parsed) {
|
|
3830
4046
|
this.log("[GitService] Unexpected metadata format", "warning", {
|
|
3831
4047
|
commitSha,
|
|
3832
|
-
|
|
4048
|
+
metadataLine
|
|
3833
4049
|
});
|
|
3834
4050
|
return null;
|
|
3835
4051
|
}
|
|
3836
|
-
const
|
|
3837
|
-
const timestamp = new Date(timestampStr);
|
|
4052
|
+
const timestamp = new Date(parsed.timestamp * 1e3);
|
|
3838
4053
|
this.log("[GitService] Local commit data retrieved", "debug", {
|
|
3839
4054
|
commitSha,
|
|
3840
4055
|
diffSizeBytes,
|
|
@@ -3842,7 +4057,10 @@ ${rootContent}`;
|
|
|
3842
4057
|
});
|
|
3843
4058
|
return {
|
|
3844
4059
|
diff,
|
|
3845
|
-
timestamp
|
|
4060
|
+
timestamp,
|
|
4061
|
+
author: parsed.author,
|
|
4062
|
+
committer: parsed.committer,
|
|
4063
|
+
coAuthors: parsed.coAuthors
|
|
3846
4064
|
};
|
|
3847
4065
|
} catch (error) {
|
|
3848
4066
|
const errorMessage = `Failed to get local commit data: ${error.message}`;
|
|
@@ -3860,11 +4078,11 @@ import * as os3 from "os";
|
|
|
3860
4078
|
import path6 from "path";
|
|
3861
4079
|
import chalk3 from "chalk";
|
|
3862
4080
|
import { withFile } from "tmp-promise";
|
|
3863
|
-
import
|
|
4081
|
+
import z27 from "zod";
|
|
3864
4082
|
|
|
3865
4083
|
// src/commands/handleMobbLogin.ts
|
|
3866
4084
|
import chalk2 from "chalk";
|
|
3867
|
-
import
|
|
4085
|
+
import Debug7 from "debug";
|
|
3868
4086
|
|
|
3869
4087
|
// src/utils/dirname.ts
|
|
3870
4088
|
import fs from "fs";
|
|
@@ -4085,10 +4303,8 @@ var errorMessages = {
|
|
|
4085
4303
|
var VUL_REPORT_DIGEST_TIMEOUT_MS = 1e3 * 60 * 30;
|
|
4086
4304
|
|
|
4087
4305
|
// src/features/analysis/graphql/gql.ts
|
|
4088
|
-
import
|
|
4089
|
-
import Debug5 from "debug";
|
|
4306
|
+
import Debug6 from "debug";
|
|
4090
4307
|
import { GraphQLClient } from "graphql-request";
|
|
4091
|
-
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
4092
4308
|
import { v4 as uuidv4 } from "uuid";
|
|
4093
4309
|
|
|
4094
4310
|
// src/mcp/core/Errors.ts
|
|
@@ -4118,6 +4334,71 @@ var ScanContext = {
|
|
|
4118
4334
|
BUGSY: "BUGSY"
|
|
4119
4335
|
};
|
|
4120
4336
|
|
|
4337
|
+
// src/utils/proxy.ts
|
|
4338
|
+
import fetchOrig from "cross-fetch";
|
|
4339
|
+
import Debug2 from "debug";
|
|
4340
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
4341
|
+
|
|
4342
|
+
// src/utils/url.ts
|
|
4343
|
+
function httpToWsUrl(url) {
|
|
4344
|
+
const parsed = new URL(url);
|
|
4345
|
+
parsed.protocol = parsed.protocol === "https:" ? "wss:" : "ws:";
|
|
4346
|
+
return parsed.toString();
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4349
|
+
// src/utils/proxy.ts
|
|
4350
|
+
var debug2 = Debug2("mobbdev:proxy");
|
|
4351
|
+
function getHttpProxy() {
|
|
4352
|
+
return process.env["HTTPS_PROXY"] || process.env["HTTP_PROXY"] || "";
|
|
4353
|
+
}
|
|
4354
|
+
function getHttpProxyOnly() {
|
|
4355
|
+
return process.env["HTTP_PROXY"] || "";
|
|
4356
|
+
}
|
|
4357
|
+
function getProxyAgent(url) {
|
|
4358
|
+
try {
|
|
4359
|
+
const parsedUrl = new URL(url);
|
|
4360
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
4361
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
|
|
4362
|
+
debug2("Skipping proxy for localhost URL: %s", url);
|
|
4363
|
+
return void 0;
|
|
4364
|
+
}
|
|
4365
|
+
const noProxy = process.env["NO_PROXY"] || process.env["no_proxy"];
|
|
4366
|
+
if (noProxy) {
|
|
4367
|
+
const noProxyList = noProxy.split(",").map((h) => h.trim().toLowerCase());
|
|
4368
|
+
if (noProxyList.includes(hostname) || noProxyList.includes("*")) {
|
|
4369
|
+
debug2("Skipping proxy due to NO_PROXY for: %s", url);
|
|
4370
|
+
return void 0;
|
|
4371
|
+
}
|
|
4372
|
+
}
|
|
4373
|
+
const isHttp = parsedUrl.protocol === "http:";
|
|
4374
|
+
const isHttps = parsedUrl.protocol === "https:";
|
|
4375
|
+
const proxy = isHttps ? getHttpProxy() : isHttp ? getHttpProxyOnly() : null;
|
|
4376
|
+
if (proxy) {
|
|
4377
|
+
debug2("Using proxy %s", proxy);
|
|
4378
|
+
debug2("Proxy agent %o", proxy);
|
|
4379
|
+
return new HttpsProxyAgent(proxy);
|
|
4380
|
+
}
|
|
4381
|
+
} catch (err) {
|
|
4382
|
+
debug2(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
4383
|
+
}
|
|
4384
|
+
return void 0;
|
|
4385
|
+
}
|
|
4386
|
+
var fetchWithProxy = (url, options = {}) => {
|
|
4387
|
+
try {
|
|
4388
|
+
const agent = getProxyAgent(url.toString());
|
|
4389
|
+
if (agent) {
|
|
4390
|
+
return fetchOrig(url, {
|
|
4391
|
+
...options,
|
|
4392
|
+
// @ts-expect-error Node-fetch doesn't type 'agent', but it's valid
|
|
4393
|
+
agent
|
|
4394
|
+
});
|
|
4395
|
+
}
|
|
4396
|
+
} catch (err) {
|
|
4397
|
+
debug2(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
4398
|
+
}
|
|
4399
|
+
return fetchOrig(url, options);
|
|
4400
|
+
};
|
|
4401
|
+
|
|
4121
4402
|
// src/utils/subscribe/subscribe.ts
|
|
4122
4403
|
import { createClient } from "graphql-ws";
|
|
4123
4404
|
import WebsocketNode from "isomorphic-ws";
|
|
@@ -4146,11 +4427,11 @@ function getGraphQlHeaders(options) {
|
|
|
4146
4427
|
}
|
|
4147
4428
|
|
|
4148
4429
|
// src/utils/subscribe/subscribe.ts
|
|
4149
|
-
var DEFAULT_API_URL2 = "
|
|
4430
|
+
var DEFAULT_API_URL2 = "wss://api.mobb.ai/v1/graphql";
|
|
4150
4431
|
var SUBSCRIPTION_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
4151
4432
|
function createWSClient(options) {
|
|
4152
|
-
const url = options.url || (process.env["API_URL"]
|
|
4153
|
-
const websocketImpl = options.websocket ||
|
|
4433
|
+
const url = options.url || (process.env["API_URL"] ? httpToWsUrl(process.env["API_URL"]) : DEFAULT_API_URL2);
|
|
4434
|
+
const websocketImpl = options.websocket || WebsocketNode;
|
|
4154
4435
|
const CustomWebSocket = options.proxyAgent ? (
|
|
4155
4436
|
// biome-ignore lint/suspicious/noExplicitAny: Dynamic WebSocket extension requires any cast for cross-platform compatibility
|
|
4156
4437
|
class extends websocketImpl {
|
|
@@ -6169,7 +6450,7 @@ var DEFUALT_ADO_ORIGIN = scmCloudUrl.Ado;
|
|
|
6169
6450
|
init_env();
|
|
6170
6451
|
import querystring from "querystring";
|
|
6171
6452
|
import * as api from "azure-devops-node-api";
|
|
6172
|
-
import
|
|
6453
|
+
import Debug3 from "debug";
|
|
6173
6454
|
import { z as z18 } from "zod";
|
|
6174
6455
|
|
|
6175
6456
|
// src/features/analysis/scm/ado/validation.ts
|
|
@@ -6208,7 +6489,7 @@ var accountsZ = z17.object({
|
|
|
6208
6489
|
});
|
|
6209
6490
|
|
|
6210
6491
|
// src/features/analysis/scm/ado/utils.ts
|
|
6211
|
-
var
|
|
6492
|
+
var debug3 = Debug3("mobbdev:scm:ado");
|
|
6212
6493
|
|
|
6213
6494
|
// src/features/analysis/scm/ado/AdoSCMLib.ts
|
|
6214
6495
|
import { setTimeout as setTimeout2 } from "timers/promises";
|
|
@@ -6220,39 +6501,39 @@ init_GitService();
|
|
|
6220
6501
|
import querystring2 from "querystring";
|
|
6221
6502
|
import * as bitbucketPkgNode from "bitbucket";
|
|
6222
6503
|
import bitbucketPkg from "bitbucket";
|
|
6223
|
-
import
|
|
6224
|
-
import { z as
|
|
6504
|
+
import Debug4 from "debug";
|
|
6505
|
+
import { z as z21 } from "zod";
|
|
6225
6506
|
|
|
6226
6507
|
// src/features/analysis/scm/bitbucket/validation.ts
|
|
6227
|
-
import { z as
|
|
6228
|
-
var BitbucketAuthResultZ =
|
|
6229
|
-
access_token:
|
|
6230
|
-
token_type:
|
|
6231
|
-
refresh_token:
|
|
6508
|
+
import { z as z20 } from "zod";
|
|
6509
|
+
var BitbucketAuthResultZ = z20.object({
|
|
6510
|
+
access_token: z20.string(),
|
|
6511
|
+
token_type: z20.string(),
|
|
6512
|
+
refresh_token: z20.string()
|
|
6232
6513
|
});
|
|
6233
6514
|
|
|
6234
6515
|
// src/features/analysis/scm/bitbucket/bitbucket.ts
|
|
6235
|
-
var
|
|
6516
|
+
var debug4 = Debug4("scm:bitbucket");
|
|
6236
6517
|
var BITBUCKET_HOSTNAME = "bitbucket.org";
|
|
6237
|
-
var TokenExpiredErrorZ =
|
|
6238
|
-
status:
|
|
6239
|
-
error:
|
|
6240
|
-
type:
|
|
6241
|
-
error:
|
|
6242
|
-
message:
|
|
6518
|
+
var TokenExpiredErrorZ = z21.object({
|
|
6519
|
+
status: z21.number(),
|
|
6520
|
+
error: z21.object({
|
|
6521
|
+
type: z21.string(),
|
|
6522
|
+
error: z21.object({
|
|
6523
|
+
message: z21.string()
|
|
6243
6524
|
})
|
|
6244
6525
|
})
|
|
6245
6526
|
});
|
|
6246
6527
|
var BITBUCKET_ACCESS_TOKEN_URL = `https://${BITBUCKET_HOSTNAME}/site/oauth2/access_token`;
|
|
6247
|
-
var BitbucketParseResultZ =
|
|
6248
|
-
organization:
|
|
6249
|
-
repoName:
|
|
6250
|
-
hostname:
|
|
6528
|
+
var BitbucketParseResultZ = z21.object({
|
|
6529
|
+
organization: z21.string(),
|
|
6530
|
+
repoName: z21.string(),
|
|
6531
|
+
hostname: z21.literal(BITBUCKET_HOSTNAME)
|
|
6251
6532
|
});
|
|
6252
6533
|
|
|
6253
6534
|
// src/features/analysis/scm/bitbucket/BitbucketSCMLib.ts
|
|
6254
6535
|
import { setTimeout as setTimeout3 } from "timers/promises";
|
|
6255
|
-
import { z as
|
|
6536
|
+
import { z as z22 } from "zod";
|
|
6256
6537
|
|
|
6257
6538
|
// src/features/analysis/scm/constants.ts
|
|
6258
6539
|
var REPORT_DEFAULT_FILE_NAME = "report.json";
|
|
@@ -6261,7 +6542,7 @@ var REPORT_DEFAULT_FILE_NAME = "report.json";
|
|
|
6261
6542
|
init_env();
|
|
6262
6543
|
|
|
6263
6544
|
// src/features/analysis/scm/github/GithubSCMLib.ts
|
|
6264
|
-
import { z as
|
|
6545
|
+
import { z as z23 } from "zod";
|
|
6265
6546
|
init_client_generates();
|
|
6266
6547
|
|
|
6267
6548
|
// src/features/analysis/scm/github/github.ts
|
|
@@ -6283,7 +6564,7 @@ import {
|
|
|
6283
6564
|
AccessLevel,
|
|
6284
6565
|
Gitlab
|
|
6285
6566
|
} from "@gitbeaker/rest";
|
|
6286
|
-
import
|
|
6567
|
+
import Debug5 from "debug";
|
|
6287
6568
|
import pLimit from "p-limit";
|
|
6288
6569
|
import {
|
|
6289
6570
|
Agent,
|
|
@@ -6293,151 +6574,107 @@ import {
|
|
|
6293
6574
|
|
|
6294
6575
|
// src/utils/contextLogger.ts
|
|
6295
6576
|
import debugModule from "debug";
|
|
6296
|
-
var
|
|
6577
|
+
var debug5 = debugModule("mobb:shared");
|
|
6297
6578
|
|
|
6298
6579
|
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
6299
6580
|
init_env();
|
|
6300
6581
|
|
|
6301
6582
|
// src/features/analysis/scm/gitlab/types.ts
|
|
6302
|
-
import { z as
|
|
6303
|
-
var GitlabAuthResultZ =
|
|
6304
|
-
access_token:
|
|
6305
|
-
token_type:
|
|
6306
|
-
refresh_token:
|
|
6583
|
+
import { z as z24 } from "zod";
|
|
6584
|
+
var GitlabAuthResultZ = z24.object({
|
|
6585
|
+
access_token: z24.string(),
|
|
6586
|
+
token_type: z24.string(),
|
|
6587
|
+
refresh_token: z24.string()
|
|
6307
6588
|
});
|
|
6308
6589
|
|
|
6309
6590
|
// src/features/analysis/scm/gitlab/gitlab.ts
|
|
6310
|
-
var
|
|
6591
|
+
var debug6 = Debug5("scm:gitlab");
|
|
6311
6592
|
|
|
6312
6593
|
// src/features/analysis/scm/gitlab/GitlabSCMLib.ts
|
|
6313
6594
|
init_client_generates();
|
|
6314
6595
|
|
|
6315
6596
|
// src/features/analysis/scm/scmFactory.ts
|
|
6316
|
-
import { z as
|
|
6597
|
+
import { z as z25 } from "zod";
|
|
6317
6598
|
|
|
6318
6599
|
// src/features/analysis/graphql/gql.ts
|
|
6319
6600
|
init_client_generates();
|
|
6320
6601
|
|
|
6321
6602
|
// src/features/analysis/graphql/types.ts
|
|
6322
6603
|
init_client_generates();
|
|
6323
|
-
import { z as
|
|
6324
|
-
var VulnerabilityReportIssueCodeNodeZ =
|
|
6325
|
-
vulnerabilityReportIssueId:
|
|
6326
|
-
path:
|
|
6327
|
-
startLine:
|
|
6328
|
-
vulnerabilityReportIssue:
|
|
6329
|
-
fixId:
|
|
6330
|
-
category:
|
|
6331
|
-
safeIssueType:
|
|
6332
|
-
vulnerabilityReportIssueTags:
|
|
6333
|
-
|
|
6334
|
-
tag:
|
|
6604
|
+
import { z as z26 } from "zod";
|
|
6605
|
+
var VulnerabilityReportIssueCodeNodeZ = z26.object({
|
|
6606
|
+
vulnerabilityReportIssueId: z26.string(),
|
|
6607
|
+
path: z26.string(),
|
|
6608
|
+
startLine: z26.number(),
|
|
6609
|
+
vulnerabilityReportIssue: z26.object({
|
|
6610
|
+
fixId: z26.string(),
|
|
6611
|
+
category: z26.nativeEnum(Vulnerability_Report_Issue_Category_Enum),
|
|
6612
|
+
safeIssueType: z26.string(),
|
|
6613
|
+
vulnerabilityReportIssueTags: z26.array(
|
|
6614
|
+
z26.object({
|
|
6615
|
+
tag: z26.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
|
|
6335
6616
|
})
|
|
6336
6617
|
)
|
|
6337
6618
|
})
|
|
6338
6619
|
});
|
|
6339
|
-
var VulnerabilityReportIssueNoFixCodeNodeZ =
|
|
6340
|
-
vulnerabilityReportIssues:
|
|
6341
|
-
|
|
6342
|
-
id:
|
|
6343
|
-
fixId:
|
|
6344
|
-
category:
|
|
6345
|
-
safeIssueType:
|
|
6346
|
-
fpId:
|
|
6347
|
-
codeNodes:
|
|
6348
|
-
|
|
6349
|
-
path:
|
|
6350
|
-
startLine:
|
|
6620
|
+
var VulnerabilityReportIssueNoFixCodeNodeZ = z26.object({
|
|
6621
|
+
vulnerabilityReportIssues: z26.array(
|
|
6622
|
+
z26.object({
|
|
6623
|
+
id: z26.string(),
|
|
6624
|
+
fixId: z26.string().nullable(),
|
|
6625
|
+
category: z26.nativeEnum(Vulnerability_Report_Issue_Category_Enum),
|
|
6626
|
+
safeIssueType: z26.string(),
|
|
6627
|
+
fpId: z26.string().uuid().nullable(),
|
|
6628
|
+
codeNodes: z26.array(
|
|
6629
|
+
z26.object({
|
|
6630
|
+
path: z26.string(),
|
|
6631
|
+
startLine: z26.number()
|
|
6351
6632
|
})
|
|
6352
6633
|
),
|
|
6353
|
-
vulnerabilityReportIssueTags:
|
|
6354
|
-
|
|
6355
|
-
tag:
|
|
6634
|
+
vulnerabilityReportIssueTags: z26.array(
|
|
6635
|
+
z26.object({
|
|
6636
|
+
tag: z26.nativeEnum(Vulnerability_Report_Issue_Tag_Enum)
|
|
6356
6637
|
})
|
|
6357
6638
|
)
|
|
6358
6639
|
})
|
|
6359
6640
|
)
|
|
6360
6641
|
});
|
|
6361
|
-
var GetVulByNodesMetadataZ =
|
|
6362
|
-
vulnerabilityReportIssueCodeNodes:
|
|
6363
|
-
nonFixablePrVuls:
|
|
6364
|
-
aggregate:
|
|
6365
|
-
count:
|
|
6642
|
+
var GetVulByNodesMetadataZ = z26.object({
|
|
6643
|
+
vulnerabilityReportIssueCodeNodes: z26.array(VulnerabilityReportIssueCodeNodeZ),
|
|
6644
|
+
nonFixablePrVuls: z26.object({
|
|
6645
|
+
aggregate: z26.object({
|
|
6646
|
+
count: z26.number()
|
|
6366
6647
|
})
|
|
6367
6648
|
}),
|
|
6368
|
-
fixablePrVuls:
|
|
6369
|
-
aggregate:
|
|
6370
|
-
count:
|
|
6649
|
+
fixablePrVuls: z26.object({
|
|
6650
|
+
aggregate: z26.object({
|
|
6651
|
+
count: z26.number()
|
|
6371
6652
|
})
|
|
6372
6653
|
}),
|
|
6373
|
-
totalScanVulnerabilities:
|
|
6374
|
-
aggregate:
|
|
6375
|
-
count:
|
|
6654
|
+
totalScanVulnerabilities: z26.object({
|
|
6655
|
+
aggregate: z26.object({
|
|
6656
|
+
count: z26.number()
|
|
6376
6657
|
})
|
|
6377
6658
|
}),
|
|
6378
|
-
irrelevantVulnerabilityReportIssue:
|
|
6659
|
+
irrelevantVulnerabilityReportIssue: z26.array(
|
|
6379
6660
|
VulnerabilityReportIssueNoFixCodeNodeZ
|
|
6380
6661
|
)
|
|
6381
6662
|
});
|
|
6382
6663
|
|
|
6383
6664
|
// src/features/analysis/graphql/gql.ts
|
|
6384
|
-
var
|
|
6665
|
+
var debug7 = Debug6("mobbdev:gql");
|
|
6385
6666
|
var API_KEY_HEADER_NAME = "x-mobb-key";
|
|
6386
6667
|
var REPORT_STATE_CHECK_DELAY = 5 * 1e3;
|
|
6387
|
-
function getProxyAgent(url) {
|
|
6388
|
-
try {
|
|
6389
|
-
const parsedUrl = new URL(url);
|
|
6390
|
-
const hostname = parsedUrl.hostname.toLowerCase();
|
|
6391
|
-
if (hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname === "[::1]") {
|
|
6392
|
-
debug6("Skipping proxy for localhost URL: %s", url);
|
|
6393
|
-
return void 0;
|
|
6394
|
-
}
|
|
6395
|
-
const noProxy = process.env["NO_PROXY"] || process.env["no_proxy"];
|
|
6396
|
-
if (noProxy) {
|
|
6397
|
-
const noProxyList = noProxy.split(",").map((h) => h.trim().toLowerCase());
|
|
6398
|
-
if (noProxyList.includes(hostname) || noProxyList.includes("*")) {
|
|
6399
|
-
debug6("Skipping proxy due to NO_PROXY for: %s", url);
|
|
6400
|
-
return void 0;
|
|
6401
|
-
}
|
|
6402
|
-
}
|
|
6403
|
-
const isHttp = parsedUrl.protocol === "http:";
|
|
6404
|
-
const isHttps = parsedUrl.protocol === "https:";
|
|
6405
|
-
const proxy = isHttps ? HTTPS_PROXY || HTTP_PROXY : isHttp ? HTTP_PROXY : null;
|
|
6406
|
-
if (proxy) {
|
|
6407
|
-
debug6("Using proxy %s", proxy);
|
|
6408
|
-
debug6("Proxy agent %o", proxy);
|
|
6409
|
-
return new HttpsProxyAgent(proxy);
|
|
6410
|
-
}
|
|
6411
|
-
} catch (err) {
|
|
6412
|
-
debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
6413
|
-
}
|
|
6414
|
-
return void 0;
|
|
6415
|
-
}
|
|
6416
|
-
var fetchWithProxy = (url, options = {}) => {
|
|
6417
|
-
try {
|
|
6418
|
-
const agent = getProxyAgent(url.toString());
|
|
6419
|
-
if (agent) {
|
|
6420
|
-
return fetchOrig(url, {
|
|
6421
|
-
...options,
|
|
6422
|
-
// @ts-expect-error Node-fetch doesn't type 'agent', but it's valid
|
|
6423
|
-
agent
|
|
6424
|
-
});
|
|
6425
|
-
}
|
|
6426
|
-
} catch (err) {
|
|
6427
|
-
debug6(`Skipping proxy for ${url}. Reason: ${err.message}`);
|
|
6428
|
-
}
|
|
6429
|
-
return fetchOrig(url, options);
|
|
6430
|
-
};
|
|
6431
6668
|
var GQLClient = class {
|
|
6432
6669
|
constructor(args) {
|
|
6433
6670
|
__publicField(this, "_client");
|
|
6434
6671
|
__publicField(this, "_clientSdk");
|
|
6435
6672
|
__publicField(this, "_apiUrl");
|
|
6436
6673
|
__publicField(this, "_auth");
|
|
6437
|
-
|
|
6674
|
+
debug7(`init with ${args}`);
|
|
6438
6675
|
this._auth = args;
|
|
6439
6676
|
this._apiUrl = args.apiUrl || API_URL;
|
|
6440
|
-
|
|
6677
|
+
debug7(
|
|
6441
6678
|
"GQLClient constructor: resolved apiUrl=%s (from param: %s)",
|
|
6442
6679
|
this._apiUrl,
|
|
6443
6680
|
args.apiUrl || "fallback to API_URL constant"
|
|
@@ -6449,7 +6686,7 @@ var GQLClient = class {
|
|
|
6449
6686
|
fetch: fetchWithProxy,
|
|
6450
6687
|
requestMiddleware: (request) => {
|
|
6451
6688
|
const requestId = uuidv4();
|
|
6452
|
-
|
|
6689
|
+
debug7(
|
|
6453
6690
|
`sending API request with id: ${requestId} and with request: ${request.body}`
|
|
6454
6691
|
);
|
|
6455
6692
|
return {
|
|
@@ -6486,7 +6723,7 @@ var GQLClient = class {
|
|
|
6486
6723
|
await this.getUserInfo();
|
|
6487
6724
|
} catch (e) {
|
|
6488
6725
|
if (e?.toString().startsWith("FetchError")) {
|
|
6489
|
-
|
|
6726
|
+
debug7("verify connection failed %o", e);
|
|
6490
6727
|
return false;
|
|
6491
6728
|
}
|
|
6492
6729
|
}
|
|
@@ -6498,7 +6735,7 @@ var GQLClient = class {
|
|
|
6498
6735
|
try {
|
|
6499
6736
|
info = await this.getUserInfo();
|
|
6500
6737
|
} catch (e) {
|
|
6501
|
-
|
|
6738
|
+
debug7("verify token failed %o", e);
|
|
6502
6739
|
return false;
|
|
6503
6740
|
}
|
|
6504
6741
|
return info?.email || true;
|
|
@@ -6559,7 +6796,7 @@ var GQLClient = class {
|
|
|
6559
6796
|
try {
|
|
6560
6797
|
await this._clientSdk.CreateCommunityUser();
|
|
6561
6798
|
} catch (e) {
|
|
6562
|
-
|
|
6799
|
+
debug7("create community user failed %o", e);
|
|
6563
6800
|
}
|
|
6564
6801
|
}
|
|
6565
6802
|
async updateScmToken(args) {
|
|
@@ -6739,11 +6976,13 @@ var GQLClient = class {
|
|
|
6739
6976
|
this._auth.type === "apiKey" ? {
|
|
6740
6977
|
apiKey: this._auth.apiKey,
|
|
6741
6978
|
type: "apiKey",
|
|
6979
|
+
url: httpToWsUrl(this._apiUrl),
|
|
6742
6980
|
timeoutInMs: params.timeoutInMs,
|
|
6743
6981
|
proxyAgent: getProxyAgent(this._apiUrl)
|
|
6744
6982
|
} : {
|
|
6745
6983
|
token: this._auth.token,
|
|
6746
6984
|
type: "token",
|
|
6985
|
+
url: httpToWsUrl(this._apiUrl),
|
|
6747
6986
|
timeoutInMs: params.timeoutInMs,
|
|
6748
6987
|
proxyAgent: getProxyAgent(this._apiUrl)
|
|
6749
6988
|
}
|
|
@@ -6756,7 +6995,7 @@ var GQLClient = class {
|
|
|
6756
6995
|
const startTime = Date.now();
|
|
6757
6996
|
const maxDuration = timeoutInMs ?? 30 * 60 * 1e3;
|
|
6758
6997
|
const pollingIntervalSec = REPORT_STATE_CHECK_DELAY / 1e3;
|
|
6759
|
-
|
|
6998
|
+
debug7(
|
|
6760
6999
|
`[pollForAnalysisState] Starting polling for analysis ${analysisId}, target states: ${callbackStates.join(", ")}, interval: ${pollingIntervalSec}s`
|
|
6761
7000
|
);
|
|
6762
7001
|
let isPolling = true;
|
|
@@ -6765,7 +7004,7 @@ var GQLClient = class {
|
|
|
6765
7004
|
pollCount++;
|
|
6766
7005
|
const elapsedSec = Math.round((Date.now() - startTime) / 1e3);
|
|
6767
7006
|
if (Date.now() - startTime > maxDuration) {
|
|
6768
|
-
|
|
7007
|
+
debug7(
|
|
6769
7008
|
`[pollForAnalysisState] Timeout expired after ${pollCount} polls (${elapsedSec}s)`
|
|
6770
7009
|
);
|
|
6771
7010
|
throw new ReportDigestError(
|
|
@@ -6773,20 +7012,20 @@ var GQLClient = class {
|
|
|
6773
7012
|
`Analysis timed out after ${Math.round(maxDuration / 6e4)} minutes. Please try again or check the Mobb platform for status.`
|
|
6774
7013
|
);
|
|
6775
7014
|
}
|
|
6776
|
-
|
|
7015
|
+
debug7(
|
|
6777
7016
|
`[pollForAnalysisState] Poll #${pollCount} (elapsed: ${elapsedSec}s) - fetching analysis state...`
|
|
6778
7017
|
);
|
|
6779
7018
|
const analysis = await this.getAnalysis(analysisId);
|
|
6780
|
-
|
|
7019
|
+
debug7(
|
|
6781
7020
|
`[pollForAnalysisState] Poll #${pollCount} - current state: ${analysis.state}`
|
|
6782
7021
|
);
|
|
6783
7022
|
if (!analysis.state || analysis.state === "Failed" /* Failed */) {
|
|
6784
7023
|
const errorMessage = analysis.failReason || `Analysis failed with id: ${analysis.id}`;
|
|
6785
|
-
|
|
7024
|
+
debug7(`[pollForAnalysisState] Analysis failed: ${errorMessage}`);
|
|
6786
7025
|
throw new ReportDigestError(errorMessage, analysis.failReason ?? "");
|
|
6787
7026
|
}
|
|
6788
7027
|
if (callbackStates.includes(analysis.state)) {
|
|
6789
|
-
|
|
7028
|
+
debug7(
|
|
6790
7029
|
`[pollForAnalysisState] Target state reached: ${analysis.state} after ${pollCount} polls (${elapsedSec}s)`
|
|
6791
7030
|
);
|
|
6792
7031
|
await callback(analysis.id);
|
|
@@ -6799,7 +7038,7 @@ var GQLClient = class {
|
|
|
6799
7038
|
}
|
|
6800
7039
|
};
|
|
6801
7040
|
}
|
|
6802
|
-
|
|
7041
|
+
debug7(
|
|
6803
7042
|
`[pollForAnalysisState] State ${analysis.state} not in target states, waiting ${pollingIntervalSec}s before next poll...`
|
|
6804
7043
|
);
|
|
6805
7044
|
await sleep(REPORT_STATE_CHECK_DELAY);
|
|
@@ -7068,7 +7307,7 @@ var AuthManager = class {
|
|
|
7068
7307
|
};
|
|
7069
7308
|
|
|
7070
7309
|
// src/commands/handleMobbLogin.ts
|
|
7071
|
-
var
|
|
7310
|
+
var debug8 = Debug7("mobbdev:commands");
|
|
7072
7311
|
var LOGIN_MAX_WAIT2 = 10 * 60 * 1e3;
|
|
7073
7312
|
var LOGIN_CHECK_DELAY2 = 5 * 1e3;
|
|
7074
7313
|
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(
|
|
@@ -7080,7 +7319,7 @@ async function getAuthenticatedGQLClient({
|
|
|
7080
7319
|
apiUrl,
|
|
7081
7320
|
webAppUrl
|
|
7082
7321
|
}) {
|
|
7083
|
-
|
|
7322
|
+
debug8(
|
|
7084
7323
|
"getAuthenticatedGQLClient called with: apiUrl=%s, webAppUrl=%s",
|
|
7085
7324
|
apiUrl || "undefined",
|
|
7086
7325
|
webAppUrl || "undefined"
|
|
@@ -7103,7 +7342,7 @@ async function handleMobbLogin({
|
|
|
7103
7342
|
webAppUrl,
|
|
7104
7343
|
loginContext
|
|
7105
7344
|
}) {
|
|
7106
|
-
|
|
7345
|
+
debug8(
|
|
7107
7346
|
"handleMobbLogin: resolved URLs - apiUrl=%s (from param: %s), webAppUrl=%s (from param: %s)",
|
|
7108
7347
|
apiUrl || "fallback",
|
|
7109
7348
|
apiUrl || "fallback",
|
|
@@ -7122,7 +7361,7 @@ async function handleMobbLogin({
|
|
|
7122
7361
|
return authManager.getGQLClient();
|
|
7123
7362
|
}
|
|
7124
7363
|
} catch (error) {
|
|
7125
|
-
|
|
7364
|
+
debug8("Authentication check failed:", error);
|
|
7126
7365
|
}
|
|
7127
7366
|
if (apiKey) {
|
|
7128
7367
|
createSpinner().start().error({
|
|
@@ -7174,9 +7413,9 @@ init_GitService();
|
|
|
7174
7413
|
init_urlParser2();
|
|
7175
7414
|
|
|
7176
7415
|
// src/features/analysis/upload-file.ts
|
|
7177
|
-
import
|
|
7416
|
+
import Debug8 from "debug";
|
|
7178
7417
|
import fetch3, { File, fileFrom, FormData } from "node-fetch";
|
|
7179
|
-
var
|
|
7418
|
+
var debug9 = Debug8("mobbdev:upload-file");
|
|
7180
7419
|
async function uploadFile({
|
|
7181
7420
|
file,
|
|
7182
7421
|
url,
|
|
@@ -7189,9 +7428,9 @@ async function uploadFile({
|
|
|
7189
7428
|
logInfo(`FileUpload: upload file start ${url}`);
|
|
7190
7429
|
logInfo(`FileUpload: upload fields`, uploadFields);
|
|
7191
7430
|
logInfo(`FileUpload: upload key ${uploadKey}`);
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7431
|
+
debug9("upload file start %s", url);
|
|
7432
|
+
debug9("upload fields %o", uploadFields);
|
|
7433
|
+
debug9("upload key %s", uploadKey);
|
|
7195
7434
|
const form = new FormData();
|
|
7196
7435
|
Object.entries(uploadFields).forEach(([key, value]) => {
|
|
7197
7436
|
form.append(key, value);
|
|
@@ -7200,11 +7439,11 @@ async function uploadFile({
|
|
|
7200
7439
|
form.append("key", uploadKey);
|
|
7201
7440
|
}
|
|
7202
7441
|
if (typeof file === "string") {
|
|
7203
|
-
|
|
7442
|
+
debug9("upload file from path %s", file);
|
|
7204
7443
|
logInfo(`FileUpload: upload file from path ${file}`);
|
|
7205
7444
|
form.append("file", await fileFrom(file));
|
|
7206
7445
|
} else {
|
|
7207
|
-
|
|
7446
|
+
debug9("upload file from buffer");
|
|
7208
7447
|
logInfo(`FileUpload: upload file from buffer`);
|
|
7209
7448
|
form.append("file", new File([new Uint8Array(file)], "file"));
|
|
7210
7449
|
}
|
|
@@ -7215,11 +7454,11 @@ async function uploadFile({
|
|
|
7215
7454
|
agent
|
|
7216
7455
|
});
|
|
7217
7456
|
if (!response.ok) {
|
|
7218
|
-
|
|
7457
|
+
debug9("error from S3 %s %s", response.body, response.status);
|
|
7219
7458
|
logInfo(`FileUpload: error from S3 ${response.body} ${response.status}`);
|
|
7220
7459
|
throw new Error(`Failed to upload the file: ${response.status}`);
|
|
7221
7460
|
}
|
|
7222
|
-
|
|
7461
|
+
debug9("upload file done");
|
|
7223
7462
|
logInfo(`FileUpload: upload file done`);
|
|
7224
7463
|
}
|
|
7225
7464
|
|
|
@@ -7317,7 +7556,8 @@ import { OpenRedaction } from "@openredaction/openredaction";
|
|
|
7317
7556
|
var openRedaction = new OpenRedaction({
|
|
7318
7557
|
patterns: [
|
|
7319
7558
|
// Core Personal Data
|
|
7320
|
-
|
|
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.
|
|
7321
7561
|
"SSN",
|
|
7322
7562
|
"NATIONAL_INSURANCE_UK",
|
|
7323
7563
|
"DATE_OF_BIRTH",
|
|
@@ -7332,7 +7572,8 @@ var openRedaction = new OpenRedaction({
|
|
|
7332
7572
|
"VISA_MRZ",
|
|
7333
7573
|
"TAX_ID",
|
|
7334
7574
|
// Financial Data (removed SWIFT_BIC, CARD_AUTH_CODE - too broad, causing false positives with authentication words)
|
|
7335
|
-
|
|
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.
|
|
7336
7577
|
"IBAN",
|
|
7337
7578
|
"BANK_ACCOUNT_UK",
|
|
7338
7579
|
"ROUTING_NUMBER_US",
|
|
@@ -7418,15 +7659,6 @@ async function sanitizeDataWithCounts(obj) {
|
|
|
7418
7659
|
...piiDetections.low
|
|
7419
7660
|
];
|
|
7420
7661
|
for (const detection of allDetections) {
|
|
7421
|
-
if (detection.type === "CREDIT_CARD") {
|
|
7422
|
-
const start = detection.position[0];
|
|
7423
|
-
const end = detection.position[1];
|
|
7424
|
-
const charBefore = (start > 0 ? str[start - 1] : "") ?? "";
|
|
7425
|
-
const charAfter = str[end] ?? "";
|
|
7426
|
-
if (charBefore === "." || charBefore >= "0" && charBefore <= "9" || charAfter >= "0" && charAfter <= "9") {
|
|
7427
|
-
continue;
|
|
7428
|
-
}
|
|
7429
|
-
}
|
|
7430
7662
|
counts.detections.total++;
|
|
7431
7663
|
if (detection.severity === "high") counts.detections.high++;
|
|
7432
7664
|
else if (detection.severity === "medium") counts.detections.medium++;
|
|
@@ -7479,8 +7711,8 @@ var defaultLogger = {
|
|
|
7479
7711
|
}
|
|
7480
7712
|
}
|
|
7481
7713
|
};
|
|
7482
|
-
var PromptItemZ =
|
|
7483
|
-
type:
|
|
7714
|
+
var PromptItemZ = z27.object({
|
|
7715
|
+
type: z27.enum([
|
|
7484
7716
|
"USER_PROMPT",
|
|
7485
7717
|
"AI_RESPONSE",
|
|
7486
7718
|
"TOOL_EXECUTION",
|
|
@@ -7488,32 +7720,32 @@ var PromptItemZ = z26.object({
|
|
|
7488
7720
|
"MCP_TOOL_CALL"
|
|
7489
7721
|
// MCP (Model Context Protocol) tool invocation
|
|
7490
7722
|
]),
|
|
7491
|
-
attachedFiles:
|
|
7492
|
-
|
|
7493
|
-
relativePath:
|
|
7494
|
-
startLine:
|
|
7723
|
+
attachedFiles: z27.array(
|
|
7724
|
+
z27.object({
|
|
7725
|
+
relativePath: z27.string(),
|
|
7726
|
+
startLine: z27.number().optional()
|
|
7495
7727
|
})
|
|
7496
7728
|
).optional(),
|
|
7497
|
-
tokens:
|
|
7498
|
-
inputCount:
|
|
7499
|
-
outputCount:
|
|
7729
|
+
tokens: z27.object({
|
|
7730
|
+
inputCount: z27.number(),
|
|
7731
|
+
outputCount: z27.number()
|
|
7500
7732
|
}).optional(),
|
|
7501
|
-
text:
|
|
7502
|
-
date:
|
|
7503
|
-
tool:
|
|
7504
|
-
name:
|
|
7505
|
-
parameters:
|
|
7506
|
-
result:
|
|
7507
|
-
rawArguments:
|
|
7508
|
-
accepted:
|
|
7733
|
+
text: z27.string().optional(),
|
|
7734
|
+
date: z27.date().optional(),
|
|
7735
|
+
tool: z27.object({
|
|
7736
|
+
name: z27.string(),
|
|
7737
|
+
parameters: z27.string(),
|
|
7738
|
+
result: z27.string(),
|
|
7739
|
+
rawArguments: z27.string().optional(),
|
|
7740
|
+
accepted: z27.boolean().optional(),
|
|
7509
7741
|
// MCP-specific fields (only populated for MCP_TOOL_CALL type)
|
|
7510
|
-
mcpServer:
|
|
7742
|
+
mcpServer: z27.string().optional(),
|
|
7511
7743
|
// MCP server name (e.g., "datadog", "mobb-mcp")
|
|
7512
|
-
mcpToolName:
|
|
7744
|
+
mcpToolName: z27.string().optional()
|
|
7513
7745
|
// MCP tool name without prefix (e.g., "scan_and_fix_vulnerabilities")
|
|
7514
7746
|
}).optional()
|
|
7515
7747
|
});
|
|
7516
|
-
var PromptItemArrayZ =
|
|
7748
|
+
var PromptItemArrayZ = z27.array(PromptItemZ);
|
|
7517
7749
|
async function getRepositoryUrl() {
|
|
7518
7750
|
try {
|
|
7519
7751
|
const gitService = new GitService(process.cwd());
|