@thinkai/tai-api-contract 2.126.0 → 2.128.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.
@@ -1,7 +1,7 @@
1
1
  openapi: 3.0.3
2
2
  info:
3
3
  title: ThinkAI API
4
- version: 2.126.0
4
+ version: 2.128.0
5
5
  description: >
6
6
  Contract surface for the AI Driven SDLC backend used by ThinkAI.
7
7
  Workspace-scoped routes use `/workspaces/{workspaceId}/...`.
@@ -86,6 +86,12 @@ tags:
86
86
  (LOC, cyclomatic complexity, duplication), hotspots, and playbook-threshold
87
87
  findings collected during readiness scans. Every metric carries
88
88
  `measured | derived | estimated | unavailable` provenance.
89
+ - name: TestPyramidInsights
90
+ description: >
91
+ Test pyramid assessment (`/insights/test-pyramid`) — workspace and per-repo
92
+ classified test-file inventory (unit, integration, acceptance/BDD, contract, E2E)
93
+ with count-based presence and advisory 70/20/10 shape. Distinct from Agentic
94
+ Foundation readiness `/readiness/test-pyramid*` (signal-inclusive presence).
89
95
 
90
96
  paths:
91
97
  /admin/users/{userId}:
@@ -3831,6 +3837,89 @@ paths:
3831
3837
  schema:
3832
3838
  $ref: "#/components/schemas/ErrorMessageDto"
3833
3839
 
3840
+ /workspaces/{workspaceId}/insights/test-pyramid/summary:
3841
+ get:
3842
+ tags: [TestPyramidInsights]
3843
+ summary: Test pyramid assessment — workspace summary
3844
+ operationId: getInsightsTestPyramidSummary
3845
+ description: >
3846
+ Org-level Test pyramid assessment for `/insights/test-pyramid`. Aggregates each
3847
+ active repo's **latest** readiness-scan test-pyramid snapshot and the immediately
3848
+ previous succeeded/partial_failed/failed point when present (`limitPerRepo: 2`).
3849
+ Layer **presence is count-based** (`fileCount > 0`); CI/dependency-only AF
3850
+ `present` flags are ignored. Shape uses fixed advisory targets (base ~70% unit,
3851
+ middle ~20% integration+contract+acceptance/BDD, top ~10% E2E) and returns
3852
+ `insufficient_data` when total classified test files < 10. Also returns
3853
+ maturity trend, coverage overlay, confidence, applicability, E2E-cross/hotspot
3854
+ risk, and workspace-only `ciQuality` from the latest org dashboard snapshot.
3855
+ Does not change Agentic Foundation `/readiness/test-pyramid*` responses.
3856
+ parameters:
3857
+ - $ref: "#/components/parameters/WorkspaceId"
3858
+ responses:
3859
+ "200":
3860
+ description: Test pyramid assessment workspace summary
3861
+ content:
3862
+ application/json:
3863
+ schema:
3864
+ $ref: "#/components/schemas/InsightsTestPyramidSummaryDto"
3865
+ "401":
3866
+ $ref: "#/components/responses/Unauthorized"
3867
+ "403":
3868
+ $ref: "#/components/responses/Forbidden"
3869
+ "404":
3870
+ description: Workspace does not exist or malformed workspaceId
3871
+ "501":
3872
+ description: Test pyramid history not supported by store
3873
+ content:
3874
+ application/json:
3875
+ schema:
3876
+ $ref: "#/components/schemas/ErrorMessageDto"
3877
+
3878
+ /workspaces/{workspaceId}/insights/test-pyramid/repos:
3879
+ get:
3880
+ tags: [TestPyramidInsights]
3881
+ summary: Test pyramid assessment — per-repo list (paginated)
3882
+ operationId: listInsightsTestPyramidRepos
3883
+ description: >
3884
+ Page of repos with latest classified test-file counts, count-based presence,
3885
+ presence maturity, shape, trend vs the previous pyramid point, coverage
3886
+ overlay, confidence/evidence, layer applicability, and risk signals
3887
+ (`e2eCrossRepoCandidate`, `hotspotCount`). Use `gapsByLayer` on the summary
3888
+ endpoint (or filter this list via layerPresent) to answer “who lacks layer X?”.
3889
+ No v1 repo-detail Insights route — link repo names to AF readiness inventory.
3890
+ parameters:
3891
+ - $ref: "#/components/parameters/WorkspaceId"
3892
+ - $ref: "#/components/parameters/PaginationLimit"
3893
+ - $ref: "#/components/parameters/PaginationOffset"
3894
+ - $ref: "#/components/parameters/InsightsTestPyramidRepoSort"
3895
+ - $ref: "#/components/parameters/PaginationOrder"
3896
+ - $ref: "#/components/parameters/InsightsTestPyramidRepoSearch"
3897
+ responses:
3898
+ "200":
3899
+ description: Paginated test pyramid assessment repo rows
3900
+ content:
3901
+ application/json:
3902
+ schema:
3903
+ $ref: "#/components/schemas/InsightsTestPyramidRepoListDto"
3904
+ "400":
3905
+ description: Invalid pagination or sort query
3906
+ content:
3907
+ application/json:
3908
+ schema:
3909
+ $ref: "#/components/schemas/ErrorMessageDto"
3910
+ "401":
3911
+ $ref: "#/components/responses/Unauthorized"
3912
+ "403":
3913
+ $ref: "#/components/responses/Forbidden"
3914
+ "404":
3915
+ description: Workspace does not exist or malformed workspaceId
3916
+ "501":
3917
+ description: Test pyramid history not supported by store
3918
+ content:
3919
+ application/json:
3920
+ schema:
3921
+ $ref: "#/components/schemas/ErrorMessageDto"
3922
+
3834
3923
  /workspaces/{workspaceId}/integrations/ai-tool/{provider}/members:
