@zksecurity/zkao-sdk 0.14.0-next.9 → 0.15.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -216,6 +216,92 @@ interface paths {
216
216
  patch?: never;
217
217
  trace?: never;
218
218
  };
219
+ "/projects/{projectId}/reports": {
220
+ parameters: {
221
+ query?: never;
222
+ header?: never;
223
+ path?: never;
224
+ cookie?: never;
225
+ };
226
+ /**
227
+ * List incoming reports
228
+ * @description Requires scope: `read`. Vulnerability reports the programme has received, newest first. Optionally filter by `status`.
229
+ *
230
+ * `publicId` is what `investigateReport` takes. `intakeState` says whether the report has been read and split into claims yet: an investigation waits for `COMPLETE`, so a `PENDING` or `RUNNING` report is one to come back to rather than one to retry.
231
+ */
232
+ get: operations["listReports"];
233
+ put?: never;
234
+ post?: never;
235
+ delete?: never;
236
+ options?: never;
237
+ head?: never;
238
+ patch?: never;
239
+ trace?: never;
240
+ };
241
+ "/projects/{projectId}/reports/{publicId}/investigate": {
242
+ parameters: {
243
+ query?: never;
244
+ header?: never;
245
+ path?: never;
246
+ cookie?: never;
247
+ };
248
+ get?: never;
249
+ put?: never;
250
+ /**
251
+ * Investigate an incoming report against the code
252
+ * @description Requires scope: `scans:launch`. Runs the triage flow over the report's claims: each is checked against the repository, deduplicated against the findings already confirmed there, and given a proof of concept where one can be written. Returns immediately with the scan doing the work; poll `/projects/{projectId}/scans/{scanId}` and then read its findings.
253
+ *
254
+ * Idempotent. A report already under investigation returns the existing scan with `claimsQueued: null`, so a retry costs nothing.
255
+ */
256
+ post: operations["investigateReport"];
257
+ delete?: never;
258
+ options?: never;
259
+ head?: never;
260
+ patch?: never;
261
+ trace?: never;
262
+ };
263
+ "/projects/{projectId}/advisories": {
264
+ parameters: {
265
+ query?: never;
266
+ header?: never;
267
+ path?: never;
268
+ cookie?: never;
269
+ };
270
+ /**
271
+ * List advisories
272
+ * @description Requires scope: `read`. The project's coordinated-disclosure advisories, newest first. Optionally filter by `status`.
273
+ */
274
+ get: operations["listAdvisories"];
275
+ put?: never;
276
+ post?: never;
277
+ delete?: never;
278
+ options?: never;
279
+ head?: never;
280
+ patch?: never;
281
+ trace?: never;
282
+ };
283
+ "/projects/{projectId}/advisories/{publicId}": {
284
+ parameters: {
285
+ query?: never;
286
+ header?: never;
287
+ path?: never;
288
+ cookie?: never;
289
+ };
290
+ /**
291
+ * Get an advisory
292
+ * @description Requires scope: `read`. The advisory, the versions it affects, and the notices planned for it.
293
+ *
294
+ * A notice the plan is holding back carries `blockedReason`. The commonest one is that no affected range names a fixed version, which only the people who shipped the release can supply; record it in the app and the notice becomes schedulable.
295
+ */
296
+ get: operations["getAdvisory"];
297
+ put?: never;
298
+ post?: never;
299
+ delete?: never;
300
+ options?: never;
301
+ head?: never;
302
+ patch?: never;
303
+ trace?: never;
304
+ };
219
305
  "/projects/{projectId}/findings": {
220
306
  parameters: {
221
307
  query?: never;
@@ -692,6 +778,105 @@ interface components {
692
778
  limit: number;
693
779
  total: number;
694
780
  };
781
+ Report: {
782
+ /** @description The identifier `investigateReport` takes. */
783
+ publicId: string;
784
+ title: string;
785
+ /** @description How it arrived. Today always GitHub private vulnerability reporting. */
786
+ source: string;
787
+ /** @description What the reporter claimed, which is not an assessment. */
788
+ claimedSeverity?: components["schemas"]["Severity"] | null;
789
+ /** @enum {string} */
790
+ status: "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
791
+ /**
792
+ * @description Whether the report has been read and split into claims. An investigation waits for COMPLETE.
793
+ * @enum {string}
794
+ */
795
+ intakeState: "PENDING" | "RUNNING" | "REVIEW" | "COMPLETE" | "FAILED";
796
+ /**
797
+ * @description How the investigation is going, or null if none has run.
798
+ * @enum {string|null}
799
+ */
800
+ evaluationState?: "QUEUED" | "RUNNING" | "COMPLETE" | "FAILED" | null;
801
+ reporterName?: string | null;
802
+ reporterGithubLogin?: string | null;
803
+ /** @description The GitHub advisory it arrived as. */
804
+ githubUrl?: string | null;
805
+ /** Format: date-time */
806
+ acknowledgedAt?: string | null;
807
+ /** Format: date-time */
808
+ createdAt: string;
809
+ };
810
+ PaginatedReports: {
811
+ items: components["schemas"]["Report"][];
812
+ page: number;
813
+ limit: number;
814
+ total: number;
815
+ };
816
+ Advisory: {
817
+ /** @description Readable identifier, e.g. `ADVISORY-ADV-2026-0045`. */
818
+ publicId: string;
819
+ title: string;
820
+ /** @enum {string} */
821
+ severity: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" | "INFO";
822
+ /** @enum {string} */
823
+ status: "DRAFT" | "SCHEDULED" | "UNDER_EMBARGO" | "PUBLISHED" | "WITHDRAWN";
824
+ /**
825
+ * Format: date-time
826
+ * @description When the embargo lifts. Null until a date is set.
827
+ */
828
+ disclosureAt?: string | null;
829
+ /** Format: date-time */
830
+ publishedAt?: string | null;
831
+ cveId?: string | null;
832
+ /** @description The GitHub advisory, once one has been filed. */
833
+ ghsaId?: string | null;
834
+ ghsaUrl?: string | null;
835
+ /** @description What GitHub reports. A created entry is a DRAFT, which is private and reaches no scanner; only a published one is public. */
836
+ ghsaState: string;
837
+ /** Format: date-time */
838
+ createdAt: string;
839
+ };
840
+ AdvisoryAffected: {
841
+ id: string;
842
+ repository: {
843
+ owner: string;
844
+ name: string;
845
+ };
846
+ /** @description First version carrying the defect. */
847
+ introducedIn: string;
848
+ /** @description Version that closes the range. Null while no patch exists, which is what holds a patch notice back. */
849
+ fixedIn: string | null;
850
+ };
851
+ AdvisoryNotice: {
852
+ label: string;
853
+ /** @description Days relative to disclosure. Negative is before it, 0 is the day itself. */
854
+ offsetDays: number;
855
+ /** Format: date-time */
856
+ scheduledFor: string;
857
+ /** @enum {string} */
858
+ status: "DRAFT" | "SCHEDULED" | "BLOCKED" | "SENDING" | "SENT" | "CANCELLED";
859
+ /** @description Why the plan is holding this notice back, if it is. */
860
+ blockedReason: string | null;
861
+ /** Format: date-time */
862
+ sentAt: string | null;
863
+ /** @description Contacts written to, as recorded when it went. */
864
+ recipientCount: number;
865
+ };
866
+ AdvisoryDetail: components["schemas"]["Advisory"] & {
867
+ summary: string;
868
+ description: string;
869
+ impact: string;
870
+ cwe?: string | null;
871
+ affected: components["schemas"]["AdvisoryAffected"][];
872
+ notices: components["schemas"]["AdvisoryNotice"][];
873
+ };
874
+ PaginatedAdvisories: {
875
+ items: components["schemas"]["Advisory"][];
876
+ page: number;
877
+ limit: number;
878
+ total: number;
879
+ };
695
880
  PaginatedFindings: {
696
881
  items: components["schemas"]["Finding"][];
697
882
  page: number;
@@ -809,6 +994,13 @@ interface components {
809
994
  /** @description Number of in-flight jobs signalled to stop. */
810
995
  cancelledJobs: number;
811
996
  };
997
+ InvestigateReportResult: {
998
+ publicId: string;
999
+ /** @description The scan triaging this report's claims. */
1000
+ scanId: string;
1001
+ /** @description Claims queued for triage, or null when an investigation was already running and this call started nothing. */
1002
+ claimsQueued: number | null;
1003
+ };
812
1004
  /** @description Optionally attach or reuse a note alongside a resolution change. */
813
1005
  ChangeNote: {
814
1006
  /** @description Create a new note with this body. */
@@ -1276,6 +1468,127 @@ interface operations {
1276
1468
  429: components["responses"]["RateLimited"];
1277
1469
  };
1278
1470
  };
1471
+ listReports: {
1472
+ parameters: {
1473
+ query?: {
1474
+ page?: components["parameters"]["Page"];
1475
+ limit?: components["parameters"]["Limit"];
1476
+ /** @description Only reports in this triage status. */
1477
+ status?: "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
1478
+ };
1479
+ header?: never;
1480
+ path: {
1481
+ projectId: components["parameters"]["ProjectId"];
1482
+ };
1483
+ cookie?: never;
1484
+ };
1485
+ requestBody?: never;
1486
+ responses: {
1487
+ /** @description OK */
1488
+ 200: {
1489
+ headers: {
1490
+ [name: string]: unknown;
1491
+ };
1492
+ content: {
1493
+ "application/json": components["schemas"]["PaginatedReports"];
1494
+ };
1495
+ };
1496
+ 400: components["responses"]["BadRequest"];
1497
+ 401: components["responses"]["Unauthorized"];
1498
+ 403: components["responses"]["Forbidden"];
1499
+ 404: components["responses"]["NotFound"];
1500
+ };
1501
+ };
1502
+ investigateReport: {
1503
+ parameters: {
1504
+ query?: never;
1505
+ header?: never;
1506
+ path: {
1507
+ projectId: components["parameters"]["ProjectId"];
1508
+ /** @description The report's public identifier. */
1509
+ publicId: string;
1510
+ };
1511
+ cookie?: never;
1512
+ };
1513
+ requestBody?: never;
1514
+ responses: {
1515
+ /** @description OK */
1516
+ 200: {
1517
+ headers: {
1518
+ [name: string]: unknown;
1519
+ };
1520
+ content: {
1521
+ "application/json": components["schemas"]["InvestigateReportResult"];
1522
+ };
1523
+ };
1524
+ 401: components["responses"]["Unauthorized"];
1525
+ 402: components["responses"]["InsufficientCredits"];
1526
+ 403: components["responses"]["Forbidden"];
1527
+ 404: components["responses"]["NotFound"];
1528
+ 409: components["responses"]["Conflict"];
1529
+ 429: components["responses"]["RateLimited"];
1530
+ };
1531
+ };
1532
+ listAdvisories: {
1533
+ parameters: {
1534
+ query?: {
1535
+ page?: components["parameters"]["Page"];
1536
+ limit?: components["parameters"]["Limit"];
1537
+ /** @description Only advisories in this status. */
1538
+ status?: "DRAFT" | "SCHEDULED" | "UNDER_EMBARGO" | "PUBLISHED" | "WITHDRAWN";
1539
+ };
1540
+ header?: never;
1541
+ path: {
1542
+ projectId: components["parameters"]["ProjectId"];
1543
+ };
1544
+ cookie?: never;
1545
+ };
1546
+ requestBody?: never;
1547
+ responses: {
1548
+ /** @description OK */
1549
+ 200: {
1550
+ headers: {
1551
+ [name: string]: unknown;
1552
+ };
1553
+ content: {
1554
+ "application/json": components["schemas"]["PaginatedAdvisories"];
1555
+ };
1556
+ };
1557
+ 400: components["responses"]["BadRequest"];
1558
+ 401: components["responses"]["Unauthorized"];
1559
+ 403: components["responses"]["Forbidden"];
1560
+ 404: components["responses"]["NotFound"];
1561
+ };
1562
+ };
1563
+ getAdvisory: {
1564
+ parameters: {
1565
+ query?: never;
1566
+ header?: never;
1567
+ path: {
1568
+ projectId: components["parameters"]["ProjectId"];
1569
+ /** @description The advisory's readable identifier. */
1570
+ publicId: string;
1571
+ };
1572
+ cookie?: never;
1573
+ };
1574
+ requestBody?: never;
1575
+ responses: {
1576
+ /** @description OK */
1577
+ 200: {
1578
+ headers: {
1579
+ [name: string]: unknown;
1580
+ };
1581
+ content: {
1582
+ "application/json": {
1583
+ advisory: components["schemas"]["AdvisoryDetail"];
1584
+ };
1585
+ };
1586
+ };
1587
+ 401: components["responses"]["Unauthorized"];
1588
+ 403: components["responses"]["Forbidden"];
1589
+ 404: components["responses"]["NotFound"];
1590
+ };
1591
+ };
1279
1592
  listFindings: {
1280
1593
  parameters: {
1281
1594
  query?: {
@@ -1720,6 +2033,14 @@ type BillingUsage = Schemas["BillingUsage"];
1720
2033
  type UsageEvent = Schemas["UsageEvent"];
1721
2034
  type UsageEventType = Schemas["UsageEventType"];
1722
2035
  type BillingSummary = Schemas["BillingSummary"];
2036
+ type InvestigateReportResult = Schemas["InvestigateReportResult"];
2037
+ type Report = Schemas["Report"];
2038
+ /** The triage statuses a report moves through. */
2039
+ type ReportStatus = "NEW" | "TRIAGING" | "NEEDS_INFO" | "ACCEPTED" | "DUPLICATE" | "REJECTED";
2040
+ type Advisory = Schemas["Advisory"];
2041
+ type AdvisoryDetail = Schemas["AdvisoryDetail"];
2042
+ /** The statuses an advisory moves through. */
2043
+ type AdvisoryStatus = "DRAFT" | "SCHEDULED" | "UNDER_EMBARGO" | "PUBLISHED" | "WITHDRAWN";
1723
2044
  type UsageMonthSummary = Schemas["UsageMonthSummary"];
1724
2045
  type Paginated<T> = {
1725
2046
  items: T[];
@@ -1892,6 +2213,47 @@ declare class ZkaoClient {
1892
2213
  * scope, which only a zkao site admin can grant; any other token gets 404.
1893
2214
  */
1894
2215
  createManualAudit(body: ManualAuditRequest): Promise<ManualAuditResult>;
2216
+ /**
2217
+ * The project's coordinated-disclosure advisories, newest first.
2218
+ */
2219
+ listAdvisories(opts?: {
2220
+ page?: number;
2221
+ limit?: number;
2222
+ status?: AdvisoryStatus;
2223
+ }): Promise<Paginated<Advisory>>;
2224
+ /**
2225
+ * One advisory, the versions it affects, and the notices planned for it.
2226
+ *
2227
+ * A notice the plan is holding back carries `blockedReason`. The commonest
2228
+ * one is that no affected range names a fixed version, which only the people
2229
+ * who shipped the release can supply.
2230
+ */
2231
+ getAdvisory(publicId: string): Promise<AdvisoryDetail>;
2232
+ /**
2233
+ * Reports the programme has received, newest first.
2234
+ *
2235
+ * `publicId` is what {@link investigateReport} takes. `intakeState` says
2236
+ * whether a report has been read and split into claims yet: an
2237
+ * investigation waits for `COMPLETE`.
2238
+ */
2239
+ listReports(opts?: {
2240
+ page?: number;
2241
+ limit?: number;
2242
+ status?: ReportStatus;
2243
+ }): Promise<Paginated<Report>>;
2244
+ /**
2245
+ * Check an incoming vulnerability report against the code.
2246
+ *
2247
+ * Requires the `scans:launch` scope. The report's claims are each checked
2248
+ * against the repository, deduplicated against the findings already
2249
+ * confirmed there, and given a proof of concept where one can be written.
2250
+ * Returns at once with the scan doing the work: poll {@link getScan} and
2251
+ * then read its findings.
2252
+ *
2253
+ * Idempotent. A report already under investigation comes back with the
2254
+ * existing scan and `claimsQueued: null`, so a retry costs nothing.
2255
+ */
2256
+ investigateReport(publicId: string): Promise<InvestigateReportResult>;
1895
2257
  listFindings(opts?: {
1896
2258
  page?: number;
1897
2259
  limit?: number;
package/dist/index.js CHANGED
@@ -376,6 +376,69 @@ var ZkaoClient = class {
376
376
  async createManualAudit(body) {
377
377
  return this.postUntyped("/manual-audits", body);
378
378
  }
379
+ // --- Advisories ---------------------------------------------------------
380
+ /**
381
+ * The project's coordinated-disclosure advisories, newest first.
382
+ */
383
+ async listAdvisories(opts = {}) {
384
+ const res = await this.http.GET("/projects/{projectId}/advisories", {
385
+ params: {
386
+ path: this.path,
387
+ query: { page: opts.page, limit: opts.limit, status: opts.status }
388
+ }
389
+ });
390
+ return unwrap(res);
391
+ }
392
+ /**
393
+ * One advisory, the versions it affects, and the notices planned for it.
394
+ *
395
+ * A notice the plan is holding back carries `blockedReason`. The commonest
396
+ * one is that no affected range names a fixed version, which only the people
397
+ * who shipped the release can supply.
398
+ */
399
+ async getAdvisory(publicId) {
400
+ const res = await this.http.GET(
401
+ "/projects/{projectId}/advisories/{publicId}",
402
+ { params: { path: { ...this.path, publicId } } }
403
+ );
404
+ return unwrap(res).advisory;
405
+ }
406
+ // --- Incoming reports ---------------------------------------------------
407
+ /**
408
+ * Reports the programme has received, newest first.
409
+ *
410
+ * `publicId` is what {@link investigateReport} takes. `intakeState` says
411
+ * whether a report has been read and split into claims yet: an
412
+ * investigation waits for `COMPLETE`.
413
+ */
414
+ async listReports(opts = {}) {
415
+ const res = await this.http.GET("/projects/{projectId}/reports", {
416
+ params: {
417
+ path: this.path,
418
+ query: { page: opts.page, limit: opts.limit, status: opts.status }
419
+ }
420
+ });
421
+ return unwrap(res);
422
+ }
423
+ /**
424
+ * Check an incoming vulnerability report against the code.
425
+ *
426
+ * Requires the `scans:launch` scope. The report's claims are each checked
427
+ * against the repository, deduplicated against the findings already
428
+ * confirmed there, and given a proof of concept where one can be written.
429
+ * Returns at once with the scan doing the work: poll {@link getScan} and
430
+ * then read its findings.
431
+ *
432
+ * Idempotent. A report already under investigation comes back with the
433
+ * existing scan and `claimsQueued: null`, so a retry costs nothing.
434
+ */
435
+ async investigateReport(publicId) {
436
+ const res = await this.http.POST(
437
+ "/projects/{projectId}/reports/{publicId}/investigate",
438
+ { params: { path: { ...this.path, publicId } } }
439
+ );
440
+ return unwrap(res);
441
+ }
379
442
  // --- Findings -----------------------------------------------------------
380
443
  async listFindings(opts = {}) {
381
444
  const res = await this.http.GET("/projects/{projectId}/findings", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zksecurity/zkao-sdk",
3
- "version": "0.14.0-next.9",
3
+ "version": "0.15.0-next.10",
4
4
  "description": "TypeScript SDK for the zkao Project API",
5
5
  "license": "MIT",
6
6
  "author": "zkSecurity",