securewithtrace 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -6
- package/dist/index.js +911 -167
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3682,7 +3682,7 @@ function extractCommandTree(cmd) {
|
|
|
3682
3682
|
description: o.description,
|
|
3683
3683
|
takesValue: o.required || o.optional
|
|
3684
3684
|
}));
|
|
3685
|
-
const subcommands = cmd.commands.filter((
|
|
3685
|
+
const subcommands = cmd.commands.filter((c25) => !c25._hidden).map((c25) => extractCommandTree(c25));
|
|
3686
3686
|
return {
|
|
3687
3687
|
name: cmd.name(),
|
|
3688
3688
|
description: cmd.description(),
|
|
@@ -3748,7 +3748,7 @@ function generateBashCompletion(tree, binName) {
|
|
|
3748
3748
|
}
|
|
3749
3749
|
function collectBashCases(tree, prefix) {
|
|
3750
3750
|
const cases = /* @__PURE__ */ new Map();
|
|
3751
|
-
const subcommandNames = tree.subcommands.map((
|
|
3751
|
+
const subcommandNames = tree.subcommands.map((c25) => c25.name);
|
|
3752
3752
|
const optionNames = tree.options.flatMap((o) => o.short ? [o.long, o.short] : [o.long]);
|
|
3753
3753
|
const extraOptions = prefix === "" ? ["--help", "--version"] : ["--help"];
|
|
3754
3754
|
const allOptions = [.../* @__PURE__ */ new Set([...optionNames, ...extraOptions])];
|
|
@@ -10803,7 +10803,7 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
|
|
|
10803
10803
|
function isValidBase64URL(data) {
|
|
10804
10804
|
if (!base64url.test(data))
|
|
10805
10805
|
return false;
|
|
10806
|
-
const base643 = data.replace(/[-_]/g, (
|
|
10806
|
+
const base643 = data.replace(/[-_]/g, (c25) => c25 === "-" ? "+" : "/");
|
|
10807
10807
|
const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "=");
|
|
10808
10808
|
return isValidBase64(padded);
|
|
10809
10809
|
}
|
|
@@ -20847,9 +20847,9 @@ var ZodDate2 = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
|
|
|
20847
20847
|
inst._zod.processJSONSchema = (ctx, json2, params) => dateProcessor(inst, ctx, json2, params);
|
|
20848
20848
|
inst.min = (value, params) => inst.check(_gte(value, params));
|
|
20849
20849
|
inst.max = (value, params) => inst.check(_lte(value, params));
|
|
20850
|
-
const
|
|
20851
|
-
inst.minDate =
|
|
20852
|
-
inst.maxDate =
|
|
20850
|
+
const c25 = inst._zod.bag;
|
|
20851
|
+
inst.minDate = c25.minimum ? new Date(c25.minimum) : null;
|
|
20852
|
+
inst.maxDate = c25.maximum ? new Date(c25.maximum) : null;
|
|
20853
20853
|
});
|
|
20854
20854
|
function date3(params) {
|
|
20855
20855
|
return _date(ZodDate2, params);
|
|
@@ -22161,6 +22161,331 @@ var chatSessionContract = c2.router({
|
|
|
22161
22161
|
}
|
|
22162
22162
|
});
|
|
22163
22163
|
|
|
22164
|
+
// ../../packages/api-contracts/src/schemas/domain/dependency.schema.ts
|
|
22165
|
+
var PackageEcosystemValues = [
|
|
22166
|
+
"NPM",
|
|
22167
|
+
"PYPI",
|
|
22168
|
+
"CARGO",
|
|
22169
|
+
"MAVEN",
|
|
22170
|
+
"GOLANG",
|
|
22171
|
+
"RUBYGEMS",
|
|
22172
|
+
"NUGET",
|
|
22173
|
+
"COMPOSER",
|
|
22174
|
+
"UNKNOWN"
|
|
22175
|
+
];
|
|
22176
|
+
var PackageEcosystem = external_exports.enum(PackageEcosystemValues);
|
|
22177
|
+
var DependencyScopeValues = ["PRODUCTION", "DEV", "PEER", "OPTIONAL", "BUNDLED"];
|
|
22178
|
+
var DependencyScope = external_exports.enum(DependencyScopeValues);
|
|
22179
|
+
var DependencySourceValues = ["REGISTRY", "WORKSPACE", "GIT", "FILE", "URL"];
|
|
22180
|
+
var DependencySource = external_exports.enum(DependencySourceValues);
|
|
22181
|
+
var DependencyIndexStatusValues = [
|
|
22182
|
+
"PENDING",
|
|
22183
|
+
"INDEXING",
|
|
22184
|
+
"COMPLETED",
|
|
22185
|
+
"PARTIAL",
|
|
22186
|
+
"FAILED"
|
|
22187
|
+
];
|
|
22188
|
+
var DependencyIndexStatus = external_exports.enum(DependencyIndexStatusValues);
|
|
22189
|
+
|
|
22190
|
+
// ../../packages/api-contracts/src/schemas/api/v1/dependency.api.ts
|
|
22191
|
+
var RepositoryDependencyParamsSchema = OrgIdParamsSchema.extend({
|
|
22192
|
+
repositoryId: external_exports.uuid()
|
|
22193
|
+
});
|
|
22194
|
+
var PackageDependencyParamsSchema = OrgIdParamsSchema.extend({
|
|
22195
|
+
packageId: external_exports.uuid()
|
|
22196
|
+
});
|
|
22197
|
+
var FailedManifestSchema = external_exports.object({
|
|
22198
|
+
filePath: external_exports.string(),
|
|
22199
|
+
ecosystem: PackageEcosystem,
|
|
22200
|
+
error: external_exports.string(),
|
|
22201
|
+
severity: external_exports.enum(["warning", "error"])
|
|
22202
|
+
});
|
|
22203
|
+
var VersionEntrySchema = external_exports.object({
|
|
22204
|
+
version: external_exports.string(),
|
|
22205
|
+
versionConstraint: external_exports.string().nullable(),
|
|
22206
|
+
isDirect: external_exports.boolean(),
|
|
22207
|
+
scope: DependencyScope,
|
|
22208
|
+
source: DependencySource,
|
|
22209
|
+
depthFromRoot: external_exports.number(),
|
|
22210
|
+
/** Manifest files where this specific version appears. */
|
|
22211
|
+
manifestFiles: external_exports.array(external_exports.string())
|
|
22212
|
+
});
|
|
22213
|
+
var DependencyIndexSchema = external_exports.object({
|
|
22214
|
+
indexId: external_exports.uuid(),
|
|
22215
|
+
status: DependencyIndexStatus,
|
|
22216
|
+
commitSha: external_exports.string().nullable(),
|
|
22217
|
+
packageCount: external_exports.number(),
|
|
22218
|
+
ecosystems: external_exports.array(PackageEcosystem),
|
|
22219
|
+
manifestFiles: external_exports.array(external_exports.string()),
|
|
22220
|
+
failedManifests: external_exports.array(FailedManifestSchema),
|
|
22221
|
+
durationMs: external_exports.number().nullable(),
|
|
22222
|
+
indexedAt: external_exports.coerce.date().nullable(),
|
|
22223
|
+
errorMessage: external_exports.string().nullable(),
|
|
22224
|
+
createdAt: external_exports.coerce.date()
|
|
22225
|
+
});
|
|
22226
|
+
var DependencySearchRequestSchema = external_exports.object({
|
|
22227
|
+
query: external_exports.string().min(1).max(200),
|
|
22228
|
+
ecosystem: PackageEcosystem.optional(),
|
|
22229
|
+
isDirect: external_exports.boolean().optional(),
|
|
22230
|
+
scope: DependencyScope.optional(),
|
|
22231
|
+
repositoryIds: external_exports.array(external_exports.uuid()).optional(),
|
|
22232
|
+
/** Exact version match, e.g. "1.2.3". */
|
|
22233
|
+
version: external_exports.string().max(100).optional(),
|
|
22234
|
+
/** Version prefix match, e.g. "1.2" matches "1.2.0", "1.2.3", etc. */
|
|
22235
|
+
versionPrefix: external_exports.string().max(50).optional(),
|
|
22236
|
+
page: external_exports.number().int().min(1).default(1).optional(),
|
|
22237
|
+
pageSize: external_exports.number().int().min(1).max(100).default(20).optional(),
|
|
22238
|
+
sortBy: external_exports.enum(["name", "repositoryCount"]).default("repositoryCount").optional(),
|
|
22239
|
+
sortOrder: external_exports.enum(["asc", "desc"]).default("desc").optional()
|
|
22240
|
+
});
|
|
22241
|
+
var PackageSearchResultSchema = external_exports.object({
|
|
22242
|
+
packageId: external_exports.uuid(),
|
|
22243
|
+
name: external_exports.string(),
|
|
22244
|
+
ecosystem: PackageEcosystem,
|
|
22245
|
+
repositories: external_exports.array(
|
|
22246
|
+
external_exports.object({
|
|
22247
|
+
repositoryId: external_exports.uuid(),
|
|
22248
|
+
fullName: external_exports.string(),
|
|
22249
|
+
/** All resolved versions of this package in this repository. */
|
|
22250
|
+
versions: external_exports.array(VersionEntrySchema)
|
|
22251
|
+
})
|
|
22252
|
+
)
|
|
22253
|
+
});
|
|
22254
|
+
var DependencySearchResponseSchema = external_exports.object({
|
|
22255
|
+
packages: external_exports.array(PackageSearchResultSchema),
|
|
22256
|
+
total: external_exports.number(),
|
|
22257
|
+
page: external_exports.number(),
|
|
22258
|
+
pageSize: external_exports.number()
|
|
22259
|
+
});
|
|
22260
|
+
var DependencyAutocompleteQuerySchema = external_exports.object({
|
|
22261
|
+
q: external_exports.string().min(1).max(200),
|
|
22262
|
+
ecosystem: external_exports.enum(PackageEcosystemValues).optional()
|
|
22263
|
+
});
|
|
22264
|
+
var AutocompleteSuggestionSchema = external_exports.object({
|
|
22265
|
+
packageId: external_exports.uuid(),
|
|
22266
|
+
name: external_exports.string(),
|
|
22267
|
+
ecosystem: PackageEcosystem,
|
|
22268
|
+
repositoryCount: external_exports.number()
|
|
22269
|
+
});
|
|
22270
|
+
var DependencyAutocompleteResponseSchema = external_exports.object({
|
|
22271
|
+
suggestions: external_exports.array(AutocompleteSuggestionSchema)
|
|
22272
|
+
});
|
|
22273
|
+
var ListRepoDependenciesQuerySchema = external_exports.object({
|
|
22274
|
+
search: external_exports.string().max(200).optional(),
|
|
22275
|
+
isDirect: external_exports.enum(["true", "false"]).transform((v) => v === "true").optional(),
|
|
22276
|
+
scope: DependencyScope.optional(),
|
|
22277
|
+
ecosystem: external_exports.enum(PackageEcosystemValues).optional(),
|
|
22278
|
+
/** Exact version match, e.g. "1.2.3". */
|
|
22279
|
+
version: external_exports.string().max(100).optional(),
|
|
22280
|
+
/** Version prefix match, e.g. "1.2" matches "1.2.0", "1.2.3", etc. */
|
|
22281
|
+
versionPrefix: external_exports.string().max(50).optional(),
|
|
22282
|
+
page: external_exports.coerce.number().int().min(1).default(1).optional(),
|
|
22283
|
+
pageSize: external_exports.coerce.number().int().min(1).max(200).default(50).optional(),
|
|
22284
|
+
sortBy: external_exports.enum(["name", "ecosystem"]).default("name").optional(),
|
|
22285
|
+
sortOrder: external_exports.enum(["asc", "desc"]).default("asc").optional()
|
|
22286
|
+
});
|
|
22287
|
+
var RepoDependencySchema = external_exports.object({
|
|
22288
|
+
packageId: external_exports.uuid(),
|
|
22289
|
+
name: external_exports.string(),
|
|
22290
|
+
ecosystem: PackageEcosystem,
|
|
22291
|
+
/** All resolved versions of this package in the repository. */
|
|
22292
|
+
versions: external_exports.array(VersionEntrySchema)
|
|
22293
|
+
});
|
|
22294
|
+
var ListRepoDependenciesResponseSchema = external_exports.object({
|
|
22295
|
+
dependencies: external_exports.array(RepoDependencySchema),
|
|
22296
|
+
total: external_exports.number(),
|
|
22297
|
+
page: external_exports.number(),
|
|
22298
|
+
pageSize: external_exports.number(),
|
|
22299
|
+
/** All manifest files discovered in this repository. */
|
|
22300
|
+
manifestFiles: external_exports.array(external_exports.string())
|
|
22301
|
+
});
|
|
22302
|
+
var PackageRepositoriesQuerySchema = external_exports.object({
|
|
22303
|
+
/** Exact version match, e.g. "1.2.3". */
|
|
22304
|
+
version: external_exports.string().max(100).optional(),
|
|
22305
|
+
/** Version prefix match, e.g. "1.2" matches "1.2.0", "1.2.3", etc. */
|
|
22306
|
+
versionPrefix: external_exports.string().max(50).optional(),
|
|
22307
|
+
page: external_exports.coerce.number().int().min(1).default(1).optional(),
|
|
22308
|
+
pageSize: external_exports.coerce.number().int().min(1).max(100).default(25).optional()
|
|
22309
|
+
});
|
|
22310
|
+
var PackageRepositoriesResponseSchema = external_exports.object({
|
|
22311
|
+
repositories: external_exports.array(
|
|
22312
|
+
external_exports.object({
|
|
22313
|
+
repositoryId: external_exports.uuid(),
|
|
22314
|
+
fullName: external_exports.string(),
|
|
22315
|
+
htmlUrl: external_exports.string().nullable(),
|
|
22316
|
+
/** All resolved versions of this package in this repository. */
|
|
22317
|
+
versions: external_exports.array(VersionEntrySchema)
|
|
22318
|
+
})
|
|
22319
|
+
),
|
|
22320
|
+
total: external_exports.number(),
|
|
22321
|
+
page: external_exports.number(),
|
|
22322
|
+
pageSize: external_exports.number()
|
|
22323
|
+
});
|
|
22324
|
+
var DependencyIndexResponseSchema = external_exports.object({
|
|
22325
|
+
latestIndex: DependencyIndexSchema.nullable()
|
|
22326
|
+
});
|
|
22327
|
+
var TriggerReindexResponseSchema = external_exports.object({
|
|
22328
|
+
indexId: external_exports.uuid(),
|
|
22329
|
+
status: DependencyIndexStatus
|
|
22330
|
+
});
|
|
22331
|
+
var BulkIndexStatusResponseSchema = external_exports.object({
|
|
22332
|
+
repositories: external_exports.array(
|
|
22333
|
+
external_exports.object({
|
|
22334
|
+
repositoryId: external_exports.uuid(),
|
|
22335
|
+
fullName: external_exports.string(),
|
|
22336
|
+
status: DependencyIndexStatus.nullable(),
|
|
22337
|
+
packageCount: external_exports.number().nullable(),
|
|
22338
|
+
indexedAt: external_exports.coerce.date().nullable()
|
|
22339
|
+
})
|
|
22340
|
+
)
|
|
22341
|
+
});
|
|
22342
|
+
var DependencyFilterOptionsResponseSchema = external_exports.object({
|
|
22343
|
+
/** Repositories that have at least one indexed dependency. */
|
|
22344
|
+
repositories: external_exports.array(
|
|
22345
|
+
external_exports.object({
|
|
22346
|
+
repositoryId: external_exports.uuid(),
|
|
22347
|
+
name: external_exports.string()
|
|
22348
|
+
})
|
|
22349
|
+
),
|
|
22350
|
+
ecosystems: external_exports.array(PackageEcosystem),
|
|
22351
|
+
scopes: external_exports.array(DependencyScope)
|
|
22352
|
+
});
|
|
22353
|
+
var DependencySummaryResponseSchema = external_exports.object({
|
|
22354
|
+
totalPackages: external_exports.number(),
|
|
22355
|
+
totalRepositories: external_exports.number(),
|
|
22356
|
+
ecosystemBreakdown: external_exports.record(PackageEcosystem, external_exports.number()),
|
|
22357
|
+
lastIndexedAt: external_exports.coerce.date().nullable(),
|
|
22358
|
+
indexingInProgress: external_exports.number()
|
|
22359
|
+
});
|
|
22360
|
+
|
|
22361
|
+
// ../../packages/api-contracts/src/contracts/v1/dependency.ts
|
|
22362
|
+
var c3 = initContract();
|
|
22363
|
+
var dependencyContract = c3.router({
|
|
22364
|
+
/** Cross-repo dependency search. Two-phase: pg_trgm on Package, then join repos. */
|
|
22365
|
+
searchDependencies: {
|
|
22366
|
+
method: "POST",
|
|
22367
|
+
path: "/organizations/:organizationId/dependencies/search",
|
|
22368
|
+
pathParams: OrgIdParamsSchema,
|
|
22369
|
+
body: DependencySearchRequestSchema,
|
|
22370
|
+
responses: {
|
|
22371
|
+
200: DependencySearchResponseSchema,
|
|
22372
|
+
400: ErrorResponseSchema,
|
|
22373
|
+
401: ErrorResponseSchema,
|
|
22374
|
+
403: ErrorResponseSchema,
|
|
22375
|
+
404: ErrorResponseSchema,
|
|
22376
|
+
500: ErrorResponseSchema
|
|
22377
|
+
}
|
|
22378
|
+
},
|
|
22379
|
+
/** Autocomplete for dependency names across all repos in org. */
|
|
22380
|
+
autocompleteDependencies: {
|
|
22381
|
+
method: "GET",
|
|
22382
|
+
path: "/organizations/:organizationId/dependencies/autocomplete",
|
|
22383
|
+
pathParams: OrgIdParamsSchema,
|
|
22384
|
+
query: DependencyAutocompleteQuerySchema,
|
|
22385
|
+
responses: {
|
|
22386
|
+
200: DependencyAutocompleteResponseSchema,
|
|
22387
|
+
401: ErrorResponseSchema,
|
|
22388
|
+
403: ErrorResponseSchema,
|
|
22389
|
+
404: ErrorResponseSchema,
|
|
22390
|
+
500: ErrorResponseSchema
|
|
22391
|
+
}
|
|
22392
|
+
},
|
|
22393
|
+
/** List dependencies for a specific repository, deduplicated by package. */
|
|
22394
|
+
listRepositoryDependencies: {
|
|
22395
|
+
method: "GET",
|
|
22396
|
+
path: "/organizations/:organizationId/repositories/:repositoryId/dependencies",
|
|
22397
|
+
pathParams: RepositoryDependencyParamsSchema,
|
|
22398
|
+
query: ListRepoDependenciesQuerySchema,
|
|
22399
|
+
responses: {
|
|
22400
|
+
200: ListRepoDependenciesResponseSchema,
|
|
22401
|
+
401: ErrorResponseSchema,
|
|
22402
|
+
403: ErrorResponseSchema,
|
|
22403
|
+
404: ErrorResponseSchema,
|
|
22404
|
+
500: ErrorResponseSchema
|
|
22405
|
+
}
|
|
22406
|
+
},
|
|
22407
|
+
/** Reverse lookup: which repositories use a given package. */
|
|
22408
|
+
listPackageRepositories: {
|
|
22409
|
+
method: "GET",
|
|
22410
|
+
path: "/organizations/:organizationId/dependencies/packages/:packageId/repositories",
|
|
22411
|
+
pathParams: PackageDependencyParamsSchema,
|
|
22412
|
+
query: PackageRepositoriesQuerySchema,
|
|
22413
|
+
responses: {
|
|
22414
|
+
200: PackageRepositoriesResponseSchema,
|
|
22415
|
+
401: ErrorResponseSchema,
|
|
22416
|
+
403: ErrorResponseSchema,
|
|
22417
|
+
404: ErrorResponseSchema,
|
|
22418
|
+
500: ErrorResponseSchema
|
|
22419
|
+
}
|
|
22420
|
+
},
|
|
22421
|
+
/** Get dependency indexing status for a repository. */
|
|
22422
|
+
getDependencyIndex: {
|
|
22423
|
+
method: "GET",
|
|
22424
|
+
path: "/organizations/:organizationId/repositories/:repositoryId/dependency-index",
|
|
22425
|
+
pathParams: RepositoryDependencyParamsSchema,
|
|
22426
|
+
responses: {
|
|
22427
|
+
200: DependencyIndexResponseSchema,
|
|
22428
|
+
401: ErrorResponseSchema,
|
|
22429
|
+
403: ErrorResponseSchema,
|
|
22430
|
+
404: ErrorResponseSchema,
|
|
22431
|
+
500: ErrorResponseSchema
|
|
22432
|
+
}
|
|
22433
|
+
},
|
|
22434
|
+
/** Trigger a manual re-index of a repository's dependencies. */
|
|
22435
|
+
triggerReindex: {
|
|
22436
|
+
method: "POST",
|
|
22437
|
+
path: "/organizations/:organizationId/repositories/:repositoryId/dependency-index",
|
|
22438
|
+
pathParams: RepositoryDependencyParamsSchema,
|
|
22439
|
+
body: null,
|
|
22440
|
+
responses: {
|
|
22441
|
+
201: TriggerReindexResponseSchema,
|
|
22442
|
+
401: ErrorResponseSchema,
|
|
22443
|
+
403: ErrorResponseSchema,
|
|
22444
|
+
404: ErrorResponseSchema,
|
|
22445
|
+
500: ErrorResponseSchema
|
|
22446
|
+
}
|
|
22447
|
+
},
|
|
22448
|
+
/** Available filter options for dependency search dropdowns. */
|
|
22449
|
+
getFilterOptions: {
|
|
22450
|
+
method: "GET",
|
|
22451
|
+
path: "/organizations/:organizationId/dependencies/filter-options",
|
|
22452
|
+
pathParams: OrgIdParamsSchema,
|
|
22453
|
+
responses: {
|
|
22454
|
+
200: DependencyFilterOptionsResponseSchema,
|
|
22455
|
+
401: ErrorResponseSchema,
|
|
22456
|
+
403: ErrorResponseSchema,
|
|
22457
|
+
404: ErrorResponseSchema,
|
|
22458
|
+
500: ErrorResponseSchema
|
|
22459
|
+
}
|
|
22460
|
+
},
|
|
22461
|
+
/** Bulk index status for all repos in org (dashboard view). */
|
|
22462
|
+
getBulkIndexStatus: {
|
|
22463
|
+
method: "GET",
|
|
22464
|
+
path: "/organizations/:organizationId/dependencies/index-status",
|
|
22465
|
+
pathParams: OrgIdParamsSchema,
|
|
22466
|
+
responses: {
|
|
22467
|
+
200: BulkIndexStatusResponseSchema,
|
|
22468
|
+
401: ErrorResponseSchema,
|
|
22469
|
+
403: ErrorResponseSchema,
|
|
22470
|
+
404: ErrorResponseSchema,
|
|
22471
|
+
500: ErrorResponseSchema
|
|
22472
|
+
}
|
|
22473
|
+
},
|
|
22474
|
+
/** Org-wide dependency summary with ecosystem breakdown. */
|
|
22475
|
+
getDependencySummary: {
|
|
22476
|
+
method: "GET",
|
|
22477
|
+
path: "/organizations/:organizationId/dependencies/summary",
|
|
22478
|
+
pathParams: OrgIdParamsSchema,
|
|
22479
|
+
responses: {
|
|
22480
|
+
200: DependencySummaryResponseSchema,
|
|
22481
|
+
401: ErrorResponseSchema,
|
|
22482
|
+
403: ErrorResponseSchema,
|
|
22483
|
+
404: ErrorResponseSchema,
|
|
22484
|
+
500: ErrorResponseSchema
|
|
22485
|
+
}
|
|
22486
|
+
}
|
|
22487
|
+
});
|
|
22488
|
+
|
|
22164
22489
|
// ../../packages/api-contracts/src/schemas/api/v1/docker-scout-integration.api.ts
|
|
22165
22490
|
var DockerScoutIntegrationIdParamsSchema = OrgIdParamsSchema.extend({
|
|
22166
22491
|
dockerScoutIntegrationId: external_exports.uuid()
|
|
@@ -22180,8 +22505,8 @@ var DockerScoutIntegrationResponseSchema = external_exports.object({
|
|
|
22180
22505
|
});
|
|
22181
22506
|
|
|
22182
22507
|
// ../../packages/api-contracts/src/contracts/v1/docker-scout-integration.ts
|
|
22183
|
-
var
|
|
22184
|
-
var dockerScoutIntegrationContract =
|
|
22508
|
+
var c4 = initContract();
|
|
22509
|
+
var dockerScoutIntegrationContract = c4.router({
|
|
22185
22510
|
createDockerScoutIntegration: {
|
|
22186
22511
|
method: "POST",
|
|
22187
22512
|
path: "/organizations/:organizationId/docker-scout-integration",
|
|
@@ -22242,9 +22567,7 @@ var GitHubCallbackQuerySchema = external_exports.object({
|
|
|
22242
22567
|
});
|
|
22243
22568
|
var GitHubCallbackRequestSchema = external_exports.object({
|
|
22244
22569
|
installationId: external_exports.number().int(),
|
|
22245
|
-
setupAction: external_exports.enum(["install", "update", "request"])
|
|
22246
|
-
githubAccountId: external_exports.number().int().optional(),
|
|
22247
|
-
githubAccountLogin: external_exports.string().min(1).optional()
|
|
22570
|
+
setupAction: external_exports.enum(["install", "update", "request"])
|
|
22248
22571
|
});
|
|
22249
22572
|
var GitHubInstallationResponseSchema = external_exports.object({
|
|
22250
22573
|
installationId: external_exports.uuid(),
|
|
@@ -22274,13 +22597,14 @@ var GitHubRepoSchema = external_exports.object({
|
|
|
22274
22597
|
fullName: external_exports.string(),
|
|
22275
22598
|
private: external_exports.boolean(),
|
|
22276
22599
|
htmlUrl: external_exports.string().url(),
|
|
22277
|
-
defaultBranch: external_exports.string()
|
|
22600
|
+
defaultBranch: external_exports.string(),
|
|
22601
|
+
language: external_exports.string().nullable()
|
|
22278
22602
|
});
|
|
22279
22603
|
var ListGitHubInstallationReposResponseSchema = external_exports.array(GitHubRepoSchema);
|
|
22280
22604
|
|
|
22281
22605
|
// ../../packages/api-contracts/src/contracts/v1/github.ts
|
|
22282
|
-
var
|
|
22283
|
-
var githubCallbackContract =
|
|
22606
|
+
var c5 = initContract();
|
|
22607
|
+
var githubCallbackContract = c5.router(
|
|
22284
22608
|
{
|
|
22285
22609
|
handleCallback: {
|
|
22286
22610
|
method: "POST",
|
|
@@ -22300,7 +22624,7 @@ var githubCallbackContract = c4.router(
|
|
|
22300
22624
|
pathPrefix: "/v1/github"
|
|
22301
22625
|
}
|
|
22302
22626
|
);
|
|
22303
|
-
var githubContract =
|
|
22627
|
+
var githubContract = c5.router({
|
|
22304
22628
|
generateInstallLink: {
|
|
22305
22629
|
method: "POST",
|
|
22306
22630
|
path: "/organizations/:organizationId/github/install-link",
|
|
@@ -22370,8 +22694,8 @@ var UpdateKnowledgeBaseResponseSchema = external_exports.object({
|
|
|
22370
22694
|
});
|
|
22371
22695
|
|
|
22372
22696
|
// ../../packages/api-contracts/src/contracts/v1/knowledge-base.ts
|
|
22373
|
-
var
|
|
22374
|
-
var knowledgeBaseContract =
|
|
22697
|
+
var c6 = initContract();
|
|
22698
|
+
var knowledgeBaseContract = c6.router({
|
|
22375
22699
|
getKnowledgeBase: {
|
|
22376
22700
|
method: "GET",
|
|
22377
22701
|
path: "/organizations/:organizationId/knowledge-base",
|
|
@@ -22592,8 +22916,8 @@ var UpdateRepoDocumentContentResponseSchema = external_exports.object({
|
|
|
22592
22916
|
});
|
|
22593
22917
|
|
|
22594
22918
|
// ../../packages/api-contracts/src/contracts/v1/knowledge-document.ts
|
|
22595
|
-
var
|
|
22596
|
-
var knowledgeDocumentContract =
|
|
22919
|
+
var c7 = initContract();
|
|
22920
|
+
var knowledgeDocumentContract = c7.router({
|
|
22597
22921
|
createDocument: {
|
|
22598
22922
|
method: "POST",
|
|
22599
22923
|
path: "/organizations/:organizationId/knowledge-documents",
|
|
@@ -22902,8 +23226,8 @@ var LlmProviderKeyResponseSchema = external_exports.object({
|
|
|
22902
23226
|
var ListLlmProviderKeysResponseSchema = external_exports.array(LlmProviderKeyResponseSchema);
|
|
22903
23227
|
|
|
22904
23228
|
// ../../packages/api-contracts/src/contracts/v1/llm-provider-key.ts
|
|
22905
|
-
var
|
|
22906
|
-
var llmProviderKeyContract =
|
|
23229
|
+
var c8 = initContract();
|
|
23230
|
+
var llmProviderKeyContract = c8.router({
|
|
22907
23231
|
createLlmProviderKey: {
|
|
22908
23232
|
method: "POST",
|
|
22909
23233
|
path: "/organizations/:organizationId/llm-provider-keys",
|
|
@@ -23018,8 +23342,8 @@ var LogoDeleteRequestSchema = external_exports.object({
|
|
|
23018
23342
|
});
|
|
23019
23343
|
|
|
23020
23344
|
// ../../packages/api-contracts/src/contracts/v1/organization.ts
|
|
23021
|
-
var
|
|
23022
|
-
var organizationContract =
|
|
23345
|
+
var c9 = initContract();
|
|
23346
|
+
var organizationContract = c9.router({
|
|
23023
23347
|
listOrganizations: {
|
|
23024
23348
|
method: "GET",
|
|
23025
23349
|
path: "/organizations",
|
|
@@ -23101,10 +23425,12 @@ var PentestStatusValues = ["SCOPING", "IN_PROGRESS", "REMEDIATION", "CLOSED"];
|
|
|
23101
23425
|
var PentestStatus = external_exports.enum(PentestStatusValues);
|
|
23102
23426
|
var PentestFindingStatusValues = [
|
|
23103
23427
|
"OPEN",
|
|
23428
|
+
"IN_PROGRESS",
|
|
23104
23429
|
"CONTESTED",
|
|
23105
23430
|
"REMEDIATED",
|
|
23106
23431
|
"VERIFIED_FIXED",
|
|
23107
|
-
"VERIFIED_OPEN"
|
|
23432
|
+
"VERIFIED_OPEN",
|
|
23433
|
+
"DISMISSED"
|
|
23108
23434
|
];
|
|
23109
23435
|
var PentestFindingStatus = external_exports.enum(PentestFindingStatusValues);
|
|
23110
23436
|
var PentestFindingSeverityValues = [
|
|
@@ -23129,7 +23455,7 @@ var RetestOutcome = external_exports.enum(RetestOutcomeValues);
|
|
|
23129
23455
|
|
|
23130
23456
|
// ../../packages/api-contracts/src/schemas/api/v1/pentest.api.ts
|
|
23131
23457
|
var PentestIdParamsSchema = OrgIdParamsSchema.extend({
|
|
23132
|
-
pentestId: external_exports.
|
|
23458
|
+
pentestId: external_exports.string().min(1)
|
|
23133
23459
|
});
|
|
23134
23460
|
var PentestResponseSchema = external_exports.object({
|
|
23135
23461
|
pentestId: external_exports.uuid(),
|
|
@@ -23170,8 +23496,8 @@ var UpdatePentestRequestSchema = external_exports.object({
|
|
|
23170
23496
|
});
|
|
23171
23497
|
|
|
23172
23498
|
// ../../packages/api-contracts/src/contracts/v1/pentest.ts
|
|
23173
|
-
var
|
|
23174
|
-
var pentestContract =
|
|
23499
|
+
var c10 = initContract();
|
|
23500
|
+
var pentestContract = c10.router({
|
|
23175
23501
|
listPentests: {
|
|
23176
23502
|
method: "GET",
|
|
23177
23503
|
path: "/organizations/:organizationId/pentests",
|
|
@@ -23276,12 +23602,15 @@ var PentestFindingResponseSchema = external_exports.object({
|
|
|
23276
23602
|
cvssVector: external_exports.string().nullable(),
|
|
23277
23603
|
cvssScore: external_exports.number().nullable(),
|
|
23278
23604
|
owaspCategory: external_exports.string().nullable(),
|
|
23605
|
+
proofOfConcept: external_exports.string().nullable(),
|
|
23606
|
+
remediation: external_exports.string().nullable(),
|
|
23279
23607
|
publishedAt: external_exports.coerce.date().nullable(),
|
|
23280
23608
|
createdById: external_exports.uuid(),
|
|
23281
23609
|
createdByName: external_exports.string(),
|
|
23282
23610
|
createdAt: external_exports.coerce.date(),
|
|
23283
23611
|
updatedAt: external_exports.coerce.date(),
|
|
23284
|
-
repositories: external_exports.array(PentestFindingRepositorySchema)
|
|
23612
|
+
repositories: external_exports.array(PentestFindingRepositorySchema),
|
|
23613
|
+
vulnerabilityIds: external_exports.array(external_exports.uuid())
|
|
23285
23614
|
});
|
|
23286
23615
|
var ListPentestFindingsResponseSchema = external_exports.array(PentestFindingResponseSchema);
|
|
23287
23616
|
var CreatePentestFindingRequestSchema = external_exports.object({
|
|
@@ -23294,6 +23623,8 @@ var CreatePentestFindingRequestSchema = external_exports.object({
|
|
|
23294
23623
|
cvssVector: external_exports.string().max(200).optional(),
|
|
23295
23624
|
cvssScore: external_exports.number().min(0).max(10).optional(),
|
|
23296
23625
|
owaspCategory: external_exports.string().max(200).optional(),
|
|
23626
|
+
proofOfConcept: external_exports.string().max(5e4).optional(),
|
|
23627
|
+
remediation: external_exports.string().max(5e4).optional(),
|
|
23297
23628
|
repositories: external_exports.array(
|
|
23298
23629
|
external_exports.object({
|
|
23299
23630
|
repositoryId: external_exports.uuid(),
|
|
@@ -23302,7 +23633,8 @@ var CreatePentestFindingRequestSchema = external_exports.object({
|
|
|
23302
23633
|
startLine: external_exports.number().int().optional(),
|
|
23303
23634
|
endLine: external_exports.number().int().optional()
|
|
23304
23635
|
})
|
|
23305
|
-
).optional()
|
|
23636
|
+
).optional(),
|
|
23637
|
+
vulnerabilityIds: external_exports.array(external_exports.uuid()).optional()
|
|
23306
23638
|
});
|
|
23307
23639
|
var UpdatePentestFindingRequestSchema = external_exports.object({
|
|
23308
23640
|
title: external_exports.string().min(1).max(500).optional(),
|
|
@@ -23314,6 +23646,8 @@ var UpdatePentestFindingRequestSchema = external_exports.object({
|
|
|
23314
23646
|
cvssVector: external_exports.string().max(200).nullable().optional(),
|
|
23315
23647
|
cvssScore: external_exports.number().min(0).max(10).nullable().optional(),
|
|
23316
23648
|
owaspCategory: external_exports.string().max(200).nullable().optional(),
|
|
23649
|
+
proofOfConcept: external_exports.string().max(5e4).nullable().optional(),
|
|
23650
|
+
remediation: external_exports.string().max(5e4).nullable().optional(),
|
|
23317
23651
|
publishedAt: external_exports.coerce.date().nullable().optional(),
|
|
23318
23652
|
repositories: external_exports.array(
|
|
23319
23653
|
external_exports.object({
|
|
@@ -23323,7 +23657,8 @@ var UpdatePentestFindingRequestSchema = external_exports.object({
|
|
|
23323
23657
|
startLine: external_exports.number().int().optional(),
|
|
23324
23658
|
endLine: external_exports.number().int().optional()
|
|
23325
23659
|
})
|
|
23326
|
-
).optional()
|
|
23660
|
+
).optional(),
|
|
23661
|
+
vulnerabilityIds: external_exports.array(external_exports.uuid()).optional()
|
|
23327
23662
|
});
|
|
23328
23663
|
var PentestFindingContestResponseSchema = external_exports.object({
|
|
23329
23664
|
contestId: external_exports.uuid(),
|
|
@@ -23384,6 +23719,13 @@ var UpdatePentestFindingNoteRequestSchema = external_exports.object({
|
|
|
23384
23719
|
var ParseFindingMarkdownRequestSchema = external_exports.object({
|
|
23385
23720
|
markdown: external_exports.string().min(1).max(1e5)
|
|
23386
23721
|
});
|
|
23722
|
+
var ParsedFindingVulnerabilitySchema = external_exports.object({
|
|
23723
|
+
title: external_exports.string(),
|
|
23724
|
+
description: external_exports.string().nullable(),
|
|
23725
|
+
affectedRepos: external_exports.array(external_exports.string()),
|
|
23726
|
+
codeSnippet: external_exports.string().nullable(),
|
|
23727
|
+
exploitConditions: external_exports.string().nullable()
|
|
23728
|
+
});
|
|
23387
23729
|
var ParseFindingMarkdownResponseSchema = external_exports.object({
|
|
23388
23730
|
title: external_exports.string(),
|
|
23389
23731
|
description: external_exports.string(),
|
|
@@ -23393,12 +23735,28 @@ var ParseFindingMarkdownResponseSchema = external_exports.object({
|
|
|
23393
23735
|
cweIds: external_exports.array(external_exports.string()),
|
|
23394
23736
|
cvssVector: external_exports.string().nullable(),
|
|
23395
23737
|
cvssScore: external_exports.number().nullable(),
|
|
23396
|
-
owaspCategory: external_exports.string().nullable()
|
|
23738
|
+
owaspCategory: external_exports.string().nullable(),
|
|
23739
|
+
proofOfConcept: external_exports.string().nullable(),
|
|
23740
|
+
remediation: external_exports.string().nullable(),
|
|
23741
|
+
vulnerabilities: external_exports.array(ParsedFindingVulnerabilitySchema)
|
|
23742
|
+
});
|
|
23743
|
+
var ParseTaskStatusSchema = external_exports.enum(["pending", "completed", "failed"]);
|
|
23744
|
+
var StartParseTaskResponseSchema = external_exports.object({
|
|
23745
|
+
taskId: external_exports.string()
|
|
23746
|
+
});
|
|
23747
|
+
var ParseTaskIdParamsSchema = PentestFindingParamsSchema.extend({
|
|
23748
|
+
taskId: external_exports.string()
|
|
23749
|
+
});
|
|
23750
|
+
var GetParseTaskStatusResponseSchema = external_exports.object({
|
|
23751
|
+
taskId: external_exports.string(),
|
|
23752
|
+
status: ParseTaskStatusSchema,
|
|
23753
|
+
result: ParseFindingMarkdownResponseSchema.nullable(),
|
|
23754
|
+
error: external_exports.string().nullable()
|
|
23397
23755
|
});
|
|
23398
23756
|
|
|
23399
23757
|
// ../../packages/api-contracts/src/contracts/v1/pentest-finding.ts
|
|
23400
|
-
var
|
|
23401
|
-
var pentestFindingContract =
|
|
23758
|
+
var c11 = initContract();
|
|
23759
|
+
var pentestFindingContract = c11.router({
|
|
23402
23760
|
// ─── Findings ───
|
|
23403
23761
|
listFindings: {
|
|
23404
23762
|
method: "GET",
|
|
@@ -23599,6 +23957,33 @@ var pentestFindingContract = c10.router({
|
|
|
23599
23957
|
404: ErrorResponseSchema,
|
|
23600
23958
|
500: ErrorResponseSchema
|
|
23601
23959
|
}
|
|
23960
|
+
},
|
|
23961
|
+
// ─── Async AI parsing (polling) ───
|
|
23962
|
+
startParseTask: {
|
|
23963
|
+
method: "POST",
|
|
23964
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/parse-markdown/tasks",
|
|
23965
|
+
pathParams: PentestFindingParamsSchema,
|
|
23966
|
+
body: ParseFindingMarkdownRequestSchema,
|
|
23967
|
+
responses: {
|
|
23968
|
+
202: StartParseTaskResponseSchema,
|
|
23969
|
+
400: ErrorResponseSchema,
|
|
23970
|
+
401: ErrorResponseSchema,
|
|
23971
|
+
403: ErrorResponseSchema,
|
|
23972
|
+
404: ErrorResponseSchema,
|
|
23973
|
+
500: ErrorResponseSchema
|
|
23974
|
+
}
|
|
23975
|
+
},
|
|
23976
|
+
getParseTaskStatus: {
|
|
23977
|
+
method: "GET",
|
|
23978
|
+
path: "/organizations/:organizationId/pentests/:pentestId/findings/parse-markdown/tasks/:taskId",
|
|
23979
|
+
pathParams: ParseTaskIdParamsSchema,
|
|
23980
|
+
responses: {
|
|
23981
|
+
200: GetParseTaskStatusResponseSchema,
|
|
23982
|
+
401: ErrorResponseSchema,
|
|
23983
|
+
403: ErrorResponseSchema,
|
|
23984
|
+
404: ErrorResponseSchema,
|
|
23985
|
+
500: ErrorResponseSchema
|
|
23986
|
+
}
|
|
23602
23987
|
}
|
|
23603
23988
|
});
|
|
23604
23989
|
|
|
@@ -23627,6 +24012,7 @@ var RepositoryResponseSchema = external_exports.object({
|
|
|
23627
24012
|
platform: external_exports.enum(PlatformValues),
|
|
23628
24013
|
status: external_exports.enum(RepositoryStatusValues),
|
|
23629
24014
|
defaultBranch: external_exports.string(),
|
|
24015
|
+
primaryLanguage: external_exports.string().nullable().optional(),
|
|
23630
24016
|
createdAt: external_exports.date(),
|
|
23631
24017
|
updatedAt: external_exports.date()
|
|
23632
24018
|
});
|
|
@@ -23640,8 +24026,8 @@ var CloneTokenResponseSchema = external_exports.object({
|
|
|
23640
24026
|
});
|
|
23641
24027
|
|
|
23642
24028
|
// ../../packages/api-contracts/src/contracts/v1/repository.ts
|
|
23643
|
-
var
|
|
23644
|
-
var repositoryContract =
|
|
24029
|
+
var c12 = initContract();
|
|
24030
|
+
var repositoryContract = c12.router({
|
|
23645
24031
|
createRepository: {
|
|
23646
24032
|
method: "POST",
|
|
23647
24033
|
path: "/organizations/:organizationId/repositories",
|
|
@@ -23839,8 +24225,8 @@ var ListScanLogsResponseSchema = external_exports.object({
|
|
|
23839
24225
|
});
|
|
23840
24226
|
|
|
23841
24227
|
// ../../packages/api-contracts/src/contracts/v1/scan.ts
|
|
23842
|
-
var
|
|
23843
|
-
var scanContract =
|
|
24228
|
+
var c13 = initContract();
|
|
24229
|
+
var scanContract = c13.router({
|
|
23844
24230
|
createScan: {
|
|
23845
24231
|
method: "POST",
|
|
23846
24232
|
path: "/organizations/:organizationId/scans",
|
|
@@ -23945,8 +24331,8 @@ var UserResponseSchema = external_exports.object({
|
|
|
23945
24331
|
var ListUsersResponseSchema = external_exports.array(UserResponseSchema);
|
|
23946
24332
|
|
|
23947
24333
|
// ../../packages/api-contracts/src/contracts/v1/user.ts
|
|
23948
|
-
var
|
|
23949
|
-
var userContract =
|
|
24334
|
+
var c14 = initContract();
|
|
24335
|
+
var userContract = c14.router({
|
|
23950
24336
|
listUsers: {
|
|
23951
24337
|
method: "GET",
|
|
23952
24338
|
path: "/organizations/:organizationId/users",
|
|
@@ -24018,8 +24404,8 @@ var VantaIntegrationResponseSchema = external_exports.object({
|
|
|
24018
24404
|
});
|
|
24019
24405
|
|
|
24020
24406
|
// ../../packages/api-contracts/src/contracts/v1/vanta-integration.ts
|
|
24021
|
-
var
|
|
24022
|
-
var vantaIntegrationContract =
|
|
24407
|
+
var c15 = initContract();
|
|
24408
|
+
var vantaIntegrationContract = c15.router({
|
|
24023
24409
|
createVantaIntegration: {
|
|
24024
24410
|
method: "POST",
|
|
24025
24411
|
path: "/organizations/:organizationId/vanta-integration",
|
|
@@ -24244,8 +24630,8 @@ var UpdateVulnerabilityRequestSchema = external_exports.object({
|
|
|
24244
24630
|
});
|
|
24245
24631
|
|
|
24246
24632
|
// ../../packages/api-contracts/src/contracts/v1/vulnerability.ts
|
|
24247
|
-
var
|
|
24248
|
-
var vulnerabilityContract =
|
|
24633
|
+
var c16 = initContract();
|
|
24634
|
+
var vulnerabilityContract = c16.router({
|
|
24249
24635
|
filterVulnerabilities: {
|
|
24250
24636
|
method: "POST",
|
|
24251
24637
|
path: "/organizations/:organizationId/vulnerabilities/filter",
|
|
@@ -24383,15 +24769,15 @@ var VulnerabilityNoteResponseSchema = external_exports.object({
|
|
|
24383
24769
|
});
|
|
24384
24770
|
var ListVulnerabilityNotesResponseSchema = external_exports.array(VulnerabilityNoteResponseSchema);
|
|
24385
24771
|
var CreateVulnerabilityNoteRequestSchema = external_exports.object({
|
|
24386
|
-
content: external_exports.string().
|
|
24772
|
+
content: external_exports.string().max(1e4)
|
|
24387
24773
|
});
|
|
24388
24774
|
var UpdateVulnerabilityNoteRequestSchema = external_exports.object({
|
|
24389
|
-
content: external_exports.string().
|
|
24775
|
+
content: external_exports.string().max(1e4)
|
|
24390
24776
|
});
|
|
24391
24777
|
|
|
24392
24778
|
// ../../packages/api-contracts/src/contracts/v1/vulnerability-note.ts
|
|
24393
|
-
var
|
|
24394
|
-
var vulnerabilityNoteContract =
|
|
24779
|
+
var c17 = initContract();
|
|
24780
|
+
var vulnerabilityNoteContract = c17.router({
|
|
24395
24781
|
listNotes: {
|
|
24396
24782
|
method: "GET",
|
|
24397
24783
|
path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes",
|
|
@@ -24463,8 +24849,8 @@ var WebApplicationResponseSchema = external_exports.object({
|
|
|
24463
24849
|
var ListWebApplicationsResponseSchema = external_exports.array(WebApplicationResponseSchema);
|
|
24464
24850
|
|
|
24465
24851
|
// ../../packages/api-contracts/src/contracts/v1/web-application.ts
|
|
24466
|
-
var
|
|
24467
|
-
var webApplicationContract =
|
|
24852
|
+
var c18 = initContract();
|
|
24853
|
+
var webApplicationContract = c18.router({
|
|
24468
24854
|
listWebApplications: {
|
|
24469
24855
|
method: "GET",
|
|
24470
24856
|
path: "/organizations/:organizationId/web-applications",
|
|
@@ -24603,8 +24989,8 @@ var ListWebhookDeliveriesResponseSchema = external_exports.object({
|
|
|
24603
24989
|
});
|
|
24604
24990
|
|
|
24605
24991
|
// ../../packages/api-contracts/src/contracts/v1/webhook-settings.ts
|
|
24606
|
-
var
|
|
24607
|
-
var webhookSettingsContract =
|
|
24992
|
+
var c19 = initContract();
|
|
24993
|
+
var webhookSettingsContract = c19.router({
|
|
24608
24994
|
listWebhookEndpoints: {
|
|
24609
24995
|
method: "GET",
|
|
24610
24996
|
path: "/organizations/:organizationId/webhook-settings/endpoints",
|
|
@@ -24742,8 +25128,8 @@ var webhookSettingsContract = c18.router({
|
|
|
24742
25128
|
});
|
|
24743
25129
|
|
|
24744
25130
|
// ../../packages/api-contracts/src/contracts/v1/index.ts
|
|
24745
|
-
var
|
|
24746
|
-
var v1Contract =
|
|
25131
|
+
var c20 = initContract();
|
|
25132
|
+
var v1Contract = c20.router(
|
|
24747
25133
|
{
|
|
24748
25134
|
admin: adminContract,
|
|
24749
25135
|
scan: scanContract,
|
|
@@ -24762,7 +25148,8 @@ var v1Contract = c19.router(
|
|
|
24762
25148
|
webApplication: webApplicationContract,
|
|
24763
25149
|
chatSession: chatSessionContract,
|
|
24764
25150
|
pentest: pentestContract,
|
|
24765
|
-
pentestFinding: pentestFindingContract
|
|
25151
|
+
pentestFinding: pentestFindingContract,
|
|
25152
|
+
dependency: dependencyContract
|
|
24766
25153
|
},
|
|
24767
25154
|
{
|
|
24768
25155
|
pathPrefix: "/v1"
|
|
@@ -24770,8 +25157,8 @@ var v1Contract = c19.router(
|
|
|
24770
25157
|
);
|
|
24771
25158
|
|
|
24772
25159
|
// ../../packages/api-contracts/src/contracts/index.ts
|
|
24773
|
-
var
|
|
24774
|
-
var contract =
|
|
25160
|
+
var c21 = initContract();
|
|
25161
|
+
var contract = c21.router({
|
|
24775
25162
|
v1: v1Contract
|
|
24776
25163
|
});
|
|
24777
25164
|
|
|
@@ -24781,8 +25168,8 @@ var GitHubWebhookResponseSchema = external_exports.object({
|
|
|
24781
25168
|
});
|
|
24782
25169
|
|
|
24783
25170
|
// ../../packages/api-contracts/src/contracts/webhooks/github.ts
|
|
24784
|
-
var
|
|
24785
|
-
var githubWebhookContract =
|
|
25171
|
+
var c22 = initContract();
|
|
25172
|
+
var githubWebhookContract = c22.router(
|
|
24786
25173
|
{
|
|
24787
25174
|
handleWebhook: {
|
|
24788
25175
|
method: "POST",
|
|
@@ -24807,8 +25194,8 @@ var HealthResponseSchema = external_exports.object({
|
|
|
24807
25194
|
});
|
|
24808
25195
|
|
|
24809
25196
|
// ../../packages/api-contracts/src/contracts/health.ts
|
|
24810
|
-
var
|
|
24811
|
-
var healthContract =
|
|
25197
|
+
var c23 = initContract();
|
|
25198
|
+
var healthContract = c23.router({
|
|
24812
25199
|
getHealth: {
|
|
24813
25200
|
method: "GET",
|
|
24814
25201
|
path: "/health",
|
|
@@ -24857,8 +25244,8 @@ var UpdatePrVulnerabilityRequestSchema = external_exports.object({
|
|
|
24857
25244
|
});
|
|
24858
25245
|
|
|
24859
25246
|
// ../../packages/api-contracts/src/contracts/v1/pr-vulnerability.ts
|
|
24860
|
-
var
|
|
24861
|
-
var prVulnerabilityContract =
|
|
25247
|
+
var c24 = initContract();
|
|
25248
|
+
var prVulnerabilityContract = c24.router(
|
|
24862
25249
|
{
|
|
24863
25250
|
listPrVulnerabilities: {
|
|
24864
25251
|
method: "GET",
|
|
@@ -25057,6 +25444,11 @@ function formatStatus(status) {
|
|
|
25057
25444
|
}
|
|
25058
25445
|
|
|
25059
25446
|
// src/pentest/commands.ts
|
|
25447
|
+
var DEFAULT_LIMIT = 30;
|
|
25448
|
+
var MAX_LIMIT = 100;
|
|
25449
|
+
function tsvSafe(value) {
|
|
25450
|
+
return value.replace(/[\t\n\r]/g, " ");
|
|
25451
|
+
}
|
|
25060
25452
|
function formatDate(date5) {
|
|
25061
25453
|
if (!date5) {
|
|
25062
25454
|
return "\u2014";
|
|
@@ -25098,6 +25490,10 @@ async function resolvePentestId(organizationId, identifier) {
|
|
|
25098
25490
|
params: { organizationId }
|
|
25099
25491
|
})
|
|
25100
25492
|
);
|
|
25493
|
+
if (result.status === 401) {
|
|
25494
|
+
console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
|
|
25495
|
+
process.exit(1);
|
|
25496
|
+
}
|
|
25101
25497
|
if (result.status !== 200) {
|
|
25102
25498
|
console.error(`Failed to list pentests (status ${result.status}).`);
|
|
25103
25499
|
process.exit(1);
|
|
@@ -25113,30 +25509,72 @@ Run \`tracecli pentest list\` to see available pentests.`
|
|
|
25113
25509
|
return pentest.pentestId;
|
|
25114
25510
|
}
|
|
25115
25511
|
function createListCommand() {
|
|
25116
|
-
return new Command("list").description("List pentests for your organization").option(
|
|
25512
|
+
return new Command("list").description("List pentests for your organization").option(
|
|
25513
|
+
"-L, --limit <n>",
|
|
25514
|
+
`Max results to return (default: ${DEFAULT_LIMIT}, max: ${MAX_LIMIT})`,
|
|
25515
|
+
(v) => {
|
|
25516
|
+
const n = Number.parseInt(v, 10);
|
|
25517
|
+
if (Number.isNaN(n) || n < 1) {
|
|
25518
|
+
throw new Error("--limit must be a positive integer");
|
|
25519
|
+
}
|
|
25520
|
+
return Math.min(n, MAX_LIMIT);
|
|
25521
|
+
}
|
|
25522
|
+
).option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
25523
|
+
"after",
|
|
25524
|
+
`
|
|
25525
|
+
Examples:
|
|
25526
|
+
tracecli pentest list
|
|
25527
|
+
tracecli pentest list --limit 10
|
|
25528
|
+
tracecli pentest list --output json | jq '.[].title'
|
|
25529
|
+
tracecli pentest list --output tsv | cut -f1,2`
|
|
25530
|
+
).action(async (options) => {
|
|
25117
25531
|
const organizationId = await resolveOrganizationId();
|
|
25118
25532
|
const result = await authenticatedRequest(
|
|
25119
25533
|
(client) => client.pentest.listPentests({
|
|
25120
25534
|
params: { organizationId }
|
|
25121
25535
|
})
|
|
25122
25536
|
);
|
|
25537
|
+
if (result.status === 401) {
|
|
25538
|
+
console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
|
|
25539
|
+
process.exit(1);
|
|
25540
|
+
}
|
|
25123
25541
|
if (result.status !== 200) {
|
|
25124
25542
|
console.error(`Failed to list pentests (status ${result.status}).`);
|
|
25125
25543
|
process.exit(1);
|
|
25126
25544
|
}
|
|
25127
|
-
const
|
|
25545
|
+
const limit = options.limit ?? DEFAULT_LIMIT;
|
|
25546
|
+
const pentests = result.body.slice(0, limit);
|
|
25547
|
+
const isJson = options.output === "json";
|
|
25548
|
+
const isTsv = options.output === "tsv";
|
|
25128
25549
|
if (pentests.length === 0) {
|
|
25129
|
-
if (
|
|
25550
|
+
if (isJson) {
|
|
25130
25551
|
console.log("[]");
|
|
25552
|
+
} else if (isTsv) {
|
|
25553
|
+
console.log("displayId title status startedAt endedAt findingsTotal");
|
|
25131
25554
|
} else {
|
|
25132
25555
|
console.log("No pentests found.");
|
|
25133
25556
|
}
|
|
25134
25557
|
return;
|
|
25135
25558
|
}
|
|
25136
|
-
if (
|
|
25559
|
+
if (isJson) {
|
|
25137
25560
|
console.log(JSON.stringify(pentests, null, 2));
|
|
25138
25561
|
return;
|
|
25139
25562
|
}
|
|
25563
|
+
if (isTsv) {
|
|
25564
|
+
console.log("displayId title status startedAt endedAt findingsTotal");
|
|
25565
|
+
for (const pt of pentests) {
|
|
25566
|
+
const cols = [
|
|
25567
|
+
`PT-${pt.displayId}`,
|
|
25568
|
+
tsvSafe(pt.title),
|
|
25569
|
+
pt.status,
|
|
25570
|
+
pt.startedAt ? String(pt.startedAt) : "",
|
|
25571
|
+
pt.endedAt ? String(pt.endedAt) : "",
|
|
25572
|
+
String(pt.findingCounts.total)
|
|
25573
|
+
];
|
|
25574
|
+
console.log(cols.join(" "));
|
|
25575
|
+
}
|
|
25576
|
+
return;
|
|
25577
|
+
}
|
|
25140
25578
|
console.log(`Found ${pentests.length} pentest${pentests.length === 1 ? "" : "s"}:
|
|
25141
25579
|
`);
|
|
25142
25580
|
for (const pt of pentests) {
|
|
@@ -25155,7 +25593,14 @@ function createListCommand() {
|
|
|
25155
25593
|
});
|
|
25156
25594
|
}
|
|
25157
25595
|
function createFindingsListCommand() {
|
|
25158
|
-
return new Command("list").description("List findings for a pentest").requiredOption("--pentest <id>", "Pentest display ID (e.g. PT-3) or UUID").option("--
|
|
25596
|
+
return new Command("list").description("List findings for a pentest").requiredOption("--pentest <id>", "Pentest display ID (e.g. PT-3) or UUID").option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
25597
|
+
"after",
|
|
25598
|
+
`
|
|
25599
|
+
Examples:
|
|
25600
|
+
tracecli pentest findings list --pentest PT-3
|
|
25601
|
+
tracecli pentest findings list --pentest PT-3 --output json
|
|
25602
|
+
tracecli pentest findings list --pentest PT-3 --output tsv | cut -f1,4`
|
|
25603
|
+
).action(async (options) => {
|
|
25159
25604
|
const organizationId = await resolveOrganizationId();
|
|
25160
25605
|
const pentestId = await resolvePentestId(organizationId, options.pentest);
|
|
25161
25606
|
const result = await authenticatedRequest(
|
|
@@ -25163,28 +25608,57 @@ function createFindingsListCommand() {
|
|
|
25163
25608
|
params: { organizationId, pentestId }
|
|
25164
25609
|
})
|
|
25165
25610
|
);
|
|
25611
|
+
if (result.status === 401) {
|
|
25612
|
+
console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
|
|
25613
|
+
process.exit(1);
|
|
25614
|
+
}
|
|
25615
|
+
if (result.status === 404) {
|
|
25616
|
+
console.error(
|
|
25617
|
+
`Pentest '${options.pentest}' not found. Verify the ID with \`tracecli pentest list\`.`
|
|
25618
|
+
);
|
|
25619
|
+
process.exit(1);
|
|
25620
|
+
}
|
|
25166
25621
|
if (result.status !== 200) {
|
|
25167
25622
|
console.error(`Failed to list findings (status ${result.status}).`);
|
|
25168
25623
|
process.exit(1);
|
|
25169
25624
|
}
|
|
25170
25625
|
const findings = result.body;
|
|
25626
|
+
const isJson = options.output === "json";
|
|
25627
|
+
const isTsv = options.output === "tsv";
|
|
25171
25628
|
if (findings.length === 0) {
|
|
25172
|
-
if (
|
|
25629
|
+
if (isJson) {
|
|
25173
25630
|
console.log("[]");
|
|
25631
|
+
} else if (isTsv) {
|
|
25632
|
+
console.log("severity status category title cweIds cvssScore");
|
|
25174
25633
|
} else {
|
|
25175
25634
|
console.log("No findings found for this pentest.");
|
|
25176
25635
|
}
|
|
25177
25636
|
return;
|
|
25178
25637
|
}
|
|
25179
|
-
if (
|
|
25638
|
+
if (isJson) {
|
|
25180
25639
|
console.log(JSON.stringify(findings, null, 2));
|
|
25181
25640
|
return;
|
|
25182
25641
|
}
|
|
25183
|
-
console.log(`Found ${findings.length} finding${findings.length === 1 ? "" : "s"}:
|
|
25184
|
-
`);
|
|
25185
25642
|
const sorted = [...findings].sort(
|
|
25186
25643
|
(a, b) => (SEVERITY_ORDER[a.severity] ?? 99) - (SEVERITY_ORDER[b.severity] ?? 99)
|
|
25187
25644
|
);
|
|
25645
|
+
if (isTsv) {
|
|
25646
|
+
console.log("severity status category title cweIds cvssScore");
|
|
25647
|
+
for (const finding of sorted) {
|
|
25648
|
+
const cols = [
|
|
25649
|
+
finding.severity,
|
|
25650
|
+
finding.status,
|
|
25651
|
+
tsvSafe(finding.category),
|
|
25652
|
+
tsvSafe(finding.title),
|
|
25653
|
+
finding.cweIds.join(";"),
|
|
25654
|
+
finding.cvssScore != null ? String(finding.cvssScore) : ""
|
|
25655
|
+
];
|
|
25656
|
+
console.log(cols.join(" "));
|
|
25657
|
+
}
|
|
25658
|
+
return;
|
|
25659
|
+
}
|
|
25660
|
+
console.log(`Found ${findings.length} finding${findings.length === 1 ? "" : "s"}:
|
|
25661
|
+
`);
|
|
25188
25662
|
for (const finding of sorted) {
|
|
25189
25663
|
const sev = formatFindingSeverity(finding.severity);
|
|
25190
25664
|
const status = formatStatus(finding.status);
|
|
@@ -25262,6 +25736,9 @@ function extractRepoName(input) {
|
|
|
25262
25736
|
return input;
|
|
25263
25737
|
}
|
|
25264
25738
|
var BRANCH_NAME_PATTERN = /^[a-zA-Z0-9._/+-]+$/;
|
|
25739
|
+
var TRACE_GIT_ASKPASS_TOKEN_ENV = "TRACE_GIT_ASKPASS_TOKEN";
|
|
25740
|
+
var REPOSITORY_PLATFORMS = ["GITHUB", "GITLAB", "BITBUCKET"];
|
|
25741
|
+
var REPOSITORY_STATUSES = ["CONNECTED", "DISCONNECTED"];
|
|
25265
25742
|
function validateBranchName(branch) {
|
|
25266
25743
|
if (branch.startsWith("-")) {
|
|
25267
25744
|
throw new Error(`Invalid branch name: '${branch}' \u2014 branch names cannot start with a dash`);
|
|
@@ -25271,29 +25748,268 @@ function validateBranchName(branch) {
|
|
|
25271
25748
|
}
|
|
25272
25749
|
return branch;
|
|
25273
25750
|
}
|
|
25274
|
-
function
|
|
25275
|
-
|
|
25276
|
-
|
|
25277
|
-
|
|
25278
|
-
|
|
25279
|
-
|
|
25280
|
-
|
|
25751
|
+
function parseCloneDepth(value) {
|
|
25752
|
+
const depth = Number.parseInt(value, 10);
|
|
25753
|
+
if (!Number.isInteger(depth) || depth < 1) {
|
|
25754
|
+
throw new Error("--depth must be a positive integer");
|
|
25755
|
+
}
|
|
25756
|
+
return depth;
|
|
25757
|
+
}
|
|
25758
|
+
function normalizeForMatching(value) {
|
|
25759
|
+
return value.trim().toLowerCase();
|
|
25760
|
+
}
|
|
25761
|
+
function normalizePlatform(value, source) {
|
|
25762
|
+
const normalized = value.trim().toUpperCase();
|
|
25763
|
+
if (REPOSITORY_PLATFORMS.includes(normalized)) {
|
|
25764
|
+
return normalized;
|
|
25765
|
+
}
|
|
25766
|
+
throw new Error(
|
|
25767
|
+
`${source} must be one of: ${REPOSITORY_PLATFORMS.join(", ")}. Received '${value}'.`
|
|
25768
|
+
);
|
|
25769
|
+
}
|
|
25770
|
+
function normalizeStatus(value, source) {
|
|
25771
|
+
const normalized = value.trim().toUpperCase();
|
|
25772
|
+
if (REPOSITORY_STATUSES.includes(normalized)) {
|
|
25773
|
+
return normalized;
|
|
25774
|
+
}
|
|
25775
|
+
throw new Error(
|
|
25776
|
+
`${source} must be one of: ${REPOSITORY_STATUSES.join(", ")}. Received '${value}'.`
|
|
25777
|
+
);
|
|
25778
|
+
}
|
|
25779
|
+
function normalizeFilterField(rawField) {
|
|
25780
|
+
const field = rawField.trim().toLowerCase();
|
|
25781
|
+
switch (field) {
|
|
25782
|
+
case "platform":
|
|
25783
|
+
return "platform";
|
|
25784
|
+
case "status":
|
|
25785
|
+
return "status";
|
|
25786
|
+
case "url":
|
|
25787
|
+
case "repository":
|
|
25788
|
+
case "repositoryurl":
|
|
25789
|
+
case "repository_url":
|
|
25790
|
+
return "repository_url";
|
|
25791
|
+
case "repo":
|
|
25792
|
+
case "name":
|
|
25793
|
+
case "repository_name":
|
|
25794
|
+
return "repo_name";
|
|
25795
|
+
case "branch":
|
|
25796
|
+
case "defaultbranch":
|
|
25797
|
+
case "default_branch":
|
|
25798
|
+
return "default_branch";
|
|
25799
|
+
case "language":
|
|
25800
|
+
case "primarylanguage":
|
|
25801
|
+
case "primary_language":
|
|
25802
|
+
return "language";
|
|
25803
|
+
default:
|
|
25804
|
+
throw new Error(
|
|
25805
|
+
`Unknown repository filter field '${rawField}'. Supported fields: platform, status, url, repo, branch, language.`
|
|
25806
|
+
);
|
|
25807
|
+
}
|
|
25808
|
+
}
|
|
25809
|
+
function parseFilterOperator(rawOperator) {
|
|
25810
|
+
switch (rawOperator) {
|
|
25811
|
+
case "=":
|
|
25812
|
+
return "exact";
|
|
25813
|
+
case "!=":
|
|
25814
|
+
return "not_exact";
|
|
25815
|
+
case ":":
|
|
25816
|
+
return "contains";
|
|
25817
|
+
case "!:":
|
|
25818
|
+
return "not_contains";
|
|
25819
|
+
default:
|
|
25820
|
+
throw new Error(`Unsupported filter operator '${rawOperator}'. Use one of: =, !=, :, !:.`);
|
|
25821
|
+
}
|
|
25822
|
+
}
|
|
25823
|
+
function parseRepositoryFilterExpression(expression) {
|
|
25824
|
+
const trimmed = expression.trim();
|
|
25825
|
+
const match = /^([a-zA-Z][a-zA-Z0-9_-]*)(!=|!:|=|:)(.+)$/.exec(trimmed);
|
|
25826
|
+
if (!match) {
|
|
25827
|
+
throw new Error(
|
|
25828
|
+
`Invalid filter '${expression}'. Expected format: <field><operator><value> (e.g., platform=GITHUB, repo:trace, status!=DISCONNECTED).`
|
|
25281
25829
|
);
|
|
25282
|
-
|
|
25283
|
-
|
|
25284
|
-
|
|
25830
|
+
}
|
|
25831
|
+
const rawField = match[1];
|
|
25832
|
+
const rawOperator = match[2];
|
|
25833
|
+
const rawValue = match[3];
|
|
25834
|
+
if (!rawField || !rawOperator || !rawValue) {
|
|
25835
|
+
throw new Error(`Invalid filter '${expression}'.`);
|
|
25836
|
+
}
|
|
25837
|
+
const value = rawValue.trim();
|
|
25838
|
+
if (!value) {
|
|
25839
|
+
throw new Error(`Invalid filter '${expression}': value cannot be empty.`);
|
|
25840
|
+
}
|
|
25841
|
+
const field = normalizeFilterField(rawField);
|
|
25842
|
+
const operator = parseFilterOperator(rawOperator);
|
|
25843
|
+
if (field === "platform") {
|
|
25844
|
+
normalizePlatform(value, "--filter");
|
|
25845
|
+
}
|
|
25846
|
+
if (field === "status") {
|
|
25847
|
+
normalizeStatus(value, "--filter");
|
|
25848
|
+
}
|
|
25849
|
+
return { field, operator, value };
|
|
25850
|
+
}
|
|
25851
|
+
function doesValueMatchFilter(candidate, filterValue, operator, exactMatchOnly) {
|
|
25852
|
+
const normalizedCandidate = normalizeForMatching(candidate);
|
|
25853
|
+
const normalizedFilter = normalizeForMatching(filterValue);
|
|
25854
|
+
if (exactMatchOnly || operator === "exact" || operator === "not_exact") {
|
|
25855
|
+
const matches2 = normalizedCandidate === normalizedFilter;
|
|
25856
|
+
return operator === "not_exact" ? !matches2 : matches2;
|
|
25857
|
+
}
|
|
25858
|
+
const matches = normalizedCandidate.includes(normalizedFilter);
|
|
25859
|
+
return operator === "not_contains" ? !matches : matches;
|
|
25860
|
+
}
|
|
25861
|
+
function matchParsedFilter(repo, parsedFilter) {
|
|
25862
|
+
switch (parsedFilter.field) {
|
|
25863
|
+
case "platform":
|
|
25864
|
+
return doesValueMatchFilter(repo.platform, parsedFilter.value, parsedFilter.operator, true);
|
|
25865
|
+
case "status":
|
|
25866
|
+
return doesValueMatchFilter(repo.status, parsedFilter.value, parsedFilter.operator, true);
|
|
25867
|
+
case "repository_url":
|
|
25868
|
+
return doesValueMatchFilter(
|
|
25869
|
+
repo.repositoryUrl,
|
|
25870
|
+
parsedFilter.value,
|
|
25871
|
+
parsedFilter.operator,
|
|
25872
|
+
false
|
|
25873
|
+
);
|
|
25874
|
+
case "repo_name":
|
|
25875
|
+
return doesValueMatchFilter(
|
|
25876
|
+
extractRepoName(repo.repositoryUrl),
|
|
25877
|
+
parsedFilter.value,
|
|
25878
|
+
parsedFilter.operator,
|
|
25879
|
+
false
|
|
25880
|
+
);
|
|
25881
|
+
case "default_branch":
|
|
25882
|
+
return doesValueMatchFilter(
|
|
25883
|
+
repo.defaultBranch,
|
|
25884
|
+
parsedFilter.value,
|
|
25885
|
+
parsedFilter.operator,
|
|
25886
|
+
false
|
|
25887
|
+
);
|
|
25888
|
+
case "language": {
|
|
25889
|
+
const language = repo.primaryLanguage ?? "";
|
|
25890
|
+
return doesValueMatchFilter(language, parsedFilter.value, parsedFilter.operator, false);
|
|
25285
25891
|
}
|
|
25286
|
-
|
|
25287
|
-
|
|
25288
|
-
|
|
25289
|
-
|
|
25892
|
+
}
|
|
25893
|
+
}
|
|
25894
|
+
function filterRepositories(repositories, options) {
|
|
25895
|
+
const parsedFilters = (options.filters ?? []).map(
|
|
25896
|
+
(expression) => parseRepositoryFilterExpression(expression)
|
|
25897
|
+
);
|
|
25898
|
+
const normalizedPlatform = options.platform ? normalizePlatform(options.platform, "--platform") : void 0;
|
|
25899
|
+
const normalizedStatus = options.status ? normalizeStatus(options.status, "--status") : void 0;
|
|
25900
|
+
const normalizedQuery = options.query ? normalizeForMatching(options.query) : void 0;
|
|
25901
|
+
const normalizedDefaultBranch = options.defaultBranch ? normalizeForMatching(options.defaultBranch) : void 0;
|
|
25902
|
+
const normalizedLanguage = options.language ? normalizeForMatching(options.language) : void 0;
|
|
25903
|
+
return repositories.filter((repo) => {
|
|
25904
|
+
if (normalizedPlatform && repo.platform.toUpperCase() !== normalizedPlatform) {
|
|
25905
|
+
return false;
|
|
25906
|
+
}
|
|
25907
|
+
if (normalizedStatus && repo.status.toUpperCase() !== normalizedStatus) {
|
|
25908
|
+
return false;
|
|
25909
|
+
}
|
|
25910
|
+
if (normalizedDefaultBranch && !normalizeForMatching(repo.defaultBranch).includes(normalizedDefaultBranch)) {
|
|
25911
|
+
return false;
|
|
25290
25912
|
}
|
|
25291
|
-
|
|
25292
|
-
|
|
25293
|
-
|
|
25294
|
-
|
|
25295
|
-
|
|
25913
|
+
const repoLanguage = normalizeForMatching(repo.primaryLanguage ?? "");
|
|
25914
|
+
if (normalizedLanguage && !repoLanguage.includes(normalizedLanguage)) {
|
|
25915
|
+
return false;
|
|
25916
|
+
}
|
|
25917
|
+
if (normalizedQuery) {
|
|
25918
|
+
const normalizedUrl = normalizeForMatching(repo.repositoryUrl);
|
|
25919
|
+
const normalizedBranch = normalizeForMatching(repo.defaultBranch);
|
|
25920
|
+
const normalizedName = normalizeForMatching(extractRepoName(repo.repositoryUrl));
|
|
25921
|
+
if (!normalizedUrl.includes(normalizedQuery) && !normalizedBranch.includes(normalizedQuery) && !repoLanguage.includes(normalizedQuery) && !normalizedName.includes(normalizedQuery)) {
|
|
25922
|
+
return false;
|
|
25923
|
+
}
|
|
25296
25924
|
}
|
|
25925
|
+
for (const parsedFilter of parsedFilters) {
|
|
25926
|
+
if (!matchParsedFilter(repo, parsedFilter)) {
|
|
25927
|
+
return false;
|
|
25928
|
+
}
|
|
25929
|
+
}
|
|
25930
|
+
return true;
|
|
25931
|
+
});
|
|
25932
|
+
}
|
|
25933
|
+
function collectFilterExpression(value, previous) {
|
|
25934
|
+
previous.push(value);
|
|
25935
|
+
return previous;
|
|
25936
|
+
}
|
|
25937
|
+
function toRepositoryListFilterOptions(options) {
|
|
25938
|
+
return {
|
|
25939
|
+
...options.platform ? { platform: options.platform } : {},
|
|
25940
|
+
...options.status ? { status: options.status } : {},
|
|
25941
|
+
...options.query ? { query: options.query } : {},
|
|
25942
|
+
...options.defaultBranch ? { defaultBranch: options.defaultBranch } : {},
|
|
25943
|
+
...options.language ? { language: options.language } : {},
|
|
25944
|
+
...options.filter.length > 0 ? { filters: options.filter } : {}
|
|
25945
|
+
};
|
|
25946
|
+
}
|
|
25947
|
+
function addRepositoryFilterOptions(command) {
|
|
25948
|
+
return command.option(
|
|
25949
|
+
"--platform <platform>",
|
|
25950
|
+
"Filter by platform (GITHUB, GITLAB, BITBUCKET)",
|
|
25951
|
+
(value) => value.toUpperCase()
|
|
25952
|
+
).option(
|
|
25953
|
+
"--status <status>",
|
|
25954
|
+
"Filter by status (CONNECTED, DISCONNECTED)",
|
|
25955
|
+
(value) => value.toUpperCase()
|
|
25956
|
+
).option("--query <query>", "Case-insensitive search across URL, repo, branch, and language").option("--default-branch <branch>", "Filter by default branch (case-insensitive contains)").option("--language <language>", "Filter by primary language (case-insensitive contains)").option(
|
|
25957
|
+
"--filter <expression>",
|
|
25958
|
+
"Advanced filter expression. Repeatable. Examples: platform=GITHUB, repo:trace, status!=DISCONNECTED, language!:typescript",
|
|
25959
|
+
collectFilterExpression,
|
|
25960
|
+
[]
|
|
25961
|
+
).option("--json", "Output as JSON");
|
|
25962
|
+
}
|
|
25963
|
+
async function runRepositoryListCommand(options) {
|
|
25964
|
+
let filteredRepositories;
|
|
25965
|
+
const organizationId = await resolveOrganizationId();
|
|
25966
|
+
const result = await authenticatedRequest(
|
|
25967
|
+
(client) => client.repository.listRepositories({
|
|
25968
|
+
params: { organizationId }
|
|
25969
|
+
})
|
|
25970
|
+
);
|
|
25971
|
+
if (result.status !== 200) {
|
|
25972
|
+
console.error(`Failed to list repositories (status ${result.status}).`);
|
|
25973
|
+
process.exit(1);
|
|
25974
|
+
}
|
|
25975
|
+
try {
|
|
25976
|
+
filteredRepositories = filterRepositories(result.body, toRepositoryListFilterOptions(options));
|
|
25977
|
+
} catch (error48) {
|
|
25978
|
+
const message = error48 instanceof Error ? error48.message : "Unknown filter parsing error.";
|
|
25979
|
+
console.error(`Invalid repository filter: ${message}`);
|
|
25980
|
+
process.exit(1);
|
|
25981
|
+
}
|
|
25982
|
+
if (filteredRepositories.length === 0) {
|
|
25983
|
+
if (options.platform || options.status || options.query || options.defaultBranch || options.language || options.filter.length > 0) {
|
|
25984
|
+
console.log("No repositories found matching the provided filters.");
|
|
25985
|
+
return;
|
|
25986
|
+
}
|
|
25987
|
+
console.log("No repositories found.");
|
|
25988
|
+
return;
|
|
25989
|
+
}
|
|
25990
|
+
if (options.json) {
|
|
25991
|
+
console.log(JSON.stringify(filteredRepositories, null, 2));
|
|
25992
|
+
return;
|
|
25993
|
+
}
|
|
25994
|
+
for (const repo of filteredRepositories) {
|
|
25995
|
+
const status = repo.status === "CONNECTED" ? "connected" : "disconnected";
|
|
25996
|
+
const url2 = stripAnsi(String(repo.repositoryUrl));
|
|
25997
|
+
const platform = stripAnsi(String(repo.platform)).toLowerCase();
|
|
25998
|
+
console.log(`${url2} (${platform}, ${status})`);
|
|
25999
|
+
}
|
|
26000
|
+
}
|
|
26001
|
+
function createListCommand2() {
|
|
26002
|
+
return addRepositoryFilterOptions(
|
|
26003
|
+
new Command("list").description("List repositories in your organization")
|
|
26004
|
+
).action(async (options) => {
|
|
26005
|
+
await runRepositoryListCommand(options);
|
|
26006
|
+
});
|
|
26007
|
+
}
|
|
26008
|
+
function createFilterCommand() {
|
|
26009
|
+
return addRepositoryFilterOptions(
|
|
26010
|
+
new Command("filter").description("Filter repositories in your organization")
|
|
26011
|
+
).action(async (options) => {
|
|
26012
|
+
await runRepositoryListCommand(options);
|
|
25297
26013
|
});
|
|
25298
26014
|
}
|
|
25299
26015
|
function urlWithUsername(httpsUrl) {
|
|
@@ -25302,14 +26018,21 @@ function urlWithUsername(httpsUrl) {
|
|
|
25302
26018
|
url2.password = "";
|
|
25303
26019
|
return url2.toString();
|
|
25304
26020
|
}
|
|
25305
|
-
function createAskPassScript(
|
|
26021
|
+
function createAskPassScript() {
|
|
25306
26022
|
const dir = mkdtempSync(join3(tmpdir(), "trace-askpass-"));
|
|
25307
26023
|
const scriptPath = join3(dir, "askpass.sh");
|
|
25308
|
-
writeFileSync3(
|
|
25309
|
-
|
|
25310
|
-
|
|
25311
|
-
|
|
25312
|
-
|
|
26024
|
+
writeFileSync3(
|
|
26025
|
+
scriptPath,
|
|
26026
|
+
`#!/bin/sh
|
|
26027
|
+
if [ -z "\${${TRACE_GIT_ASKPASS_TOKEN_ENV}:-}" ]; then
|
|
26028
|
+
exit 1
|
|
26029
|
+
fi
|
|
26030
|
+
printf '%s\\n' "$${TRACE_GIT_ASKPASS_TOKEN_ENV}"
|
|
26031
|
+
`,
|
|
26032
|
+
{
|
|
26033
|
+
mode: 448
|
|
26034
|
+
}
|
|
26035
|
+
);
|
|
25313
26036
|
chmodSync(scriptPath, 448);
|
|
25314
26037
|
return scriptPath;
|
|
25315
26038
|
}
|
|
@@ -25329,7 +26052,8 @@ async function fetchCloneToken(repoUrl) {
|
|
|
25329
26052
|
return null;
|
|
25330
26053
|
}
|
|
25331
26054
|
if (result.status === 200) {
|
|
25332
|
-
|
|
26055
|
+
const token = result.body.token.trim();
|
|
26056
|
+
return token.length > 0 ? token : null;
|
|
25333
26057
|
}
|
|
25334
26058
|
return null;
|
|
25335
26059
|
} catch {
|
|
@@ -25337,7 +26061,7 @@ async function fetchCloneToken(repoUrl) {
|
|
|
25337
26061
|
}
|
|
25338
26062
|
}
|
|
25339
26063
|
function createCloneCommand() {
|
|
25340
|
-
return new Command("clone").description("Clone a repository").argument("<repository>", "Repository URL or owner/repo shorthand").argument("[directory]", "Directory to clone into").option("--branch <branch>", "Branch to clone").option("--depth <depth>", "Shallow clone depth",
|
|
26064
|
+
return new Command("clone").description("Clone a repository").argument("<repository>", "Repository URL or owner/repo shorthand").argument("[directory]", "Directory to clone into").option("--branch <branch>", "Branch to clone").option("--depth <depth>", "Shallow clone depth", parseCloneDepth).action(
|
|
25341
26065
|
async (repository, directory, options) => {
|
|
25342
26066
|
const cloneUrl = resolveRepoUrl(repository);
|
|
25343
26067
|
const targetDir = directory ?? extractRepoName(repository);
|
|
@@ -25359,8 +26083,9 @@ function createCloneCommand() {
|
|
|
25359
26083
|
console.log(`Cloning ${cloneUrl} into ${targetDir}...`);
|
|
25360
26084
|
const extraEnv = {};
|
|
25361
26085
|
if (installationToken) {
|
|
25362
|
-
askPassScript = createAskPassScript(
|
|
26086
|
+
askPassScript = createAskPassScript();
|
|
25363
26087
|
extraEnv["GIT_ASKPASS"] = askPassScript;
|
|
26088
|
+
extraEnv[TRACE_GIT_ASKPASS_TOKEN_ENV] = installationToken;
|
|
25364
26089
|
extraEnv["GIT_TERMINAL_PROMPT"] = "0";
|
|
25365
26090
|
}
|
|
25366
26091
|
try {
|
|
@@ -25371,7 +26096,7 @@ function createCloneCommand() {
|
|
|
25371
26096
|
});
|
|
25372
26097
|
const exitCode = await proc.exited;
|
|
25373
26098
|
if (exitCode !== 0) {
|
|
25374
|
-
process.exit(
|
|
26099
|
+
process.exit(1);
|
|
25375
26100
|
}
|
|
25376
26101
|
if (installationToken) {
|
|
25377
26102
|
const resetProc = Bun.spawn(["git", "remote", "set-url", "origin", cloneUrl], {
|
|
@@ -25398,13 +26123,14 @@ function createCloneCommand() {
|
|
|
25398
26123
|
function createRepoCommand() {
|
|
25399
26124
|
const repo = new Command("repo").description("Manage repositories");
|
|
25400
26125
|
repo.addCommand(createListCommand2());
|
|
26126
|
+
repo.addCommand(createFilterCommand());
|
|
25401
26127
|
repo.addCommand(createCloneCommand());
|
|
25402
26128
|
return repo;
|
|
25403
26129
|
}
|
|
25404
26130
|
|
|
25405
26131
|
// src/vulnerabilities/commands.ts
|
|
25406
|
-
|
|
25407
|
-
var
|
|
26132
|
+
var DEFAULT_LIMIT2 = 30;
|
|
26133
|
+
var MAX_LIMIT2 = 100;
|
|
25408
26134
|
async function resolveRepositoryIdAuthenticated(organizationId, repoIdentifier) {
|
|
25409
26135
|
const result = await authenticatedRequest(
|
|
25410
26136
|
(client) => client.repository.listRepositories({
|
|
@@ -25416,21 +26142,18 @@ async function resolveRepositoryIdAuthenticated(organizationId, repoIdentifier)
|
|
|
25416
26142
|
process.exit(1);
|
|
25417
26143
|
}
|
|
25418
26144
|
const repos = result.body;
|
|
25419
|
-
const
|
|
25420
|
-
|
|
25421
|
-
|
|
25422
|
-
|
|
25423
|
-
|
|
25424
|
-
|
|
25425
|
-
return true;
|
|
25426
|
-
|
|
25427
|
-
|
|
25428
|
-
|
|
26145
|
+
const isBareNameOnly = !repoIdentifier.includes("/") && !repoIdentifier.startsWith("http");
|
|
26146
|
+
if (!isBareNameOnly) {
|
|
26147
|
+
const match = repos.find((r) => {
|
|
26148
|
+
const url2 = r.repositoryUrl;
|
|
26149
|
+
if (url2.endsWith(`/${repoIdentifier}`)) return true;
|
|
26150
|
+
if (url2.endsWith(`/${repoIdentifier}.git`)) return true;
|
|
26151
|
+
if (url2 === repoIdentifier) return true;
|
|
26152
|
+
return false;
|
|
26153
|
+
});
|
|
26154
|
+
if (match) {
|
|
26155
|
+
return match.repositoryId;
|
|
25429
26156
|
}
|
|
25430
|
-
return false;
|
|
25431
|
-
});
|
|
25432
|
-
if (match) {
|
|
25433
|
-
return match.repositoryId;
|
|
25434
26157
|
}
|
|
25435
26158
|
const byName = repos.filter((r) => {
|
|
25436
26159
|
const segments = r.repositoryUrl.replace(/\.git$/, "").split("/");
|
|
@@ -25484,15 +26207,26 @@ function printVulnerabilities(vulnerabilities) {
|
|
|
25484
26207
|
console.log("");
|
|
25485
26208
|
}
|
|
25486
26209
|
}
|
|
25487
|
-
|
|
25488
|
-
|
|
25489
|
-
|
|
25490
|
-
|
|
25491
|
-
|
|
25492
|
-
|
|
25493
|
-
|
|
25494
|
-
|
|
25495
|
-
|
|
26210
|
+
function sanitizeTsvField(value) {
|
|
26211
|
+
return value.replace(/[\t\n\r]/g, " ");
|
|
26212
|
+
}
|
|
26213
|
+
function printVulnerabilitiesTsv(vulnerabilities) {
|
|
26214
|
+
const sorted = [...vulnerabilities].sort(
|
|
26215
|
+
(a, b) => (SEVERITY_ORDER[a.severity] ?? 99) - (SEVERITY_ORDER[b.severity] ?? 99)
|
|
26216
|
+
);
|
|
26217
|
+
console.log("severity status repository file line traceId title");
|
|
26218
|
+
for (const vuln of sorted) {
|
|
26219
|
+
const cols = [
|
|
26220
|
+
vuln.severity,
|
|
26221
|
+
vuln.status,
|
|
26222
|
+
vuln.repositoryName,
|
|
26223
|
+
vuln.codeSnippet.filePath,
|
|
26224
|
+
String(vuln.codeSnippet.startLine),
|
|
26225
|
+
vuln.traceId,
|
|
26226
|
+
vuln.title
|
|
26227
|
+
].map(sanitizeTsvField);
|
|
26228
|
+
console.log(cols.join(" "));
|
|
26229
|
+
}
|
|
25496
26230
|
}
|
|
25497
26231
|
function createListCommand3() {
|
|
25498
26232
|
return new Command("list").description("List vulnerabilities for your organization").option("--repo <repo>", "Filter by repository name or owner/repo").option(
|
|
@@ -25503,13 +26237,26 @@ function createListCommand3() {
|
|
|
25503
26237
|
"--status <status>",
|
|
25504
26238
|
"Filter by status (OPEN, IN_PROGRESS, FIXED, IGNORED, FALSE_POSITIVE)",
|
|
25505
26239
|
(value) => value.toUpperCase()
|
|
25506
|
-
).option(
|
|
25507
|
-
|
|
25508
|
-
|
|
25509
|
-
|
|
25510
|
-
|
|
25511
|
-
|
|
25512
|
-
|
|
26240
|
+
).option(
|
|
26241
|
+
"-L, --limit <n>",
|
|
26242
|
+
`Max results to return (default: ${DEFAULT_LIMIT2}, max: ${MAX_LIMIT2})`,
|
|
26243
|
+
(v) => {
|
|
26244
|
+
const n = Number.parseInt(v, 10);
|
|
26245
|
+
if (Number.isNaN(n) || n < 1) {
|
|
26246
|
+
throw new Error("--limit must be a positive integer");
|
|
26247
|
+
}
|
|
26248
|
+
return Math.min(n, MAX_LIMIT2);
|
|
26249
|
+
}
|
|
26250
|
+
).option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
|
|
26251
|
+
"after",
|
|
26252
|
+
`
|
|
26253
|
+
Examples:
|
|
26254
|
+
tracecli vulnerabilities list
|
|
26255
|
+
tracecli vulnerabilities list --severity CRITICAL --status OPEN
|
|
26256
|
+
tracecli vulnerabilities list --repo securewithtrace/trace --limit 50
|
|
26257
|
+
tracecli vulnerabilities list --output json | jq '.[].title'
|
|
26258
|
+
tracecli vulnerabilities list --output tsv | cut -f1,7`
|
|
26259
|
+
).action(
|
|
25513
26260
|
async (options) => {
|
|
25514
26261
|
const organizationId = await resolveOrganizationId();
|
|
25515
26262
|
const conditions = [];
|
|
@@ -25529,57 +26276,54 @@ function createListCommand3() {
|
|
|
25529
26276
|
sortBy: "severity",
|
|
25530
26277
|
sortOrder: "desc"
|
|
25531
26278
|
};
|
|
25532
|
-
const
|
|
26279
|
+
const limit = options.limit ?? DEFAULT_LIMIT2;
|
|
26280
|
+
const isJson = options.output === "json";
|
|
26281
|
+
const isTsv = options.output === "tsv";
|
|
26282
|
+
const collected = [];
|
|
25533
26283
|
let page = 1;
|
|
25534
|
-
|
|
25535
|
-
|
|
25536
|
-
const allJsonVulnerabilities = [];
|
|
25537
|
-
while (true) {
|
|
26284
|
+
const pageSize = Math.min(limit, 100);
|
|
26285
|
+
while (collected.length < limit) {
|
|
25538
26286
|
const result = await authenticatedRequest(
|
|
25539
26287
|
(client) => client.vulnerability.filterVulnerabilities({
|
|
25540
26288
|
params: { organizationId },
|
|
25541
26289
|
body: { ...filterBody, page, pageSize }
|
|
25542
26290
|
})
|
|
25543
26291
|
);
|
|
26292
|
+
if (result.status === 401) {
|
|
26293
|
+
console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
|
|
26294
|
+
process.exit(1);
|
|
26295
|
+
}
|
|
25544
26296
|
if (result.status !== 200) {
|
|
25545
26297
|
console.error(`Failed to list vulnerabilities (status ${result.status}).`);
|
|
25546
26298
|
process.exit(1);
|
|
25547
26299
|
}
|
|
25548
|
-
total = result.body.total;
|
|
25549
26300
|
const vulnerabilities = result.body.statusGroups.flatMap((g) => g.vulnerabilities);
|
|
25550
|
-
|
|
25551
|
-
|
|
25552
|
-
console.log("[]");
|
|
25553
|
-
} else {
|
|
25554
|
-
console.log("No vulnerabilities found.");
|
|
25555
|
-
}
|
|
25556
|
-
return;
|
|
25557
|
-
}
|
|
25558
|
-
if (options.json) {
|
|
25559
|
-
allJsonVulnerabilities.push(...vulnerabilities);
|
|
25560
|
-
} else {
|
|
25561
|
-
if (page === 1) {
|
|
25562
|
-
console.log(`Found ${total} vulnerabilit${total === 1 ? "y" : "ies"}:
|
|
25563
|
-
`);
|
|
25564
|
-
}
|
|
25565
|
-
printVulnerabilities(vulnerabilities);
|
|
25566
|
-
}
|
|
25567
|
-
totalDisplayed += vulnerabilities.length;
|
|
25568
|
-
if (totalDisplayed >= total || vulnerabilities.length < pageSize) {
|
|
25569
|
-
break;
|
|
25570
|
-
}
|
|
25571
|
-
if (options.json) {
|
|
25572
|
-
page++;
|
|
25573
|
-
continue;
|
|
25574
|
-
}
|
|
25575
|
-
const wantMore = await promptContinue(totalDisplayed, total);
|
|
25576
|
-
if (!wantMore) {
|
|
26301
|
+
collected.push(...vulnerabilities);
|
|
26302
|
+
if (vulnerabilities.length < pageSize || collected.length >= result.body.total) {
|
|
25577
26303
|
break;
|
|
25578
26304
|
}
|
|
25579
26305
|
page++;
|
|
25580
26306
|
}
|
|
25581
|
-
|
|
25582
|
-
|
|
26307
|
+
const items = collected.slice(0, limit);
|
|
26308
|
+
if (items.length === 0) {
|
|
26309
|
+
if (isJson) {
|
|
26310
|
+
console.log("[]");
|
|
26311
|
+
} else if (isTsv) {
|
|
26312
|
+
console.log("severity status repository file line traceId title");
|
|
26313
|
+
} else {
|
|
26314
|
+
console.log("No vulnerabilities found.");
|
|
26315
|
+
}
|
|
26316
|
+
return;
|
|
26317
|
+
}
|
|
26318
|
+
if (isJson) {
|
|
26319
|
+
console.log(JSON.stringify(items, null, 2));
|
|
26320
|
+
} else if (isTsv) {
|
|
26321
|
+
printVulnerabilitiesTsv(items);
|
|
26322
|
+
} else {
|
|
26323
|
+
const total = collected.length;
|
|
26324
|
+
console.log(`Found ${total} vulnerabilit${total === 1 ? "y" : "ies"}:
|
|
26325
|
+
`);
|
|
26326
|
+
printVulnerabilities(items);
|
|
25583
26327
|
}
|
|
25584
26328
|
}
|
|
25585
26329
|
);
|