@@ -1785,9 +1785,30 @@ static char *handle_get_architecture(cbm_mcp_server_t *srv, const char *args) {
17851785 }
17861786 }
17871787
1788+ /* Build a C string array from aspects for cbm_store_get_architecture.
1789+ * Strings point into aspects_doc memory so aspects_doc must outlive this array. */
1790+ const char * aspects_strs [MCP_COL_16 ];
1791+ int aspects_strs_count = 0 ;
1792+ if (aspects_arr ) {
1793+ size_t aspect_idx ;
1794+ size_t aspect_max ;
1795+ yyjson_val * aspect_val ;
1796+ yyjson_arr_foreach (aspects_arr , aspect_idx , aspect_max , aspect_val ) {
1797+ const char * s = yyjson_get_str (aspect_val );
1798+ if (s && aspects_strs_count < MCP_COL_16 ) {
1799+ aspects_strs [aspects_strs_count ++ ] = s ;
1800+ }
1801+ }
1802+ }
1803+
17881804 cbm_schema_info_t schema = {0 };
17891805 cbm_store_get_schema (store , project , & schema );
17901806
1807+ cbm_architecture_info_t arch = {0 };
1808+ cbm_store_get_architecture (store , project ,
1809+ aspects_strs_count > 0 ? aspects_strs : NULL ,
1810+ aspects_strs_count , & arch );
1811+
17911812 int node_count = cbm_store_count_nodes (store , project );
17921813 int edge_count = cbm_store_count_edges (store , project );
17931814
@@ -1834,10 +1855,117 @@ static char *handle_get_architecture(cbm_mcp_server_t *srv, const char *args) {
18341855 yyjson_mut_obj_add_val (doc , root , "relationship_patterns" , pats );
18351856 }
18361857
1858+ /* Languages */
1859+ if (arch .language_count > 0 ) {
1860+ yyjson_mut_val * langs = yyjson_mut_arr (doc );
1861+ for (int i = 0 ; i < arch .language_count ; i ++ ) {
1862+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1863+ yyjson_mut_obj_add_str (doc , item , "language" , arch .languages [i ].language );
1864+ yyjson_mut_obj_add_int (doc , item , "file_count" , arch .languages [i ].file_count );
1865+ yyjson_mut_arr_add_val (langs , item );
1866+ }
1867+ yyjson_mut_obj_add_val (doc , root , "languages" , langs );
1868+ }
1869+
1870+ /* Packages */
1871+ if (arch .package_count > 0 ) {
1872+ yyjson_mut_val * pkgs = yyjson_mut_arr (doc );
1873+ for (int i = 0 ; i < arch .package_count ; i ++ ) {
1874+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1875+ yyjson_mut_obj_add_str (doc , item , "name" , arch .packages [i ].name );
1876+ yyjson_mut_obj_add_int (doc , item , "node_count" , arch .packages [i ].node_count );
1877+ yyjson_mut_obj_add_int (doc , item , "fan_in" , arch .packages [i ].fan_in );
1878+ yyjson_mut_obj_add_int (doc , item , "fan_out" , arch .packages [i ].fan_out );
1879+ yyjson_mut_arr_add_val (pkgs , item );
1880+ }
1881+ yyjson_mut_obj_add_val (doc , root , "packages" , pkgs );
1882+ }
1883+
1884+ /* Entry points */
1885+ if (arch .entry_point_count > 0 ) {
1886+ yyjson_mut_val * eps = yyjson_mut_arr (doc );
1887+ for (int i = 0 ; i < arch .entry_point_count ; i ++ ) {
1888+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1889+ yyjson_mut_obj_add_str (doc , item , "name" , arch .entry_points [i ].name );
1890+ yyjson_mut_obj_add_str (doc , item , "qualified_name" ,
1891+ arch .entry_points [i ].qualified_name );
1892+ yyjson_mut_obj_add_str (doc , item , "file" , arch .entry_points [i ].file );
1893+ yyjson_mut_arr_add_val (eps , item );
1894+ }
1895+ yyjson_mut_obj_add_val (doc , root , "entry_points" , eps );
1896+ }
1897+
1898+ /* HTTP routes */
1899+ if (arch .route_count > 0 ) {
1900+ yyjson_mut_val * routes = yyjson_mut_arr (doc );
1901+ for (int i = 0 ; i < arch .route_count ; i ++ ) {
1902+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1903+ yyjson_mut_obj_add_str (doc , item , "method" , arch .routes [i ].method );
1904+ yyjson_mut_obj_add_str (doc , item , "path" , arch .routes [i ].path );
1905+ yyjson_mut_obj_add_str (doc , item , "handler" , arch .routes [i ].handler );
1906+ yyjson_mut_arr_add_val (routes , item );
1907+ }
1908+ yyjson_mut_obj_add_val (doc , root , "routes" , routes );
1909+ }
1910+
1911+ /* Hotspots */
1912+ if (arch .hotspot_count > 0 ) {
1913+ yyjson_mut_val * hotspots = yyjson_mut_arr (doc );
1914+ for (int i = 0 ; i < arch .hotspot_count ; i ++ ) {
1915+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1916+ yyjson_mut_obj_add_str (doc , item , "name" , arch .hotspots [i ].name );
1917+ yyjson_mut_obj_add_str (doc , item , "qualified_name" ,
1918+ arch .hotspots [i ].qualified_name );
1919+ yyjson_mut_obj_add_int (doc , item , "fan_in" , arch .hotspots [i ].fan_in );
1920+ yyjson_mut_arr_add_val (hotspots , item );
1921+ }
1922+ yyjson_mut_obj_add_val (doc , root , "hotspots" , hotspots );
1923+ }
1924+
1925+ /* Cross-package boundaries */
1926+ if (arch .boundary_count > 0 ) {
1927+ yyjson_mut_val * boundaries = yyjson_mut_arr (doc );
1928+ for (int i = 0 ; i < arch .boundary_count ; i ++ ) {
1929+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1930+ yyjson_mut_obj_add_str (doc , item , "from" , arch .boundaries [i ].from );
1931+ yyjson_mut_obj_add_str (doc , item , "to" , arch .boundaries [i ].to );
1932+ yyjson_mut_obj_add_int (doc , item , "call_count" , arch .boundaries [i ].call_count );
1933+ yyjson_mut_arr_add_val (boundaries , item );
1934+ }
1935+ yyjson_mut_obj_add_val (doc , root , "boundaries" , boundaries );
1936+ }
1937+
1938+ /* Package layers */
1939+ if (arch .layer_count > 0 ) {
1940+ yyjson_mut_val * layers = yyjson_mut_arr (doc );
1941+ for (int i = 0 ; i < arch .layer_count ; i ++ ) {
1942+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1943+ yyjson_mut_obj_add_str (doc , item , "name" , arch .layers [i ].name );
1944+ yyjson_mut_obj_add_str (doc , item , "layer" , arch .layers [i ].layer );
1945+ yyjson_mut_obj_add_str (doc , item , "reason" , arch .layers [i ].reason );
1946+ yyjson_mut_arr_add_val (layers , item );
1947+ }
1948+ yyjson_mut_obj_add_val (doc , root , "layers" , layers );
1949+ }
1950+
1951+ /* File tree */
1952+ if (arch .file_tree_count > 0 ) {
1953+ yyjson_mut_val * file_tree = yyjson_mut_arr (doc );
1954+ for (int i = 0 ; i < arch .file_tree_count ; i ++ ) {
1955+ yyjson_mut_val * item = yyjson_mut_obj (doc );
1956+ yyjson_mut_obj_add_str (doc , item , "path" , arch .file_tree [i ].path );
1957+ yyjson_mut_obj_add_str (doc , item , "type" , arch .file_tree [i ].type );
1958+ yyjson_mut_obj_add_int (doc , item , "children" , arch .file_tree [i ].children );
1959+ yyjson_mut_arr_add_val (file_tree , item );
1960+ }
1961+ yyjson_mut_obj_add_val (doc , root , "file_tree" , file_tree );
1962+ }
1963+
18371964 append_cross_repo_summary (doc , root , & schema );
18381965
18391966 char * json = yy_doc_to_str (doc );
18401967 yyjson_mut_doc_free (doc );
1968+ cbm_store_architecture_free (& arch );
18411969 cbm_store_schema_free (& schema );
18421970 if (aspects_doc ) {
18431971 yyjson_doc_free (aspects_doc );
0 commit comments