3835
3924
  get:
3836
3925
  tags: [Workspace]
@@ -10051,6 +10140,23 @@ components:
10051
10140
  description: Case-insensitive substring filter on repo name / provider slug.
10052
10141
  schema:
10053
10142
  type: string
10143
+ InsightsTestPyramidRepoSort:
10144
+ name: sort
10145
+ in: query
10146
+ required: false
10147
+ description: Allowlisted Test pyramid assessment repo sort field.
10148
+ schema:
10149
+ type: string
10150
+ enum: [repoName, totalClassifiedFiles, scannedAt, maturity]
10151
+ default: repoName
10152
+ InsightsTestPyramidRepoSearch:
10153
+ name: search
10154
+ in: query
10155
+ required: false
10156
+ description: Case-insensitive substring filter on repository name.
10157
+ schema:
10158
+ type: string
10159
+ maxLength: 256
10054
10160
  ReadinessRepoSearch:
10055
10161
  name: search
10056
10162
  in: query
@@ -21508,3 +21614,362 @@ components:
21508
21614
  description: Org top-10 complexity hotspots by `ccMax` (current per-repo snapshots).
21509
21615
  sonar:
21510
21616
  $ref: "#/components/schemas/CodeInsightsSonarDto"
21617
+
21618
+ InsightsTestPyramidMaturityDto:
21619
+ type: string
21620
+ enum: [missing, emerging, established, mature]
21621
+ description: >
21622
+ Presence maturity (model A) using count-based layer presence
21623
+ (`fileCount > 0`), not AF signal-inclusive `present`.
21624
+
21625
+ InsightsTestPyramidShapeLabelDto:
21626
+ type: string
21627
+ enum: [insufficient_data, base_heavy, balanced, top_heavy, middle_heavy]
21628
+ description: >
21629
+ Advisory shape label vs fixed 70/20/10. `insufficient_data` when total
21630
+ classified test files < 10 (band percents are null).
21631
+
21632
+ InsightsTestPyramidShapeDto:
21633
+ type: object
21634
+ required: [label, totalClassifiedFiles, basePercent, middlePercent, topPercent, targets]
21635
+ properties:
21636
+ label:
21637
+ $ref: "#/components/schemas/InsightsTestPyramidShapeLabelDto"
21638
+ totalClassifiedFiles:
21639
+ type: integer
21640
+ minimum: 0
21641
+ description: Sum of classified test **files** across the five layers (not test cases).
21642
+ basePercent:
21643
+ type: number
21644
+ nullable: true
21645
+ description: Share of classified files in unit (base). Null when insufficient_data.
21646
+ middlePercent:
21647
+ type: number
21648
+ nullable: true
21649
+ description: >
21650
+ Share in integration + contract + acceptance_bdd (middle). Null when
21651
+ insufficient_data.
21652
+ topPercent:
21653
+ type: number
21654
+ nullable: true
21655
+ description: Share in e2e (top). Null when insufficient_data.
21656
+ targets:
21657
+ type: object
21658
+ required: [basePercent, middlePercent, topPercent]
21659
+ properties:
21660
+ basePercent: { type: number, enum: [70] }
21661
+ middlePercent: { type: number, enum: [20] }
21662
+ topPercent: { type: number, enum: [10] }
21663
+
21664
+ InsightsTestPyramidLayerCountsDto:
21665
+ type: object
21666
+ required: [unit, integration, acceptance_bdd, contract, e2e]
21667
+ properties:
21668
+ unit: { type: integer, minimum: 0 }
21669
+ integration: { type: integer, minimum: 0 }
21670
+ acceptance_bdd: { type: integer, minimum: 0 }
21671
+ contract: { type: integer, minimum: 0 }
21672
+ e2e: { type: integer, minimum: 0 }
21673
+
21674
+ InsightsTestPyramidLayerPresentDto:
21675
+ type: object
21676
+ required: [unit, integration, acceptance_bdd, contract, e2e]
21677
+ properties:
21678
+ unit: { type: boolean }
21679
+ integration: { type: boolean }
21680
+ acceptance_bdd: { type: boolean }
21681
+ contract: { type: boolean }
21682
+ e2e: { type: boolean }
21683
+
21684
+ InsightsTestPyramidLayerPresenceDto:
21685
+ type: object
21686
+ required: [presentRepos, applicableRepos, percent, missingRepoIds, missingRepoNames]
21687
+ properties:
21688
+ presentRepos: { type: integer, minimum: 0 }
21689
+ applicableRepos: { type: integer, minimum: 0 }
21690
+ percent:
21691
+ type: integer
21692
+ nullable: true
21693
+ minimum: 0
21694
+ maximum: 100
21695
+ missingRepoIds:
21696
+ type: array
21697
+ items: { type: string, format: uuid }
21698
+ missingRepoNames:
21699
+ type: array
21700
+ items: { type: string }
21701
+
21702
+ InsightsTestPyramidGapRepoDto:
21703
+ type: object
21704
+ required: [repoId, repoName]
21705
+ properties:
21706
+ repoId: { type: string, format: uuid }
21707
+ repoName: { type: string }
21708
+
21709
+ InsightsTestPyramidGapsByLayerDto:
21710
+ type: object
21711
+ required: [unit, integration, acceptance_bdd, contract, e2e]
21712
+ properties:
21713
+ unit:
21714
+ type: array
21715
+ items: { $ref: "#/components/schemas/InsightsTestPyramidGapRepoDto" }
21716
+ integration:
21717
+ type: array
21718
+ items: { $ref: "#/components/schemas/InsightsTestPyramidGapRepoDto" }
21719
+ acceptance_bdd:
21720
+ type: array
21721
+ items: { $ref: "#/components/schemas/InsightsTestPyramidGapRepoDto" }
21722
+ contract:
21723
+ type: array
21724
+ items: { $ref: "#/components/schemas/InsightsTestPyramidGapRepoDto" }
21725
+ e2e:
21726
+ type: array
21727
+ items: { $ref: "#/components/schemas/InsightsTestPyramidGapRepoDto" }
21728
+
21729
+ InsightsTestPyramidMaturityCountsDto:
21730
+ type: object
21731
+ required: [missing, emerging, established, mature]
21732
+ properties:
21733
+ missing: { type: integer, minimum: 0 }
21734
+ emerging: { type: integer, minimum: 0 }
21735
+ established: { type: integer, minimum: 0 }
21736
+ mature: { type: integer, minimum: 0 }
21737
+
21738
+ InsightsTestPyramidLayerPresenceMapDto:
21739
+ type: object
21740
+ required: [unit, integration, acceptance_bdd, contract, e2e]
21741
+ properties:
21742
+ unit: { $ref: "#/components/schemas/InsightsTestPyramidLayerPresenceDto" }
21743
+ integration: { $ref: "#/components/schemas/InsightsTestPyramidLayerPresenceDto" }
21744
+ acceptance_bdd: { $ref: "#/components/schemas/InsightsTestPyramidLayerPresenceDto" }
21745
+ contract: { $ref: "#/components/schemas/InsightsTestPyramidLayerPresenceDto" }
21746
+ e2e: { $ref: "#/components/schemas/InsightsTestPyramidLayerPresenceDto" }
21747
+
21748
+ InsightsTestPyramidMaturityDeltaDto:
21749
+ type: string
21750
+ enum: [up, down, unchanged, none]
21751
+ description: >
21752
+ Insights maturity rank change vs the immediately previous pyramid point
21753
+ (missing 0, emerging 1, established 2, mature 3). `none` when the repo
21754
+ has no previous succeeded/partial_failed/failed point.
21755
+
21756
+ InsightsTestPyramidConfidenceDto:
21757
+ type: string
21758
+ enum: [high, medium, low]
21759
+
21760
+ InsightsTestPyramidLayerConfidenceDto:
21761
+ type: object
21762
+ required: [unit, integration, acceptance_bdd, contract, e2e]
21763
+ properties:
21764
+ unit: { $ref: "#/components/schemas/InsightsTestPyramidConfidenceDto" }
21765
+ integration: { $ref: "#/components/schemas/InsightsTestPyramidConfidenceDto" }
21766
+ acceptance_bdd: { $ref: "#/components/schemas/InsightsTestPyramidConfidenceDto" }
21767
+ contract: { $ref: "#/components/schemas/InsightsTestPyramidConfidenceDto" }
21768
+ e2e: { $ref: "#/components/schemas/InsightsTestPyramidConfidenceDto" }
21769
+
21770
+ InsightsTestPyramidCoverageRollupDto:
21771
+ type: object
21772
+ required: [reposWithCoverage, medianLinePercent]
21773
+ properties:
21774
+ reposWithCoverage:
21775
+ type: integer
21776
+ minimum: 0
21777
+ description: Repos whose overlaid `lineCoverage` is non-null.
21778
+ medianLinePercent:
21779
+ type: number
21780
+ nullable: true
21781
+ minimum: 0
21782
+ maximum: 100
21783
+ description: >
21784
+ Median of repo `linePercent` among repos that have coverage. Null when
21785
+ `reposWithCoverage` is 0.
21786
+
21787
+ InsightsTestPyramidCiQualityDto:
21788
+ type: object
21789
+ nullable: true
21790
+ required: [ciFailureRatePercent, bucketEnd]
21791
+ properties:
21792
+ ciFailureRatePercent:
21793
+ type: number
21794
+ minimum: 0
21795
+ maximum: 100
21796
+ description: >
21797
+ Latest org dashboard `quality.ciFailureRatePercent`, falling back to
21798
+ `quality.ciBuildFailRatePercent`.
21799
+ ciFlakinessPercent:
21800
+ type: number
21801
+ minimum: 0
21802
+ maximum: 100
21803
+ description: Included only when `quality.ciFlakinessPercent` is a finite number.
21804
+ bucketEnd:
21805
+ type: string
21806
+ description: Dashboard metrics bucket end for the org snapshot.
21807
+
21808
+ InsightsTestPyramidSummaryDto:
21809
+ type: object
21810
+ required:
21811
+ - workspaceId
21812
+ - generatedAt
21813
+ - reposWithPyramid
21814
+ - reposFromDegradedRuns
21815
+ - totalClassifiedFiles
21816
+ - shape
21817
+ - layerPresence
21818
+ - maturityCounts
21819
+ - gapsByLayer
21820
+ - newestScannedAt
21821
+ - maturedRepoCount
21822
+ - slippedRepoCount
21823
+ - previousShape
21824
+ - coverage
21825
+ - e2eCrossRepoCandidateCount
21826
+ - reposWithHotspots
21827
+ - ciQuality
21828
+ properties:
21829
+ workspaceId: { type: string, format: uuid }
21830
+ generatedAt: { type: string, format: date-time }
21831
+ reposWithPyramid: { type: integer, minimum: 0 }
21832
+ reposFromDegradedRuns:
21833
+ type: array
21834
+ items: { type: string, format: uuid }
21835
+ description: Repos whose newest pyramid came from a non-succeeded readiness run.
21836
+ totalClassifiedFiles:
21837
+ type: integer
21838
+ minimum: 0
21839
+ description: Workspace sum of classified test files (not cases).
21840
+ shape:
21841
+ $ref: "#/components/schemas/InsightsTestPyramidShapeDto"
21842
+ layerPresence:
21843
+ $ref: "#/components/schemas/InsightsTestPyramidLayerPresenceMapDto"
21844
+ maturityCounts:
21845
+ $ref: "#/components/schemas/InsightsTestPyramidMaturityCountsDto"
21846
+ gapsByLayer:
21847
+ $ref: "#/components/schemas/InsightsTestPyramidGapsByLayerDto"
21848
+ newestScannedAt:
21849
+ type: string
21850
+ format: date-time
21851
+ nullable: true
21852
+ description: Latest per-repo `scannedAt`. Null when `reposWithPyramid` is 0.
21853
+ maturedRepoCount:
21854
+ type: integer
21855
+ minimum: 0
21856
+ description: Repos whose Insights maturity rank increased vs the previous point.
21857
+ slippedRepoCount:
21858
+ type: integer
21859
+ minimum: 0
21860
+ description: Repos whose Insights maturity rank decreased vs the previous point.
21861
+ previousShape:
21862
+ allOf:
21863
+ - $ref: "#/components/schemas/InsightsTestPyramidShapeDto"
21864
+ nullable: true
21865
+ description: >
21866
+ Insights workspace shape from previous-point file totals for repos that
21867
+ have a previous point. Null when no repo has a previous point.
21868
+ coverage:
21869
+ $ref: "#/components/schemas/InsightsTestPyramidCoverageRollupDto"
21870
+ e2eCrossRepoCandidateCount:
21871
+ type: integer
21872
+ minimum: 0
21873
+ reposWithHotspots:
21874
+ type: integer
21875
+ minimum: 0
21876
+ description: Repos whose latest Code Insights snapshot has `hotspotCount` > 0.
21877
+ ciQuality:
21878
+ $ref: "#/components/schemas/InsightsTestPyramidCiQualityDto"
21879
+
21880
+ InsightsTestPyramidRepoItemDto:
21881
+ type: object
21882
+ required:
21883
+ - repoId
21884
+ - repoName
21885
+ - scannedAt
21886
+ - currentRunStatus
21887
+ - maturity
21888
+ - layerFileCounts
21889
+ - layerPresent
21890
+ - totalClassifiedFiles
21891
+ - shape
21892
+ - previousMaturity
21893
+ - maturityDelta
21894
+ - previousShapeLabel
21895
+ - lineCoverage
21896
+ - lowestConfidence
21897
+ - layerConfidence
21898
+ - evidenceCount
21899
+ - frameworks
21900
+ - layerApplicable
21901
+ - e2eCrossRepoCandidate
21902
+ - hotspotCount
21903
+ properties:
21904
+ repoId: { type: string, format: uuid }
21905
+ repoName: { type: string }
21906
+ scannedAt: { type: string, format: date-time }
21907
+ currentRunStatus:
21908
+ $ref: "#/components/schemas/TestPyramidRunStatusDto"
21909
+ maturity:
21910
+ $ref: "#/components/schemas/InsightsTestPyramidMaturityDto"
21911
+ previousMaturity:
21912
+ allOf:
21913
+ - $ref: "#/components/schemas/InsightsTestPyramidMaturityDto"
21914
+ nullable: true
21915
+ maturityDelta:
21916
+ $ref: "#/components/schemas/InsightsTestPyramidMaturityDeltaDto"
21917
+ previousShapeLabel:
21918
+ allOf:
21919
+ - $ref: "#/components/schemas/InsightsTestPyramidShapeLabelDto"
21920
+ nullable: true
21921
+ layerFileCounts:
21922
+ $ref: "#/components/schemas/InsightsTestPyramidLayerCountsDto"
21923
+ layerPresent:
21924
+ $ref: "#/components/schemas/InsightsTestPyramidLayerPresentDto"
21925
+ layerApplicable:
21926
+ allOf:
21927
+ - $ref: "#/components/schemas/InsightsTestPyramidLayerPresentDto"
21928
+ description: Snapshot `layers.*.applicable` for each layer.
21929
+ totalClassifiedFiles: { type: integer, minimum: 0 }
21930
+ shape:
21931
+ $ref: "#/components/schemas/InsightsTestPyramidShapeDto"
21932
+ lineCoverage:
21933
+ allOf:
21934
+ - $ref: "#/components/schemas/TestPyramidLineCoverageDto"
21935
+ description: >
21936
+ Same overlay as AF progress — latest Sonar row first, else snapshot
21937
+ `testPyramid.lineCoverage`. Null when both are missing. Not Code Insights
21938
+ `coveragePct`.
21939
+ lowestConfidence:
21940
+ allOf:
21941
+ - $ref: "#/components/schemas/InsightsTestPyramidConfidenceDto"
21942
+ description: >
21943
+ Minimum confidence among layers with Insights presence (`fileCount > 0`);
21944
+ if none present, minimum of applicable layers. Order low < medium < high.
21945
+ layerConfidence:
21946
+ $ref: "#/components/schemas/InsightsTestPyramidLayerConfidenceDto"
21947
+ evidenceCount:
21948
+ type: integer
21949
+ minimum: 0
21950
+ description: Sum of layer `evidence[]` lengths on the latest snapshot.
21951
+ frameworks:
21952
+ type: array
21953
+ maxItems: 8
21954
+ items: { type: string }
21955
+ description: Unique framework names across layers, capped at 8.
21956
+ e2eCrossRepoCandidate: { type: boolean }
21957
+ hotspotCount:
21958
+ type: integer
21959
+ nullable: true
21960
+ minimum: 0
21961
+ description: >
21962
+ Row count in `tai_workspace_repo_code_hotspots` for the repo's latest
21963
+ Code Insights metrics snapshot. Null when the repo has no metrics snapshot.
21964
+
21965
+ InsightsTestPyramidRepoListDto:
21966
+ type: object
21967
+ required: [items, total, limit, offset]
21968
+ properties:
21969
+ items:
21970
+ type: array
21971
+ items:
21972
+ $ref: "#/components/schemas/InsightsTestPyramidRepoItemDto"
21973
+ total: { type: integer, minimum: 0 }
21974
+ limit: { type: integer, minimum: 1 }
21975
+ offset: { type: integer, minimum: 0 }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkai/tai-api-contract",
3
- "version": "2.126.0",
3
+ "version": "2.128.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -20,7 +20,7 @@
20
20
  },
21
21
  "devDependencies": {
22
22
  "@stoplight/spectral-cli": "^6.16.3",
23
- "@types/node": "^26.4.0",
23
+ "@types/node": "^26.5.1",
24
24
  "jsonpath-plus": "^10.3.0",
25
25
  "openapi-typescript": "^7.13.0",
26
26
  "typescript": "~6.0.3"