securewithtrace 0.8.0 → 0.10.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.
Files changed (3) hide show
  1. package/README.md +56 -5
  2. package/dist/index.js +1537 -211
  3. 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((c21) => !c21._hidden).map((c21) => extractCommandTree(c21));
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((c21) => c21.name);
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])];
@@ -4035,11 +4035,6 @@ function createCompletionCommand(program3) {
4035
4035
  });
4036
4036
  }
4037
4037
 
4038
- // src/repo/commands.ts
4039
- import { chmodSync, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
4040
- import { tmpdir } from "os";
4041
- import { join as join3 } from "path";
4042
-
4043
4038
  // ../../node_modules/.bun/@ts-rest+core@3.53.0-rc.1+f9199aabcde8d6a0/node_modules/@ts-rest/core/index.esm.mjs
4044
4039
  var util;
4045
4040
  (function(util2) {
@@ -10808,7 +10803,7 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
10808
10803
  function isValidBase64URL(data) {
10809
10804
  if (!base64url.test(data))
10810
10805
  return false;
10811
- const base643 = data.replace(/[-_]/g, (c21) => c21 === "-" ? "+" : "/");
10806
+ const base643 = data.replace(/[-_]/g, (c25) => c25 === "-" ? "+" : "/");
10812
10807
  const padded = base643.padEnd(Math.ceil(base643.length / 4) * 4, "=");
10813
10808
  return isValidBase64(padded);
10814
10809
  }
@@ -20852,9 +20847,9 @@ var ZodDate2 = /* @__PURE__ */ $constructor("ZodDate", (inst, def) => {
20852
20847
  inst._zod.processJSONSchema = (ctx, json2, params) => dateProcessor(inst, ctx, json2, params);
20853
20848
  inst.min = (value, params) => inst.check(_gte(value, params));
20854
20849
  inst.max = (value, params) => inst.check(_lte(value, params));
20855
- const c21 = inst._zod.bag;
20856
- inst.minDate = c21.minimum ? new Date(c21.minimum) : null;
20857
- inst.maxDate = c21.maximum ? new Date(c21.maximum) : null;
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;
20858
20853
  });
20859
20854
  function date3(params) {
20860
20855
  return _date(ZodDate2, params);
@@ -22166,6 +22161,331 @@ var chatSessionContract = c2.router({
22166
22161
  }
22167
22162
  });
22168
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
+
22169
22489
  // ../../packages/api-contracts/src/schemas/api/v1/docker-scout-integration.api.ts
22170
22490
  var DockerScoutIntegrationIdParamsSchema = OrgIdParamsSchema.extend({
22171
22491
  dockerScoutIntegrationId: external_exports.uuid()
@@ -22185,8 +22505,8 @@ var DockerScoutIntegrationResponseSchema = external_exports.object({
22185
22505
  });
22186
22506
 
22187
22507
  // ../../packages/api-contracts/src/contracts/v1/docker-scout-integration.ts
22188
- var c3 = initContract();
22189
- var dockerScoutIntegrationContract = c3.router({
22508
+ var c4 = initContract();
22509
+ var dockerScoutIntegrationContract = c4.router({
22190
22510
  createDockerScoutIntegration: {
22191
22511
  method: "POST",
22192
22512
  path: "/organizations/:organizationId/docker-scout-integration",
@@ -22247,9 +22567,7 @@ var GitHubCallbackQuerySchema = external_exports.object({
22247
22567
  });
22248
22568
  var GitHubCallbackRequestSchema = external_exports.object({
22249
22569
  installationId: external_exports.number().int(),
22250
- setupAction: external_exports.enum(["install", "update", "request"]),
22251
- githubAccountId: external_exports.number().int().optional(),
22252
- githubAccountLogin: external_exports.string().min(1).optional()
22570
+ setupAction: external_exports.enum(["install", "update", "request"])
22253
22571
  });
22254
22572
  var GitHubInstallationResponseSchema = external_exports.object({
22255
22573
  installationId: external_exports.uuid(),
@@ -22279,13 +22597,14 @@ var GitHubRepoSchema = external_exports.object({
22279
22597
  fullName: external_exports.string(),
22280
22598
  private: external_exports.boolean(),
22281
22599
  htmlUrl: external_exports.string().url(),
22282
- defaultBranch: external_exports.string()
22600
+ defaultBranch: external_exports.string(),
22601
+ language: external_exports.string().nullable()
22283
22602
  });
22284
22603
  var ListGitHubInstallationReposResponseSchema = external_exports.array(GitHubRepoSchema);
22285
22604
 
22286
22605
  // ../../packages/api-contracts/src/contracts/v1/github.ts
22287
- var c4 = initContract();
22288
- var githubCallbackContract = c4.router(
22606
+ var c5 = initContract();
22607
+ var githubCallbackContract = c5.router(
22289
22608
  {
22290
22609
  handleCallback: {
22291
22610
  method: "POST",
@@ -22305,7 +22624,7 @@ var githubCallbackContract = c4.router(
22305
22624
  pathPrefix: "/v1/github"
22306
22625
  }
22307
22626
  );
22308
- var githubContract = c4.router({
22627
+ var githubContract = c5.router({
22309
22628
  generateInstallLink: {
22310
22629
  method: "POST",
22311
22630
  path: "/organizations/:organizationId/github/install-link",
@@ -22375,8 +22694,8 @@ var UpdateKnowledgeBaseResponseSchema = external_exports.object({
22375
22694
  });
22376
22695
 
22377
22696
  // ../../packages/api-contracts/src/contracts/v1/knowledge-base.ts
22378
- var c5 = initContract();
22379
- var knowledgeBaseContract = c5.router({
22697
+ var c6 = initContract();
22698
+ var knowledgeBaseContract = c6.router({
22380
22699
  getKnowledgeBase: {
22381
22700
  method: "GET",
22382
22701
  path: "/organizations/:organizationId/knowledge-base",
@@ -22597,8 +22916,8 @@ var UpdateRepoDocumentContentResponseSchema = external_exports.object({
22597
22916
  });
22598
22917
 
22599
22918
  // ../../packages/api-contracts/src/contracts/v1/knowledge-document.ts
22600
- var c6 = initContract();
22601
- var knowledgeDocumentContract = c6.router({
22919
+ var c7 = initContract();
22920
+ var knowledgeDocumentContract = c7.router({
22602
22921
  createDocument: {
22603
22922
  method: "POST",
22604
22923
  path: "/organizations/:organizationId/knowledge-documents",
@@ -22907,8 +23226,8 @@ var LlmProviderKeyResponseSchema = external_exports.object({
22907
23226
  var ListLlmProviderKeysResponseSchema = external_exports.array(LlmProviderKeyResponseSchema);
22908
23227
 
22909
23228
  // ../../packages/api-contracts/src/contracts/v1/llm-provider-key.ts
22910
- var c7 = initContract();
22911
- var llmProviderKeyContract = c7.router({
23229
+ var c8 = initContract();
23230
+ var llmProviderKeyContract = c8.router({
22912
23231
  createLlmProviderKey: {
22913
23232
  method: "POST",
22914
23233
  path: "/organizations/:organizationId/llm-provider-keys",
@@ -22976,23 +23295,55 @@ var llmProviderKeyContract = c7.router({
22976
23295
  });
22977
23296
 
22978
23297
  // ../../packages/api-contracts/src/schemas/api/v1/organization.api.ts
23298
+ var OrgCapabilityValues = [
23299
+ "PENTEST",
23300
+ "SCAN_SAST",
23301
+ "SCAN_SCA",
23302
+ "SCAN_SECRETS",
23303
+ "SCAN_DAST",
23304
+ "AUTO_PR_SCANS",
23305
+ "AUTO_PUSH_SCANS"
23306
+ ];
22979
23307
  var UpdateOrganizationRequestSchema = external_exports.object({
22980
23308
  name: external_exports.string().min(1).max(255).optional(),
22981
- logoUrl: external_exports.string().url().max(2048).nullish()
23309
+ logoUrl: external_exports.string().url().max(2048).nullish(),
23310
+ logoS3Key: external_exports.string().max(1024).nullish(),
23311
+ darkModeLogoUrl: external_exports.string().url().max(2048).nullish(),
23312
+ darkModeLogoS3Key: external_exports.string().max(1024).nullish()
23313
+ });
23314
+ var LogoUploadRequestSchema = external_exports.object({
23315
+ variant: external_exports.enum(["light", "dark"]),
23316
+ contentType: external_exports.enum(["image/png", "image/jpeg", "image/gif", "image/svg+xml", "image/webp"]),
23317
+ fileName: external_exports.string().min(1).max(255)
23318
+ });
23319
+ var LogoUploadResponseSchema = external_exports.object({
23320
+ uploadUrl: external_exports.string(),
23321
+ s3Key: external_exports.string()
23322
+ });
23323
+ var PatchCapabilitiesRequestSchema = external_exports.object({
23324
+ capabilities: external_exports.array(external_exports.enum(OrgCapabilityValues)).min(1)
23325
+ });
23326
+ var PatchCapabilitiesResponseSchema = external_exports.object({
23327
+ capabilities: external_exports.array(external_exports.enum(OrgCapabilityValues))
22982
23328
  });
22983
23329
  var OrganizationResponseSchema = external_exports.object({
22984
23330
  organizationId: external_exports.uuid(),
22985
23331
  name: external_exports.string(),
22986
23332
  slug: external_exports.string(),
22987
23333
  logoUrl: external_exports.string().nullable(),
23334
+ darkModeLogoUrl: external_exports.string().nullable(),
23335
+ capabilities: external_exports.array(external_exports.enum(OrgCapabilityValues)),
22988
23336
  createdAt: external_exports.date(),
22989
23337
  updatedAt: external_exports.date()
22990
23338
  });
22991
23339
  var ListOrganizationsResponseSchema = external_exports.array(OrganizationResponseSchema);
23340
+ var LogoDeleteRequestSchema = external_exports.object({
23341
+ variant: external_exports.enum(["light", "dark"])
23342
+ });
22992
23343
 
22993
23344
  // ../../packages/api-contracts/src/contracts/v1/organization.ts
22994
- var c8 = initContract();
22995
- var organizationContract = c8.router({
23345
+ var c9 = initContract();
23346
+ var organizationContract = c9.router({
22996
23347
  listOrganizations: {
22997
23348
  method: "GET",
22998
23349
  path: "/organizations",
@@ -23040,103 +23391,169 @@ var organizationContract = c8.router({
23040
23391
  404: ErrorResponseSchema,
23041
23392
  500: ErrorResponseSchema
23042
23393
  }
23394
+ },
23395
+ patchCapabilities: {
23396
+ method: "PATCH",
23397
+ path: "/organizations/:organizationId/capabilities",
23398
+ pathParams: OrgIdParamsSchema,
23399
+ body: PatchCapabilitiesRequestSchema,
23400
+ responses: {
23401
+ 200: PatchCapabilitiesResponseSchema,
23402
+ 401: ErrorResponseSchema,
23403
+ 403: ErrorResponseSchema,
23404
+ 404: ErrorResponseSchema,
23405
+ 500: ErrorResponseSchema
23406
+ }
23407
+ },
23408
+ generateLogoUploadUrl: {
23409
+ method: "POST",
23410
+ path: "/organizations/:organizationId/logo-upload-url",
23411
+ pathParams: OrgIdParamsSchema,
23412
+ body: LogoUploadRequestSchema,
23413
+ responses: {
23414
+ 200: LogoUploadResponseSchema,
23415
+ 401: ErrorResponseSchema,
23416
+ 403: ErrorResponseSchema,
23417
+ 404: ErrorResponseSchema,
23418
+ 500: ErrorResponseSchema
23419
+ }
23043
23420
  }
23044
23421
  });
23045
23422
 
23046
- // ../../packages/api-contracts/src/schemas/api/v1/repository.api.ts
23047
- var PlatformValues = ["GITHUB", "GITLAB", "BITBUCKET"];
23048
- var RepositoryStatusValues = ["CONNECTED", "DISCONNECTED"];
23049
- var RepositoryIdParamsSchema = OrgIdParamsSchema.extend({
23050
- repositoryId: external_exports.uuid()
23051
- });
23052
- var CreateRepositoryRequestSchema = external_exports.object({
23053
- repositoryUrl: external_exports.url(),
23054
- platform: external_exports.enum(PlatformValues),
23055
- defaultBranch: external_exports.string().min(1).max(255).optional(),
23056
- status: external_exports.enum(RepositoryStatusValues).optional()
23057
- });
23058
- var UpdateRepositoryRequestSchema = external_exports.object({
23059
- repositoryUrl: external_exports.url().optional(),
23060
- platform: external_exports.enum(PlatformValues).optional(),
23061
- defaultBranch: external_exports.string().min(1).max(255).optional(),
23062
- status: external_exports.enum(RepositoryStatusValues).optional()
23423
+ // ../../packages/api-contracts/src/schemas/domain/pentest.schema.ts
23424
+ var PentestStatusValues = ["SCOPING", "IN_PROGRESS", "REMEDIATION", "CLOSED"];
23425
+ var PentestStatus = external_exports.enum(PentestStatusValues);
23426
+ var PentestFindingStatusValues = [
23427
+ "OPEN",
23428
+ "IN_PROGRESS",
23429
+ "CONTESTED",
23430
+ "REMEDIATED",
23431
+ "VERIFIED_FIXED",
23432
+ "VERIFIED_OPEN",
23433
+ "DISMISSED"
23434
+ ];
23435
+ var PentestFindingStatus = external_exports.enum(PentestFindingStatusValues);
23436
+ var PentestFindingSeverityValues = [
23437
+ "INFORMATIONAL",
23438
+ "LOW",
23439
+ "MEDIUM",
23440
+ "HIGH",
23441
+ "CRITICAL"
23442
+ ];
23443
+ var PentestFindingSeverity = external_exports.enum(PentestFindingSeverityValues);
23444
+ var ContestReasonValues = [
23445
+ "FALSE_POSITIVE",
23446
+ "ACCEPTED_RISK",
23447
+ "MITIGATING_CONTROLS",
23448
+ "OUT_OF_SCOPE",
23449
+ "DUPLICATE",
23450
+ "OTHER"
23451
+ ];
23452
+ var ContestReason = external_exports.enum(ContestReasonValues);
23453
+ var RetestOutcomeValues = ["FIXED", "PARTIALLY_FIXED", "NOT_FIXED"];
23454
+ var RetestOutcome = external_exports.enum(RetestOutcomeValues);
23455
+
23456
+ // ../../packages/api-contracts/src/schemas/api/v1/pentest.api.ts
23457
+ var PentestIdParamsSchema = OrgIdParamsSchema.extend({
23458
+ pentestId: external_exports.string().min(1)
23063
23459
  });
23064
- var RepositoryResponseSchema = external_exports.object({
23065
- repositoryId: external_exports.uuid(),
23460
+ var PentestResponseSchema = external_exports.object({
23461
+ pentestId: external_exports.uuid(),
23066
23462
  organizationId: external_exports.uuid(),
23067
- repositoryUrl: external_exports.url(),
23068
- platform: external_exports.enum(PlatformValues),
23069
- status: external_exports.enum(RepositoryStatusValues),
23070
- defaultBranch: external_exports.string(),
23071
- createdAt: external_exports.date(),
23072
- updatedAt: external_exports.date()
23073
- });
23074
- var ListRepositoriesResponseSchema = external_exports.array(RepositoryResponseSchema);
23075
- var CloneTokenRequestSchema = external_exports.object({
23076
- repositoryUrl: external_exports.string().url()
23463
+ displayId: external_exports.number(),
23464
+ title: external_exports.string(),
23465
+ description: external_exports.string().nullable(),
23466
+ status: PentestStatus,
23467
+ scope: external_exports.string().nullable(),
23468
+ startedAt: external_exports.coerce.date().nullable(),
23469
+ endedAt: external_exports.coerce.date().nullable(),
23470
+ createdById: external_exports.uuid(),
23471
+ createdByName: external_exports.string(),
23472
+ createdAt: external_exports.coerce.date(),
23473
+ updatedAt: external_exports.coerce.date(),
23474
+ findingCounts: external_exports.object({
23475
+ total: external_exports.number(),
23476
+ bySeverity: external_exports.record(PentestFindingSeverity, external_exports.number()),
23477
+ byStatus: external_exports.record(PentestFindingStatus, external_exports.number())
23478
+ })
23077
23479
  });
23078
- var CloneTokenResponseSchema = external_exports.object({
23079
- token: external_exports.string(),
23080
- expiresAt: external_exports.string().datetime()
23480
+ var ListPentestsResponseSchema = external_exports.array(PentestResponseSchema);
23481
+ var CreatePentestRequestSchema = external_exports.object({
23482
+ title: external_exports.string().min(1).max(500),
23483
+ description: external_exports.string().max(1e4).optional(),
23484
+ scope: external_exports.string().max(5e4).optional(),
23485
+ status: PentestStatus.optional(),
23486
+ startedAt: external_exports.coerce.date().optional(),
23487
+ endedAt: external_exports.coerce.date().optional()
23488
+ });
23489
+ var UpdatePentestRequestSchema = external_exports.object({
23490
+ title: external_exports.string().min(1).max(500).optional(),
23491
+ description: external_exports.string().max(1e4).nullable().optional(),
23492
+ status: PentestStatus.optional(),
23493
+ scope: external_exports.string().max(5e4).nullable().optional(),
23494
+ startedAt: external_exports.coerce.date().nullable().optional(),
23495
+ endedAt: external_exports.coerce.date().nullable().optional()
23081
23496
  });
23082
23497
 
23083
- // ../../packages/api-contracts/src/contracts/v1/repository.ts
23084
- var c9 = initContract();
23085
- var repositoryContract = c9.router({
23086
- createRepository: {
23087
- method: "POST",
23088
- path: "/organizations/:organizationId/repositories",
23498
+ // ../../packages/api-contracts/src/contracts/v1/pentest.ts
23499
+ var c10 = initContract();
23500
+ var pentestContract = c10.router({
23501
+ listPentests: {
23502
+ method: "GET",
23503
+ path: "/organizations/:organizationId/pentests",
23089
23504
  pathParams: OrgIdParamsSchema,
23090
- body: CreateRepositoryRequestSchema,
23091
23505
  responses: {
23092
- 201: RepositoryResponseSchema,
23506
+ 200: ListPentestsResponseSchema,
23093
23507
  401: ErrorResponseSchema,
23094
23508
  403: ErrorResponseSchema,
23095
23509
  404: ErrorResponseSchema,
23096
23510
  500: ErrorResponseSchema
23097
23511
  }
23098
23512
  },
23099
- listRepositories: {
23100
- method: "GET",
23101
- path: "/organizations/:organizationId/repositories",
23513
+ createPentest: {
23514
+ method: "POST",
23515
+ path: "/organizations/:organizationId/pentests",
23102
23516
  pathParams: OrgIdParamsSchema,
23517
+ body: CreatePentestRequestSchema,
23103
23518
  responses: {
23104
- 200: ListRepositoriesResponseSchema,
23519
+ 201: PentestResponseSchema,
23520
+ 400: ErrorResponseSchema,
23105
23521
  401: ErrorResponseSchema,
23106
23522
  403: ErrorResponseSchema,
23107
23523
  404: ErrorResponseSchema,
23108
23524
  500: ErrorResponseSchema
23109
23525
  }
23110
23526
  },
23111
- getRepository: {
23527
+ getPentest: {
23112
23528
  method: "GET",
23113
- path: "/organizations/:organizationId/repositories/:repositoryId",
23114
- pathParams: RepositoryIdParamsSchema,
23529
+ path: "/organizations/:organizationId/pentests/:pentestId",
23530
+ pathParams: PentestIdParamsSchema,
23115
23531
  responses: {
23116
- 200: RepositoryResponseSchema,
23532
+ 200: PentestResponseSchema,
23117
23533
  401: ErrorResponseSchema,
23118
23534
  403: ErrorResponseSchema,
23119
23535
  404: ErrorResponseSchema,
23120
23536
  500: ErrorResponseSchema
23121
23537
  }
23122
23538
  },
23123
- updateRepository: {
23124
- method: "PUT",
23125
- path: "/organizations/:organizationId/repositories/:repositoryId",
23126
- pathParams: RepositoryIdParamsSchema,
23127
- body: UpdateRepositoryRequestSchema,
23539
+ updatePentest: {
23540
+ method: "PATCH",
23541
+ path: "/organizations/:organizationId/pentests/:pentestId",
23542
+ pathParams: PentestIdParamsSchema,
23543
+ body: UpdatePentestRequestSchema,
23128
23544
  responses: {
23129
- 200: RepositoryResponseSchema,
23545
+ 200: PentestResponseSchema,
23546
+ 400: ErrorResponseSchema,
23130
23547
  401: ErrorResponseSchema,
23131
23548
  403: ErrorResponseSchema,
23132
23549
  404: ErrorResponseSchema,
23133
23550
  500: ErrorResponseSchema
23134
23551
  }
23135
23552
  },
23136
- deleteRepository: {
23553
+ deletePentest: {
23137
23554
  method: "DELETE",
23138
- path: "/organizations/:organizationId/repositories/:repositoryId",
23139
- pathParams: RepositoryIdParamsSchema,
23555
+ path: "/organizations/:organizationId/pentests/:pentestId",
23556
+ pathParams: PentestIdParamsSchema,
23140
23557
  responses: {
23141
23558
  204: DeleteResponseSchema,
23142
23559
  401: ErrorResponseSchema,
@@ -23144,26 +23561,554 @@ var repositoryContract = c9.router({
23144
23561
  404: ErrorResponseSchema,
23145
23562
  500: ErrorResponseSchema
23146
23563
  }
23147
- },
23148
- getCloneToken: {
23149
- method: "POST",
23150
- path: "/organizations/:organizationId/repositories/clone-token",
23151
- pathParams: OrgIdParamsSchema,
23152
- body: CloneTokenRequestSchema,
23153
- responses: {
23154
- 200: CloneTokenResponseSchema,
23155
- 401: ErrorResponseSchema,
23156
- 403: ErrorResponseSchema,
23157
- 404: ErrorResponseSchema,
23158
- 500: ErrorResponseSchema
23159
- }
23160
23564
  }
23161
23565
  });
23162
23566
 
23163
- // ../../packages/api-contracts/src/schemas/domain/scan.schema.ts
23164
- var ScanStatusValues = [
23165
- "PENDING",
23166
- "QUEUED",
23567
+ // ../../packages/api-contracts/src/schemas/api/v1/pentest-finding.api.ts
23568
+ var PentestFindingParamsSchema = OrgIdParamsSchema.extend({
23569
+ pentestId: external_exports.uuid()
23570
+ });
23571
+ var PentestFindingIdParamsSchema = PentestFindingParamsSchema.extend({
23572
+ pentestFindingId: external_exports.uuid()
23573
+ });
23574
+ var PentestFindingContestIdParamsSchema = PentestFindingIdParamsSchema.extend({
23575
+ contestId: external_exports.uuid()
23576
+ });
23577
+ var PentestFindingRetestIdParamsSchema = PentestFindingIdParamsSchema.extend({
23578
+ retestId: external_exports.uuid()
23579
+ });
23580
+ var PentestFindingNoteIdParamsSchema = PentestFindingIdParamsSchema.extend({
23581
+ noteId: external_exports.uuid()
23582
+ });
23583
+ var PentestFindingRepositorySchema = external_exports.object({
23584
+ repositoryId: external_exports.uuid(),
23585
+ repositoryName: external_exports.string(),
23586
+ commitSha: external_exports.string().nullable(),
23587
+ filePath: external_exports.string().nullable(),
23588
+ startLine: external_exports.number().nullable(),
23589
+ endLine: external_exports.number().nullable()
23590
+ });
23591
+ var PentestFindingResponseSchema = external_exports.object({
23592
+ pentestFindingId: external_exports.uuid(),
23593
+ organizationId: external_exports.uuid(),
23594
+ pentestId: external_exports.uuid(),
23595
+ displayId: external_exports.number(),
23596
+ title: external_exports.string(),
23597
+ description: external_exports.string(),
23598
+ severity: PentestFindingSeverity,
23599
+ category: external_exports.string(),
23600
+ status: PentestFindingStatus,
23601
+ cweIds: external_exports.array(external_exports.string()),
23602
+ cvssVector: external_exports.string().nullable(),
23603
+ cvssScore: external_exports.number().nullable(),
23604
+ owaspCategory: external_exports.string().nullable(),
23605
+ proofOfConcept: external_exports.string().nullable(),
23606
+ remediation: external_exports.string().nullable(),
23607
+ publishedAt: external_exports.coerce.date().nullable(),
23608
+ createdById: external_exports.uuid(),
23609
+ createdByName: external_exports.string(),
23610
+ createdAt: external_exports.coerce.date(),
23611
+ updatedAt: external_exports.coerce.date(),
23612
+ repositories: external_exports.array(PentestFindingRepositorySchema),
23613
+ vulnerabilityIds: external_exports.array(external_exports.uuid())
23614
+ });
23615
+ var ListPentestFindingsResponseSchema = external_exports.array(PentestFindingResponseSchema);
23616
+ var CreatePentestFindingRequestSchema = external_exports.object({
23617
+ title: external_exports.string().min(1).max(500),
23618
+ description: external_exports.string().min(1).max(5e4),
23619
+ severity: PentestFindingSeverity,
23620
+ category: external_exports.string().min(1).max(200),
23621
+ status: PentestFindingStatus.optional(),
23622
+ cweIds: external_exports.array(external_exports.string()).optional(),
23623
+ cvssVector: external_exports.string().max(200).optional(),
23624
+ cvssScore: external_exports.number().min(0).max(10).optional(),
23625
+ owaspCategory: external_exports.string().max(200).optional(),
23626
+ proofOfConcept: external_exports.string().max(5e4).optional(),
23627
+ remediation: external_exports.string().max(5e4).optional(),
23628
+ repositories: external_exports.array(
23629
+ external_exports.object({
23630
+ repositoryId: external_exports.uuid(),
23631
+ commitSha: external_exports.string().optional(),
23632
+ filePath: external_exports.string().optional(),
23633
+ startLine: external_exports.number().int().optional(),
23634
+ endLine: external_exports.number().int().optional()
23635
+ })
23636
+ ).optional(),
23637
+ vulnerabilityIds: external_exports.array(external_exports.uuid()).optional()
23638
+ });
23639
+ var UpdatePentestFindingRequestSchema = external_exports.object({
23640
+ title: external_exports.string().min(1).max(500).optional(),
23641
+ description: external_exports.string().min(1).max(5e4).optional(),
23642
+ severity: PentestFindingSeverity.optional(),
23643
+ category: external_exports.string().min(1).max(200).optional(),
23644
+ status: PentestFindingStatus.optional(),
23645
+ cweIds: external_exports.array(external_exports.string()).optional(),
23646
+ cvssVector: external_exports.string().max(200).nullable().optional(),
23647
+ cvssScore: external_exports.number().min(0).max(10).nullable().optional(),
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(),
23651
+ publishedAt: external_exports.coerce.date().nullable().optional(),
23652
+ repositories: external_exports.array(
23653
+ external_exports.object({
23654
+ repositoryId: external_exports.uuid(),
23655
+ commitSha: external_exports.string().optional(),
23656
+ filePath: external_exports.string().optional(),
23657
+ startLine: external_exports.number().int().optional(),
23658
+ endLine: external_exports.number().int().optional()
23659
+ })
23660
+ ).optional(),
23661
+ vulnerabilityIds: external_exports.array(external_exports.uuid()).optional()
23662
+ });
23663
+ var PentestFindingContestResponseSchema = external_exports.object({
23664
+ contestId: external_exports.uuid(),
23665
+ pentestFindingId: external_exports.uuid(),
23666
+ organizationId: external_exports.uuid(),
23667
+ reason: ContestReason,
23668
+ justification: external_exports.string(),
23669
+ contestedById: external_exports.uuid(),
23670
+ contestedByName: external_exports.string(),
23671
+ contestedAt: external_exports.coerce.date(),
23672
+ resolution: external_exports.string().nullable(),
23673
+ resolvedById: external_exports.uuid().nullable(),
23674
+ resolvedByName: external_exports.string().nullable(),
23675
+ resolvedAt: external_exports.coerce.date().nullable()
23676
+ });
23677
+ var ListPentestFindingContestsResponseSchema = external_exports.array(
23678
+ PentestFindingContestResponseSchema
23679
+ );
23680
+ var CreatePentestFindingContestRequestSchema = external_exports.object({
23681
+ reason: ContestReason,
23682
+ justification: external_exports.string().min(1).max(1e4)
23683
+ });
23684
+ var ResolvePentestFindingContestRequestSchema = external_exports.object({
23685
+ resolution: external_exports.string().min(1).max(1e4)
23686
+ });
23687
+ var PentestFindingRetestResponseSchema = external_exports.object({
23688
+ retestId: external_exports.uuid(),
23689
+ pentestFindingId: external_exports.uuid(),
23690
+ organizationId: external_exports.uuid(),
23691
+ outcome: RetestOutcome,
23692
+ notes: external_exports.string().nullable(),
23693
+ testedById: external_exports.uuid(),
23694
+ testedByName: external_exports.string(),
23695
+ testedAt: external_exports.coerce.date()
23696
+ });
23697
+ var ListPentestFindingRetestsResponseSchema = external_exports.array(PentestFindingRetestResponseSchema);
23698
+ var CreatePentestFindingRetestRequestSchema = external_exports.object({
23699
+ outcome: RetestOutcome,
23700
+ notes: external_exports.string().max(1e4).optional()
23701
+ });
23702
+ var PentestFindingNoteResponseSchema = external_exports.object({
23703
+ noteId: external_exports.uuid(),
23704
+ pentestFindingId: external_exports.uuid(),
23705
+ organizationId: external_exports.uuid(),
23706
+ authorId: external_exports.uuid(),
23707
+ authorName: external_exports.string(),
23708
+ content: external_exports.string(),
23709
+ createdAt: external_exports.coerce.date(),
23710
+ updatedAt: external_exports.coerce.date()
23711
+ });
23712
+ var ListPentestFindingNotesResponseSchema = external_exports.array(PentestFindingNoteResponseSchema);
23713
+ var CreatePentestFindingNoteRequestSchema = external_exports.object({
23714
+ content: external_exports.string().min(1).max(1e4)
23715
+ });
23716
+ var UpdatePentestFindingNoteRequestSchema = external_exports.object({
23717
+ content: external_exports.string().min(1).max(1e4)
23718
+ });
23719
+ var ParseFindingMarkdownRequestSchema = external_exports.object({
23720
+ markdown: external_exports.string().min(1).max(1e5)
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
+ });
23729
+ var ParseFindingMarkdownResponseSchema = external_exports.object({
23730
+ title: external_exports.string(),
23731
+ description: external_exports.string(),
23732
+ severity: PentestFindingSeverity,
23733
+ category: external_exports.string(),
23734
+ status: PentestFindingStatus,
23735
+ cweIds: external_exports.array(external_exports.string()),
23736
+ cvssVector: external_exports.string().nullable(),
23737
+ cvssScore: external_exports.number().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()
23755
+ });
23756
+
23757
+ // ../../packages/api-contracts/src/contracts/v1/pentest-finding.ts
23758
+ var c11 = initContract();
23759
+ var pentestFindingContract = c11.router({
23760
+ // ─── Findings ───
23761
+ listFindings: {
23762
+ method: "GET",
23763
+ path: "/organizations/:organizationId/pentests/:pentestId/findings",
23764
+ pathParams: PentestFindingParamsSchema,
23765
+ responses: {
23766
+ 200: ListPentestFindingsResponseSchema,
23767
+ 401: ErrorResponseSchema,
23768
+ 403: ErrorResponseSchema,
23769
+ 404: ErrorResponseSchema,
23770
+ 500: ErrorResponseSchema
23771
+ }
23772
+ },
23773
+ createFinding: {
23774
+ method: "POST",
23775
+ path: "/organizations/:organizationId/pentests/:pentestId/findings",
23776
+ pathParams: PentestFindingParamsSchema,
23777
+ body: CreatePentestFindingRequestSchema,
23778
+ responses: {
23779
+ 201: PentestFindingResponseSchema,
23780
+ 400: ErrorResponseSchema,
23781
+ 401: ErrorResponseSchema,
23782
+ 403: ErrorResponseSchema,
23783
+ 404: ErrorResponseSchema,
23784
+ 500: ErrorResponseSchema
23785
+ }
23786
+ },
23787
+ getFinding: {
23788
+ method: "GET",
23789
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId",
23790
+ pathParams: PentestFindingIdParamsSchema,
23791
+ responses: {
23792
+ 200: PentestFindingResponseSchema,
23793
+ 401: ErrorResponseSchema,
23794
+ 403: ErrorResponseSchema,
23795
+ 404: ErrorResponseSchema,
23796
+ 500: ErrorResponseSchema
23797
+ }
23798
+ },
23799
+ updateFinding: {
23800
+ method: "PATCH",
23801
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId",
23802
+ pathParams: PentestFindingIdParamsSchema,
23803
+ body: UpdatePentestFindingRequestSchema,
23804
+ responses: {
23805
+ 200: PentestFindingResponseSchema,
23806
+ 400: ErrorResponseSchema,
23807
+ 401: ErrorResponseSchema,
23808
+ 403: ErrorResponseSchema,
23809
+ 404: ErrorResponseSchema,
23810
+ 500: ErrorResponseSchema
23811
+ }
23812
+ },
23813
+ deleteFinding: {
23814
+ method: "DELETE",
23815
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId",
23816
+ pathParams: PentestFindingIdParamsSchema,
23817
+ responses: {
23818
+ 204: DeleteResponseSchema,
23819
+ 401: ErrorResponseSchema,
23820
+ 403: ErrorResponseSchema,
23821
+ 404: ErrorResponseSchema,
23822
+ 500: ErrorResponseSchema
23823
+ }
23824
+ },
23825
+ // ─── Contests ───
23826
+ listContests: {
23827
+ method: "GET",
23828
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/contests",
23829
+ pathParams: PentestFindingIdParamsSchema,
23830
+ responses: {
23831
+ 200: ListPentestFindingContestsResponseSchema,
23832
+ 401: ErrorResponseSchema,
23833
+ 403: ErrorResponseSchema,
23834
+ 404: ErrorResponseSchema,
23835
+ 500: ErrorResponseSchema
23836
+ }
23837
+ },
23838
+ createContest: {
23839
+ method: "POST",
23840
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/contests",
23841
+ pathParams: PentestFindingIdParamsSchema,
23842
+ body: CreatePentestFindingContestRequestSchema,
23843
+ responses: {
23844
+ 201: PentestFindingContestResponseSchema,
23845
+ 400: ErrorResponseSchema,
23846
+ 401: ErrorResponseSchema,
23847
+ 403: ErrorResponseSchema,
23848
+ 404: ErrorResponseSchema,
23849
+ 500: ErrorResponseSchema
23850
+ }
23851
+ },
23852
+ resolveContest: {
23853
+ method: "PATCH",
23854
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/contests/:contestId",
23855
+ pathParams: PentestFindingContestIdParamsSchema,
23856
+ body: ResolvePentestFindingContestRequestSchema,
23857
+ responses: {
23858
+ 200: PentestFindingContestResponseSchema,
23859
+ 400: ErrorResponseSchema,
23860
+ 401: ErrorResponseSchema,
23861
+ 403: ErrorResponseSchema,
23862
+ 404: ErrorResponseSchema,
23863
+ 500: ErrorResponseSchema
23864
+ }
23865
+ },
23866
+ // ─── Retests ───
23867
+ listRetests: {
23868
+ method: "GET",
23869
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/retests",
23870
+ pathParams: PentestFindingIdParamsSchema,
23871
+ responses: {
23872
+ 200: ListPentestFindingRetestsResponseSchema,
23873
+ 401: ErrorResponseSchema,
23874
+ 403: ErrorResponseSchema,
23875
+ 404: ErrorResponseSchema,
23876
+ 500: ErrorResponseSchema
23877
+ }
23878
+ },
23879
+ createRetest: {
23880
+ method: "POST",
23881
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/retests",
23882
+ pathParams: PentestFindingIdParamsSchema,
23883
+ body: CreatePentestFindingRetestRequestSchema,
23884
+ responses: {
23885
+ 201: PentestFindingRetestResponseSchema,
23886
+ 400: ErrorResponseSchema,
23887
+ 401: ErrorResponseSchema,
23888
+ 403: ErrorResponseSchema,
23889
+ 404: ErrorResponseSchema,
23890
+ 500: ErrorResponseSchema
23891
+ }
23892
+ },
23893
+ // ─── Notes ───
23894
+ listNotes: {
23895
+ method: "GET",
23896
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes",
23897
+ pathParams: PentestFindingIdParamsSchema,
23898
+ responses: {
23899
+ 200: ListPentestFindingNotesResponseSchema,
23900
+ 401: ErrorResponseSchema,
23901
+ 403: ErrorResponseSchema,
23902
+ 404: ErrorResponseSchema,
23903
+ 500: ErrorResponseSchema
23904
+ }
23905
+ },
23906
+ createNote: {
23907
+ method: "POST",
23908
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes",
23909
+ pathParams: PentestFindingIdParamsSchema,
23910
+ body: CreatePentestFindingNoteRequestSchema,
23911
+ responses: {
23912
+ 201: PentestFindingNoteResponseSchema,
23913
+ 400: ErrorResponseSchema,
23914
+ 401: ErrorResponseSchema,
23915
+ 403: ErrorResponseSchema,
23916
+ 404: ErrorResponseSchema,
23917
+ 500: ErrorResponseSchema
23918
+ }
23919
+ },
23920
+ updateNote: {
23921
+ method: "PATCH",
23922
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes/:noteId",
23923
+ pathParams: PentestFindingNoteIdParamsSchema,
23924
+ body: UpdatePentestFindingNoteRequestSchema,
23925
+ responses: {
23926
+ 200: PentestFindingNoteResponseSchema,
23927
+ 400: ErrorResponseSchema,
23928
+ 401: ErrorResponseSchema,
23929
+ 403: ErrorResponseSchema,
23930
+ 404: ErrorResponseSchema,
23931
+ 500: ErrorResponseSchema
23932
+ }
23933
+ },
23934
+ deleteNote: {
23935
+ method: "DELETE",
23936
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/:pentestFindingId/notes/:noteId",
23937
+ pathParams: PentestFindingNoteIdParamsSchema,
23938
+ responses: {
23939
+ 204: DeleteResponseSchema,
23940
+ 401: ErrorResponseSchema,
23941
+ 403: ErrorResponseSchema,
23942
+ 404: ErrorResponseSchema,
23943
+ 500: ErrorResponseSchema
23944
+ }
23945
+ },
23946
+ // ─── AI parsing ───
23947
+ parseFindingMarkdown: {
23948
+ method: "POST",
23949
+ path: "/organizations/:organizationId/pentests/:pentestId/findings/parse-markdown",
23950
+ pathParams: PentestFindingParamsSchema,
23951
+ body: ParseFindingMarkdownRequestSchema,
23952
+ responses: {
23953
+ 200: ParseFindingMarkdownResponseSchema,
23954
+ 400: ErrorResponseSchema,
23955
+ 401: ErrorResponseSchema,
23956
+ 403: ErrorResponseSchema,
23957
+ 404: ErrorResponseSchema,
23958
+ 500: ErrorResponseSchema
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
+ }
23987
+ }
23988
+ });
23989
+
23990
+ // ../../packages/api-contracts/src/schemas/api/v1/repository.api.ts
23991
+ var PlatformValues = ["GITHUB", "GITLAB", "BITBUCKET"];
23992
+ var RepositoryStatusValues = ["CONNECTED", "DISCONNECTED"];
23993
+ var RepositoryIdParamsSchema = OrgIdParamsSchema.extend({
23994
+ repositoryId: external_exports.uuid()
23995
+ });
23996
+ var CreateRepositoryRequestSchema = external_exports.object({
23997
+ repositoryUrl: external_exports.url(),
23998
+ platform: external_exports.enum(PlatformValues),
23999
+ defaultBranch: external_exports.string().min(1).max(255).optional(),
24000
+ status: external_exports.enum(RepositoryStatusValues).optional()
24001
+ });
24002
+ var UpdateRepositoryRequestSchema = external_exports.object({
24003
+ repositoryUrl: external_exports.url().optional(),
24004
+ platform: external_exports.enum(PlatformValues).optional(),
24005
+ defaultBranch: external_exports.string().min(1).max(255).optional(),
24006
+ status: external_exports.enum(RepositoryStatusValues).optional()
24007
+ });
24008
+ var RepositoryResponseSchema = external_exports.object({
24009
+ repositoryId: external_exports.uuid(),
24010
+ organizationId: external_exports.uuid(),
24011
+ repositoryUrl: external_exports.url(),
24012
+ platform: external_exports.enum(PlatformValues),
24013
+ status: external_exports.enum(RepositoryStatusValues),
24014
+ defaultBranch: external_exports.string(),
24015
+ primaryLanguage: external_exports.string().nullable().optional(),
24016
+ createdAt: external_exports.date(),
24017
+ updatedAt: external_exports.date()
24018
+ });
24019
+ var ListRepositoriesResponseSchema = external_exports.array(RepositoryResponseSchema);
24020
+ var CloneTokenRequestSchema = external_exports.object({
24021
+ repositoryUrl: external_exports.string().url()
24022
+ });
24023
+ var CloneTokenResponseSchema = external_exports.object({
24024
+ token: external_exports.string(),
24025
+ expiresAt: external_exports.string().datetime()
24026
+ });
24027
+
24028
+ // ../../packages/api-contracts/src/contracts/v1/repository.ts
24029
+ var c12 = initContract();
24030
+ var repositoryContract = c12.router({
24031
+ createRepository: {
24032
+ method: "POST",
24033
+ path: "/organizations/:organizationId/repositories",
24034
+ pathParams: OrgIdParamsSchema,
24035
+ body: CreateRepositoryRequestSchema,
24036
+ responses: {
24037
+ 201: RepositoryResponseSchema,
24038
+ 401: ErrorResponseSchema,
24039
+ 403: ErrorResponseSchema,
24040
+ 404: ErrorResponseSchema,
24041
+ 500: ErrorResponseSchema
24042
+ }
24043
+ },
24044
+ listRepositories: {
24045
+ method: "GET",
24046
+ path: "/organizations/:organizationId/repositories",
24047
+ pathParams: OrgIdParamsSchema,
24048
+ responses: {
24049
+ 200: ListRepositoriesResponseSchema,
24050
+ 401: ErrorResponseSchema,
24051
+ 403: ErrorResponseSchema,
24052
+ 404: ErrorResponseSchema,
24053
+ 500: ErrorResponseSchema
24054
+ }
24055
+ },
24056
+ getRepository: {
24057
+ method: "GET",
24058
+ path: "/organizations/:organizationId/repositories/:repositoryId",
24059
+ pathParams: RepositoryIdParamsSchema,
24060
+ responses: {
24061
+ 200: RepositoryResponseSchema,
24062
+ 401: ErrorResponseSchema,
24063
+ 403: ErrorResponseSchema,
24064
+ 404: ErrorResponseSchema,
24065
+ 500: ErrorResponseSchema
24066
+ }
24067
+ },
24068
+ updateRepository: {
24069
+ method: "PUT",
24070
+ path: "/organizations/:organizationId/repositories/:repositoryId",
24071
+ pathParams: RepositoryIdParamsSchema,
24072
+ body: UpdateRepositoryRequestSchema,
24073
+ responses: {
24074
+ 200: RepositoryResponseSchema,
24075
+ 401: ErrorResponseSchema,
24076
+ 403: ErrorResponseSchema,
24077
+ 404: ErrorResponseSchema,
24078
+ 500: ErrorResponseSchema
24079
+ }
24080
+ },
24081
+ deleteRepository: {
24082
+ method: "DELETE",
24083
+ path: "/organizations/:organizationId/repositories/:repositoryId",
24084
+ pathParams: RepositoryIdParamsSchema,
24085
+ responses: {
24086
+ 204: DeleteResponseSchema,
24087
+ 401: ErrorResponseSchema,
24088
+ 403: ErrorResponseSchema,
24089
+ 404: ErrorResponseSchema,
24090
+ 500: ErrorResponseSchema
24091
+ }
24092
+ },
24093
+ getCloneToken: {
24094
+ method: "POST",
24095
+ path: "/organizations/:organizationId/repositories/clone-token",
24096
+ pathParams: OrgIdParamsSchema,
24097
+ body: CloneTokenRequestSchema,
24098
+ responses: {
24099
+ 200: CloneTokenResponseSchema,
24100
+ 401: ErrorResponseSchema,
24101
+ 403: ErrorResponseSchema,
24102
+ 404: ErrorResponseSchema,
24103
+ 500: ErrorResponseSchema
24104
+ }
24105
+ }
24106
+ });
24107
+
24108
+ // ../../packages/api-contracts/src/schemas/domain/scan.schema.ts
24109
+ var ScanStatusValues = [
24110
+ "PENDING",
24111
+ "QUEUED",
23167
24112
  "RUNNING",
23168
24113
  "COMPLETED",
23169
24114
  "FAILED",
@@ -23247,9 +24192,18 @@ var ScanResponseSchema = external_exports.object({
23247
24192
  updatedAt: external_exports.date()
23248
24193
  });
23249
24194
  var ListScansQuerySchema = external_exports.object({
23250
- status: external_exports.enum(ScanStatusValues).array().or(external_exports.enum(ScanStatusValues)).optional()
24195
+ status: external_exports.enum(ScanStatusValues).array().or(external_exports.enum(ScanStatusValues)).optional(),
24196
+ repositoryId: external_exports.uuid().optional(),
24197
+ page: external_exports.coerce.number().int().min(1).max(1e4).optional(),
24198
+ pageSize: external_exports.coerce.number().int().min(1).max(200).optional()
24199
+ });
24200
+ var ListScansResponseSchema = external_exports.object({
24201
+ scans: external_exports.array(ScanResponseSchema),
24202
+ total: external_exports.number(),
24203
+ page: external_exports.number(),
24204
+ pageSize: external_exports.number()
23251
24205
  });
23252
- var ListScansResponseSchema = external_exports.array(ScanResponseSchema);
24206
+ var ScanArrayResponseSchema = external_exports.array(ScanResponseSchema);
23253
24207
  var CancelScanResponseSchema = external_exports.object({
23254
24208
  scanId: external_exports.uuid(),
23255
24209
  status: external_exports.literal("CANCELLED")
@@ -23271,8 +24225,8 @@ var ListScanLogsResponseSchema = external_exports.object({
23271
24225
  });
23272
24226
 
23273
24227
  // ../../packages/api-contracts/src/contracts/v1/scan.ts
23274
- var c10 = initContract();
23275
- var scanContract = c10.router({
24228
+ var c13 = initContract();
24229
+ var scanContract = c13.router({
23276
24230
  createScan: {
23277
24231
  method: "POST",
23278
24232
  path: "/organizations/:organizationId/scans",
@@ -23370,14 +24324,15 @@ var UserResponseSchema = external_exports.object({
23370
24324
  lastName: external_exports.string(),
23371
24325
  email: external_exports.string(),
23372
24326
  profilePictureUrl: external_exports.string().nullable(),
24327
+ isStaff: external_exports.boolean(),
23373
24328
  createdAt: external_exports.date(),
23374
24329
  updatedAt: external_exports.date()
23375
24330
  });
23376
24331
  var ListUsersResponseSchema = external_exports.array(UserResponseSchema);
23377
24332
 
23378
24333
  // ../../packages/api-contracts/src/contracts/v1/user.ts
23379
- var c11 = initContract();
23380
- var userContract = c11.router({
24334
+ var c14 = initContract();
24335
+ var userContract = c14.router({
23381
24336
  listUsers: {
23382
24337
  method: "GET",
23383
24338
  path: "/organizations/:organizationId/users",
@@ -23449,8 +24404,8 @@ var VantaIntegrationResponseSchema = external_exports.object({
23449
24404
  });
23450
24405
 
23451
24406
  // ../../packages/api-contracts/src/contracts/v1/vanta-integration.ts
23452
- var c12 = initContract();
23453
- var vantaIntegrationContract = c12.router({
24407
+ var c15 = initContract();
24408
+ var vantaIntegrationContract = c15.router({
23454
24409
  createVantaIntegration: {
23455
24410
  method: "POST",
23456
24411
  path: "/organizations/:organizationId/vanta-integration",
@@ -23510,7 +24465,8 @@ var VulnerabilityStatusValues = [
23510
24465
  "IN_PROGRESS",
23511
24466
  "FIXED",
23512
24467
  "IGNORED",
23513
- "FALSE_POSITIVE"
24468
+ "FALSE_POSITIVE",
24469
+ "DISMISSED"
23514
24470
  ];
23515
24471
  var VulnerabilityStatus = external_exports.enum(VulnerabilityStatusValues);
23516
24472
  var VulnerabilitySeverityValues = ["LOW", "MEDIUM", "HIGH", "CRITICAL"];
@@ -23523,6 +24479,8 @@ var VulnerabilityTypeValues = [
23523
24479
  "MISCONFIGURATION"
23524
24480
  ];
23525
24481
  var VulnerabilityType = external_exports.enum(VulnerabilityTypeValues);
24482
+ var DismissReasonValues = ["ACCEPTED_RISK", "FALSE_POSITIVE", "OTHER"];
24483
+ var DismissReason = external_exports.enum(DismissReasonValues);
23526
24484
  var ScanModeValues2 = ["SAST", "DAST", "SCA", "SECRETS"];
23527
24485
  var ScanMode2 = external_exports.enum(ScanModeValues2);
23528
24486
 
@@ -23551,7 +24509,12 @@ var VulnerabilityLatestFindingSchema = external_exports.object({
23551
24509
  attackVector: external_exports.string(),
23552
24510
  exploitScenario: external_exports.string(),
23553
24511
  impact: external_exports.string(),
23554
- confidence: external_exports.number()
24512
+ confidence: external_exports.number(),
24513
+ // Threat model fields (null for findings from scans before this feature)
24514
+ classification: external_exports.enum(["vulnerability", "defense_in_depth", "context_dependent"]).nullable(),
24515
+ prerequisiteAccess: external_exports.string().nullable(),
24516
+ capabilityGain: external_exports.string().nullable(),
24517
+ technicalSeverity: VulnerabilitySeverity.nullable()
23555
24518
  });
23556
24519
  var DependencyGraphSchema = external_exports.object({
23557
24520
  vulnerablePackage: external_exports.string(),
@@ -23575,6 +24538,7 @@ var VulnerabilityResponseSchema = external_exports.object({
23575
24538
  scanMode: ScanMode2.nullable(),
23576
24539
  status: VulnerabilityStatus,
23577
24540
  statusReason: external_exports.string().nullable(),
24541
+ dismissReason: DismissReason.nullable(),
23578
24542
  cweId: external_exports.string().nullable(),
23579
24543
  source: VulnerabilitySourceSchema,
23580
24544
  introducedBy: VulnerabilityIntroducedBySchema,
@@ -23661,12 +24625,13 @@ var VulnerabilityAggregatedCountsResponseSchema = external_exports.object({
23661
24625
  });
23662
24626
  var UpdateVulnerabilityRequestSchema = external_exports.object({
23663
24627
  status: VulnerabilityStatus.optional(),
23664
- statusReason: external_exports.string().optional()
24628
+ statusReason: external_exports.string().optional(),
24629
+ dismissReason: DismissReason.optional()
23665
24630
  });
23666
24631
 
23667
24632
  // ../../packages/api-contracts/src/contracts/v1/vulnerability.ts
23668
- var c13 = initContract();
23669
- var vulnerabilityContract = c13.router({
24633
+ var c16 = initContract();
24634
+ var vulnerabilityContract = c16.router({
23670
24635
  filterVulnerabilities: {
23671
24636
  method: "POST",
23672
24637
  path: "/organizations/:organizationId/vulnerabilities/filter",
@@ -23775,7 +24740,90 @@ var vulnerabilityContract = c13.router({
23775
24740
  path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/retests",
23776
24741
  pathParams: VulnerabilityIdParamsSchema,
23777
24742
  responses: {
23778
- 200: ListScansResponseSchema,
24743
+ 200: ScanArrayResponseSchema,
24744
+ 401: ErrorResponseSchema,
24745
+ 403: ErrorResponseSchema,
24746
+ 404: ErrorResponseSchema,
24747
+ 500: ErrorResponseSchema
24748
+ }
24749
+ }
24750
+ });
24751
+
24752
+ // ../../packages/api-contracts/src/schemas/api/v1/vulnerability-note.api.ts
24753
+ var VulnerabilityNoteParamsSchema = OrgIdParamsSchema.extend({
24754
+ vulnerabilityId: external_exports.uuid()
24755
+ });
24756
+ var VulnerabilityNoteIdParamsSchema = VulnerabilityNoteParamsSchema.extend({
24757
+ noteId: external_exports.uuid()
24758
+ });
24759
+ var VulnerabilityNoteResponseSchema = external_exports.object({
24760
+ noteId: external_exports.uuid(),
24761
+ vulnerabilityId: external_exports.uuid(),
24762
+ organizationId: external_exports.uuid(),
24763
+ authorId: external_exports.uuid(),
24764
+ authorName: external_exports.string(),
24765
+ authorProfilePictureUrl: external_exports.string().nullable(),
24766
+ content: external_exports.string(),
24767
+ createdAt: external_exports.coerce.date(),
24768
+ updatedAt: external_exports.coerce.date()
24769
+ });
24770
+ var ListVulnerabilityNotesResponseSchema = external_exports.array(VulnerabilityNoteResponseSchema);
24771
+ var CreateVulnerabilityNoteRequestSchema = external_exports.object({
24772
+ content: external_exports.string().max(1e4)
24773
+ });
24774
+ var UpdateVulnerabilityNoteRequestSchema = external_exports.object({
24775
+ content: external_exports.string().max(1e4)
24776
+ });
24777
+
24778
+ // ../../packages/api-contracts/src/contracts/v1/vulnerability-note.ts
24779
+ var c17 = initContract();
24780
+ var vulnerabilityNoteContract = c17.router({
24781
+ listNotes: {
24782
+ method: "GET",
24783
+ path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes",
24784
+ pathParams: VulnerabilityNoteParamsSchema,
24785
+ responses: {
24786
+ 200: ListVulnerabilityNotesResponseSchema,
24787
+ 401: ErrorResponseSchema,
24788
+ 403: ErrorResponseSchema,
24789
+ 404: ErrorResponseSchema,
24790
+ 500: ErrorResponseSchema
24791
+ }
24792
+ },
24793
+ createNote: {
24794
+ method: "POST",
24795
+ path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes",
24796
+ pathParams: VulnerabilityNoteParamsSchema,
24797
+ body: CreateVulnerabilityNoteRequestSchema,
24798
+ responses: {
24799
+ 201: VulnerabilityNoteResponseSchema,
24800
+ 400: ErrorResponseSchema,
24801
+ 401: ErrorResponseSchema,
24802
+ 403: ErrorResponseSchema,
24803
+ 404: ErrorResponseSchema,
24804
+ 500: ErrorResponseSchema
24805
+ }
24806
+ },
24807
+ updateNote: {
24808
+ method: "PATCH",
24809
+ path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes/:noteId",
24810
+ pathParams: VulnerabilityNoteIdParamsSchema,
24811
+ body: UpdateVulnerabilityNoteRequestSchema,
24812
+ responses: {
24813
+ 200: VulnerabilityNoteResponseSchema,
24814
+ 400: ErrorResponseSchema,
24815
+ 401: ErrorResponseSchema,
24816
+ 403: ErrorResponseSchema,
24817
+ 404: ErrorResponseSchema,
24818
+ 500: ErrorResponseSchema
24819
+ }
24820
+ },
24821
+ deleteNote: {
24822
+ method: "DELETE",
24823
+ path: "/organizations/:organizationId/vulnerabilities/:vulnerabilityId/notes/:noteId",
24824
+ pathParams: VulnerabilityNoteIdParamsSchema,
24825
+ responses: {
24826
+ 204: DeleteResponseSchema,
23779
24827
  401: ErrorResponseSchema,
23780
24828
  403: ErrorResponseSchema,
23781
24829
  404: ErrorResponseSchema,
@@ -23801,8 +24849,8 @@ var WebApplicationResponseSchema = external_exports.object({
23801
24849
  var ListWebApplicationsResponseSchema = external_exports.array(WebApplicationResponseSchema);
23802
24850
 
23803
24851
  // ../../packages/api-contracts/src/contracts/v1/web-application.ts
23804
- var c14 = initContract();
23805
- var webApplicationContract = c14.router({
24852
+ var c18 = initContract();
24853
+ var webApplicationContract = c18.router({
23806
24854
  listWebApplications: {
23807
24855
  method: "GET",
23808
24856
  path: "/organizations/:organizationId/web-applications",
@@ -23941,8 +24989,8 @@ var ListWebhookDeliveriesResponseSchema = external_exports.object({
23941
24989
  });
23942
24990
 
23943
24991
  // ../../packages/api-contracts/src/contracts/v1/webhook-settings.ts
23944
- var c15 = initContract();
23945
- var webhookSettingsContract = c15.router({
24992
+ var c19 = initContract();
24993
+ var webhookSettingsContract = c19.router({
23946
24994
  listWebhookEndpoints: {
23947
24995
  method: "GET",
23948
24996
  path: "/organizations/:organizationId/webhook-settings/endpoints",
@@ -24080,8 +25128,8 @@ var webhookSettingsContract = c15.router({
24080
25128
  });
24081
25129
 
24082
25130
  // ../../packages/api-contracts/src/contracts/v1/index.ts
24083
- var c16 = initContract();
24084
- var v1Contract = c16.router(
25131
+ var c20 = initContract();
25132
+ var v1Contract = c20.router(
24085
25133
  {
24086
25134
  admin: adminContract,
24087
25135
  scan: scanContract,
@@ -24095,9 +25143,13 @@ var v1Contract = c16.router(
24095
25143
  knowledgeBase: knowledgeBaseContract,
24096
25144
  knowledgeDocument: knowledgeDocumentContract,
24097
25145
  vulnerability: vulnerabilityContract,
25146
+ vulnerabilityNote: vulnerabilityNoteContract,
24098
25147
  webhookSettings: webhookSettingsContract,
24099
25148
  webApplication: webApplicationContract,
24100
- chatSession: chatSessionContract
25149
+ chatSession: chatSessionContract,
25150
+ pentest: pentestContract,
25151
+ pentestFinding: pentestFindingContract,
25152
+ dependency: dependencyContract
24101
25153
  },
24102
25154
  {
24103
25155
  pathPrefix: "/v1"
@@ -24105,8 +25157,8 @@ var v1Contract = c16.router(
24105
25157
  );
24106
25158
 
24107
25159
  // ../../packages/api-contracts/src/contracts/index.ts
24108
- var c17 = initContract();
24109
- var contract = c17.router({
25160
+ var c21 = initContract();
25161
+ var contract = c21.router({
24110
25162
  v1: v1Contract
24111
25163
  });
24112
25164
 
@@ -24116,8 +25168,8 @@ var GitHubWebhookResponseSchema = external_exports.object({
24116
25168
  });
24117
25169
 
24118
25170
  // ../../packages/api-contracts/src/contracts/webhooks/github.ts
24119
- var c18 = initContract();
24120
- var githubWebhookContract = c18.router(
25171
+ var c22 = initContract();
25172
+ var githubWebhookContract = c22.router(
24121
25173
  {
24122
25174
  handleWebhook: {
24123
25175
  method: "POST",
@@ -24142,8 +25194,8 @@ var HealthResponseSchema = external_exports.object({
24142
25194
  });
24143
25195
 
24144
25196
  // ../../packages/api-contracts/src/contracts/health.ts
24145
- var c19 = initContract();
24146
- var healthContract = c19.router({
25197
+ var c23 = initContract();
25198
+ var healthContract = c23.router({
24147
25199
  getHealth: {
24148
25200
  method: "GET",
24149
25201
  path: "/health",
@@ -24187,12 +25239,13 @@ var ListPrVulnerabilitiesResponseSchema = external_exports.object({
24187
25239
  });
24188
25240
  var UpdatePrVulnerabilityRequestSchema = external_exports.object({
24189
25241
  status: VulnerabilityStatus,
24190
- statusReason: external_exports.string().optional()
25242
+ statusReason: external_exports.string().optional(),
25243
+ dismissReason: DismissReason.optional()
24191
25244
  });
24192
25245
 
24193
25246
  // ../../packages/api-contracts/src/contracts/v1/pr-vulnerability.ts
24194
- var c20 = initContract();
24195
- var prVulnerabilityContract = c20.router(
25247
+ var c24 = initContract();
25248
+ var prVulnerabilityContract = c24.router(
24196
25249
  {
24197
25250
  listPrVulnerabilities: {
24198
25251
  method: "GET",
@@ -24378,7 +25431,267 @@ async function resolveOrganizationIdSafe(client) {
24378
25431
  }
24379
25432
  }
24380
25433
 
25434
+ // src/format.ts
25435
+ var SEVERITY_ORDER = {
25436
+ CRITICAL: 0,
25437
+ HIGH: 1,
25438
+ MEDIUM: 2,
25439
+ LOW: 3,
25440
+ INFORMATIONAL: 4
25441
+ };
25442
+ function formatStatus(status) {
25443
+ return status.toLowerCase().replace("_", " ");
25444
+ }
25445
+
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
+ }
25452
+ function formatDate(date5) {
25453
+ if (!date5) {
25454
+ return "\u2014";
25455
+ }
25456
+ const d = typeof date5 === "string" ? new Date(date5) : date5;
25457
+ return d.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric" });
25458
+ }
25459
+ function formatFindingSeverity(severity) {
25460
+ switch (severity) {
25461
+ case "CRITICAL":
25462
+ return "CRIT";
25463
+ case "HIGH":
25464
+ return "HIGH";
25465
+ case "MEDIUM":
25466
+ return "MED";
25467
+ case "LOW":
25468
+ return "LOW";
25469
+ case "INFORMATIONAL":
25470
+ return "INFO";
25471
+ default:
25472
+ return severity;
25473
+ }
25474
+ }
25475
+ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
25476
+ async function resolvePentestId(organizationId, identifier) {
25477
+ if (UUID_PATTERN.test(identifier)) {
25478
+ return identifier;
25479
+ }
25480
+ const numericMatch = identifier.match(/^(?:PT-)?(\d+)$/i);
25481
+ if (!numericMatch?.[1]) {
25482
+ console.error(
25483
+ `Invalid pentest identifier '${identifier}'. Use a display ID (e.g. PT-3) or UUID.`
25484
+ );
25485
+ process.exit(1);
25486
+ }
25487
+ const displayId = Number.parseInt(numericMatch[1], 10);
25488
+ const result = await authenticatedRequest(
25489
+ (client) => client.pentest.listPentests({
25490
+ params: { organizationId }
25491
+ })
25492
+ );
25493
+ if (result.status === 401) {
25494
+ console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
25495
+ process.exit(1);
25496
+ }
25497
+ if (result.status !== 200) {
25498
+ console.error(`Failed to list pentests (status ${result.status}).`);
25499
+ process.exit(1);
25500
+ }
25501
+ const pentest = result.body.find((p) => p.displayId === displayId);
25502
+ if (!pentest) {
25503
+ console.error(
25504
+ `Pentest with display ID ${displayId} not found.
25505
+ Run \`tracecli pentest list\` to see available pentests.`
25506
+ );
25507
+ process.exit(1);
25508
+ }
25509
+ return pentest.pentestId;
25510
+ }
25511
+ function createListCommand() {
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) => {
25531
+ const organizationId = await resolveOrganizationId();
25532
+ const result = await authenticatedRequest(
25533
+ (client) => client.pentest.listPentests({
25534
+ params: { organizationId }
25535
+ })
25536
+ );
25537
+ if (result.status === 401) {
25538
+ console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
25539
+ process.exit(1);
25540
+ }
25541
+ if (result.status !== 200) {
25542
+ console.error(`Failed to list pentests (status ${result.status}).`);
25543
+ process.exit(1);
25544
+ }
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";
25549
+ if (pentests.length === 0) {
25550
+ if (isJson) {
25551
+ console.log("[]");
25552
+ } else if (isTsv) {
25553
+ console.log("displayId title status startedAt endedAt findingsTotal");
25554
+ } else {
25555
+ console.log("No pentests found.");
25556
+ }
25557
+ return;
25558
+ }
25559
+ if (isJson) {
25560
+ console.log(JSON.stringify(pentests, null, 2));
25561
+ return;
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
+ }
25578
+ console.log(`Found ${pentests.length} pentest${pentests.length === 1 ? "" : "s"}:
25579
+ `);
25580
+ for (const pt of pentests) {
25581
+ const status = formatStatus(pt.status);
25582
+ const started = formatDate(pt.startedAt);
25583
+ const ended = formatDate(pt.endedAt);
25584
+ const dateRange = pt.startedAt ? `${started} \u2013 ${ended}` : "Not started";
25585
+ const findings = pt.findingCounts.total;
25586
+ console.log(` [PT-${pt.displayId}] ${pt.title}`);
25587
+ console.log(` Status: ${status} | Findings: ${findings} | ${dateRange}`);
25588
+ if (pt.description) {
25589
+ console.log(` ${pt.description}`);
25590
+ }
25591
+ console.log("");
25592
+ }
25593
+ });
25594
+ }
25595
+ function createFindingsListCommand() {
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) => {
25604
+ const organizationId = await resolveOrganizationId();
25605
+ const pentestId = await resolvePentestId(organizationId, options.pentest);
25606
+ const result = await authenticatedRequest(
25607
+ (client) => client.pentestFinding.listFindings({
25608
+ params: { organizationId, pentestId }
25609
+ })
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
+ }
25621
+ if (result.status !== 200) {
25622
+ console.error(`Failed to list findings (status ${result.status}).`);
25623
+ process.exit(1);
25624
+ }
25625
+ const findings = result.body;
25626
+ const isJson = options.output === "json";
25627
+ const isTsv = options.output === "tsv";
25628
+ if (findings.length === 0) {
25629
+ if (isJson) {
25630
+ console.log("[]");
25631
+ } else if (isTsv) {
25632
+ console.log("severity status category title cweIds cvssScore");
25633
+ } else {
25634
+ console.log("No findings found for this pentest.");
25635
+ }
25636
+ return;
25637
+ }
25638
+ if (isJson) {
25639
+ console.log(JSON.stringify(findings, null, 2));
25640
+ return;
25641
+ }
25642
+ const sorted = [...findings].sort(
25643
+ (a, b) => (SEVERITY_ORDER[a.severity] ?? 99) - (SEVERITY_ORDER[b.severity] ?? 99)
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
+ `);
25662
+ for (const finding of sorted) {
25663
+ const sev = formatFindingSeverity(finding.severity);
25664
+ const status = formatStatus(finding.status);
25665
+ const cwes = finding.cweIds.length > 0 ? ` | ${finding.cweIds.join(", ")}` : "";
25666
+ const score = finding.cvssScore != null ? ` | CVSS ${finding.cvssScore.toFixed(1)}` : "";
25667
+ console.log(` [${sev}] ${finding.title}`);
25668
+ console.log(` ${finding.category} \xB7 ${status}${cwes}${score}`);
25669
+ if (finding.repositories.length > 0) {
25670
+ for (const repo of finding.repositories) {
25671
+ const location = repo.filePath ? `${repo.repositoryName} \xB7 ${repo.filePath}${repo.startLine != null ? `:${repo.startLine}` : ""}` : repo.repositoryName;
25672
+ console.log(` ${location}`);
25673
+ }
25674
+ }
25675
+ console.log("");
25676
+ }
25677
+ });
25678
+ }
25679
+ function createFindingsCommand() {
25680
+ const findings = new Command("findings").description("Manage pentest findings");
25681
+ findings.addCommand(createFindingsListCommand());
25682
+ return findings;
25683
+ }
25684
+ function createPentestCommand() {
25685
+ const pentest = new Command("pentest").description("Manage pentests");
25686
+ pentest.addCommand(createListCommand());
25687
+ pentest.addCommand(createFindingsCommand());
25688
+ return pentest;
25689
+ }
25690
+
24381
25691
  // src/repo/commands.ts
25692
+ import { chmodSync, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
25693
+ import { tmpdir } from "os";
25694
+ import { join as join3 } from "path";
24382
25695
  function stripAnsi(str) {
24383
25696
  const ESC2 = String.fromCharCode(27);
24384
25697
  const CSI = String.fromCharCode(155);
@@ -24432,7 +25745,7 @@ function validateBranchName(branch) {
24432
25745
  }
24433
25746
  return branch;
24434
25747
  }
24435
- function createListCommand() {
25748
+ function createListCommand2() {
24436
25749
  return new Command("list").description("List repositories in your organization").action(async () => {
24437
25750
  const organizationId = await resolveOrganizationId();
24438
25751
  const result = await authenticatedRequest(
@@ -24558,20 +25871,14 @@ function createCloneCommand() {
24558
25871
  }
24559
25872
  function createRepoCommand() {
24560
25873
  const repo = new Command("repo").description("Manage repositories");
24561
- repo.addCommand(createListCommand());
25874
+ repo.addCommand(createListCommand2());
24562
25875
  repo.addCommand(createCloneCommand());
24563
25876
  return repo;
24564
25877
  }
24565
25878
 
24566
25879
  // src/vulnerabilities/commands.ts
24567
- import { createInterface } from "readline";
24568
- var SEVERITY_ORDER = {
24569
- CRITICAL: 0,
24570
- HIGH: 1,
24571
- MEDIUM: 2,
24572
- LOW: 3
24573
- };
24574
- var DEFAULT_PAGE_SIZE = 25;
25880
+ var DEFAULT_LIMIT2 = 30;
25881
+ var MAX_LIMIT2 = 100;
24575
25882
  async function resolveRepositoryIdAuthenticated(organizationId, repoIdentifier) {
24576
25883
  const result = await authenticatedRequest(
24577
25884
  (client) => client.repository.listRepositories({
@@ -24583,21 +25890,18 @@ async function resolveRepositoryIdAuthenticated(organizationId, repoIdentifier)
24583
25890
  process.exit(1);
24584
25891
  }
24585
25892
  const repos = result.body;
24586
- const match = repos.find((r) => {
24587
- const url2 = r.repositoryUrl;
24588
- if (url2.endsWith(`/${repoIdentifier}`)) {
24589
- return true;
24590
- }
24591
- if (url2.endsWith(`/${repoIdentifier}.git`)) {
24592
- return true;
24593
- }
24594
- if (url2 === repoIdentifier) {
24595
- return true;
25893
+ const isBareNameOnly = !repoIdentifier.includes("/") && !repoIdentifier.startsWith("http");
25894
+ if (!isBareNameOnly) {
25895
+ const match = repos.find((r) => {
25896
+ const url2 = r.repositoryUrl;
25897
+ if (url2.endsWith(`/${repoIdentifier}`)) return true;
25898
+ if (url2.endsWith(`/${repoIdentifier}.git`)) return true;
25899
+ if (url2 === repoIdentifier) return true;
25900
+ return false;
25901
+ });
25902
+ if (match) {
25903
+ return match.repositoryId;
24596
25904
  }
24597
- return false;
24598
- });
24599
- if (match) {
24600
- return match.repositoryId;
24601
25905
  }
24602
25906
  const byName = repos.filter((r) => {
24603
25907
  const segments = r.repositoryUrl.replace(/\.git$/, "").split("/");
@@ -24641,7 +25945,7 @@ function printVulnerabilities(vulnerabilities) {
24641
25945
  );
24642
25946
  for (const vuln of sorted) {
24643
25947
  const sev = formatSeverity(vuln.severity);
24644
- const status = vuln.status.toLowerCase().replace("_", " ");
25948
+ const status = formatStatus(vuln.status);
24645
25949
  const repo = vuln.repositoryName;
24646
25950
  const file2 = vuln.codeSnippet.filePath;
24647
25951
  const line = vuln.codeSnippet.startLine;
@@ -24651,17 +25955,28 @@ function printVulnerabilities(vulnerabilities) {
24651
25955
  console.log("");
24652
25956
  }
24653
25957
  }
24654
- async function promptContinue(displayed, total) {
24655
- const rl = createInterface({ input: process.stdin, output: process.stdout });
24656
- return new Promise((resolve) => {
24657
- rl.question(`Showing ${displayed} of ${total}. Show more? [Y/n] `, (answer) => {
24658
- rl.close();
24659
- const trimmed = answer.trim().toLowerCase();
24660
- resolve(trimmed === "" || trimmed === "y" || trimmed === "yes");
24661
- });
24662
- });
25958
+ function sanitizeTsvField(value) {
25959
+ return value.replace(/[\t\n\r]/g, " ");
24663
25960
  }
24664
- function createListCommand2() {
25961
+ function printVulnerabilitiesTsv(vulnerabilities) {
25962
+ const sorted = [...vulnerabilities].sort(
25963
+ (a, b) => (SEVERITY_ORDER[a.severity] ?? 99) - (SEVERITY_ORDER[b.severity] ?? 99)
25964
+ );
25965
+ console.log("severity status repository file line traceId title");
25966
+ for (const vuln of sorted) {
25967
+ const cols = [
25968
+ vuln.severity,
25969
+ vuln.status,
25970
+ vuln.repositoryName,
25971
+ vuln.codeSnippet.filePath,
25972
+ String(vuln.codeSnippet.startLine),
25973
+ vuln.traceId,
25974
+ vuln.title
25975
+ ].map(sanitizeTsvField);
25976
+ console.log(cols.join(" "));
25977
+ }
25978
+ }
25979
+ function createListCommand3() {
24665
25980
  return new Command("list").description("List vulnerabilities for your organization").option("--repo <repo>", "Filter by repository name or owner/repo").option(
24666
25981
  "--severity <severity>",
24667
25982
  "Filter by severity (CRITICAL, HIGH, MEDIUM, LOW)",
@@ -24670,13 +25985,26 @@ function createListCommand2() {
24670
25985
  "--status <status>",
24671
25986
  "Filter by status (OPEN, IN_PROGRESS, FIXED, IGNORED, FALSE_POSITIVE)",
24672
25987
  (value) => value.toUpperCase()
24673
- ).option("--page-size <size>", "Number of results per page", (v) => {
24674
- const n = Number.parseInt(v, 10);
24675
- if (Number.isNaN(n) || n < 1) {
24676
- throw new Error("--page-size must be a positive integer");
24677
- }
24678
- return Math.min(n, 200);
24679
- }).option("--json", "Output as JSON").action(
25988
+ ).option(
25989
+ "-L, --limit <n>",
25990
+ `Max results to return (default: ${DEFAULT_LIMIT2}, max: ${MAX_LIMIT2})`,
25991
+ (v) => {
25992
+ const n = Number.parseInt(v, 10);
25993
+ if (Number.isNaN(n) || n < 1) {
25994
+ throw new Error("--limit must be a positive integer");
25995
+ }
25996
+ return Math.min(n, MAX_LIMIT2);
25997
+ }
25998
+ ).option("-o, --output <format>", "Output format: table, json, tsv (default: table)", "table").addHelpText(
25999
+ "after",
26000
+ `
26001
+ Examples:
26002
+ tracecli vulnerabilities list
26003
+ tracecli vulnerabilities list --severity CRITICAL --status OPEN
26004
+ tracecli vulnerabilities list --repo securewithtrace/trace --limit 50
26005
+ tracecli vulnerabilities list --output json | jq '.[].title'
26006
+ tracecli vulnerabilities list --output tsv | cut -f1,7`
26007
+ ).action(
24680
26008
  async (options) => {
24681
26009
  const organizationId = await resolveOrganizationId();
24682
26010
  const conditions = [];
@@ -24696,64 +26024,61 @@ function createListCommand2() {
24696
26024
  sortBy: "severity",
24697
26025
  sortOrder: "desc"
24698
26026
  };
24699
- const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;
26027
+ const limit = options.limit ?? DEFAULT_LIMIT2;
26028
+ const isJson = options.output === "json";
26029
+ const isTsv = options.output === "tsv";
26030
+ const collected = [];
24700
26031
  let page = 1;
24701
- let totalDisplayed = 0;
24702
- let total = 0;
24703
- const allJsonVulnerabilities = [];
24704
- while (true) {
26032
+ const pageSize = Math.min(limit, 100);
26033
+ while (collected.length < limit) {
24705
26034
  const result = await authenticatedRequest(
24706
26035
  (client) => client.vulnerability.filterVulnerabilities({
24707
26036
  params: { organizationId },
24708
26037
  body: { ...filterBody, page, pageSize }
24709
26038
  })
24710
26039
  );
26040
+ if (result.status === 401) {
26041
+ console.error("Authentication failed. Run `tracecli auth login` to re-authenticate.");
26042
+ process.exit(1);
26043
+ }
24711
26044
  if (result.status !== 200) {
24712
26045
  console.error(`Failed to list vulnerabilities (status ${result.status}).`);
24713
26046
  process.exit(1);
24714
26047
  }
24715
- total = result.body.total;
24716
26048
  const vulnerabilities = result.body.statusGroups.flatMap((g) => g.vulnerabilities);
24717
- if (page === 1 && vulnerabilities.length === 0) {
24718
- if (options.json) {
24719
- console.log("[]");
24720
- } else {
24721
- console.log("No vulnerabilities found.");
24722
- }
24723
- return;
24724
- }
24725
- if (options.json) {
24726
- allJsonVulnerabilities.push(...vulnerabilities);
24727
- } else {
24728
- if (page === 1) {
24729
- console.log(`Found ${total} vulnerabilit${total === 1 ? "y" : "ies"}:
24730
- `);
24731
- }
24732
- printVulnerabilities(vulnerabilities);
24733
- }
24734
- totalDisplayed += vulnerabilities.length;
24735
- if (totalDisplayed >= total || vulnerabilities.length < pageSize) {
24736
- break;
24737
- }
24738
- if (options.json) {
24739
- page++;
24740
- continue;
24741
- }
24742
- const wantMore = await promptContinue(totalDisplayed, total);
24743
- if (!wantMore) {
26049
+ collected.push(...vulnerabilities);
26050
+ if (vulnerabilities.length < pageSize || collected.length >= result.body.total) {
24744
26051
  break;
24745
26052
  }
24746
26053
  page++;
24747
26054
  }
24748
- if (options.json) {
24749
- console.log(JSON.stringify(allJsonVulnerabilities, null, 2));
26055
+ const items = collected.slice(0, limit);
26056
+ if (items.length === 0) {
26057
+ if (isJson) {
26058
+ console.log("[]");
26059
+ } else if (isTsv) {
26060
+ console.log("severity status repository file line traceId title");
26061
+ } else {
26062
+ console.log("No vulnerabilities found.");
26063
+ }
26064
+ return;
26065
+ }
26066
+ if (isJson) {
26067
+ console.log(JSON.stringify(items, null, 2));
26068
+ } else if (isTsv) {
26069
+ printVulnerabilitiesTsv(items);
26070
+ } else {
26071
+ const total = collected.length;
26072
+ console.log(`Found ${total} vulnerabilit${total === 1 ? "y" : "ies"}:
26073
+ `);
26074
+ printVulnerabilities(items);
24750
26075
  }
24751
26076
  }
24752
26077
  );
24753
26078
  }
24754
26079
  function createVulnerabilitiesCommand() {
24755
26080
  const vulnerabilities = new Command("vulnerabilities").description("Manage vulnerabilities");
24756
- vulnerabilities.addCommand(createListCommand2());
26081
+ vulnerabilities.addCommand(createListCommand3());
24757
26082
  return vulnerabilities;
24758
26083
  }
24759
26084
 
@@ -24767,5 +26092,6 @@ program2.action(() => {
24767
26092
  program2.addCommand(createAuthCommand());
24768
26093
  program2.addCommand(createRepoCommand());
24769
26094
  program2.addCommand(createVulnerabilitiesCommand());
26095
+ program2.addCommand(createPentestCommand());
24770
26096
  program2.addCommand(createCompletionCommand(program2));
24771
26097
  program2.parse();