| 401 | } |
| 402 | |
| 403 | static char *render_kiro_profile(cbm_graph_tier_t tier, cbm_graph_access_t access, |
| 404 | const char *binary_path, const char *prompt) { |
| 405 | if (access == CBM_GRAPH_ACCESS_DIRECT && (!binary_path || !binary_path[0])) { |
| 406 | return NULL; |
| 407 | } |
| 408 | yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL); |
| 409 | yyjson_mut_val *root = doc ? yyjson_mut_obj(doc) : NULL; |
| 410 | yyjson_mut_val *tools = doc ? yyjson_mut_arr(doc) : NULL; |
| 411 | if (!doc || !root || !tools) { |
| 412 | if (doc) { |
| 413 | yyjson_mut_doc_free(doc); |
| 414 | } |
| 415 | return NULL; |
| 416 | } |
| 417 | yyjson_mut_doc_set_root(doc, root); |
| 418 | const char *slug = cbm_graph_tier_slug(tier); |
| 419 | bool ok = |
| 420 | yyjson_mut_obj_add_strcpy(doc, root, "name", slug) && |
| 421 | yyjson_mut_obj_add_strcpy(doc, root, "description", profile_description(tier, access)) && |
| 422 | yyjson_mut_obj_add_strcpy(doc, root, "prompt", prompt) && |
| 423 | yyjson_mut_arr_add_str(doc, tools, "read") && yyjson_mut_arr_add_str(doc, tools, "grep") && |
| 424 | yyjson_mut_arr_add_str(doc, tools, "glob"); |
| 425 | if (ok && access == CBM_GRAPH_ACCESS_DIRECT) { |
| 426 | const profile_tool_t *tier_tools = NULL; |
| 427 | size_t count = 0U; |
| 428 | tier_tool_set(tier, &tier_tools, &count); |
| 429 | for (size_t i = 0U; ok && i < count; i++) { |
| 430 | char identifier[160]; |
| 431 | ok = tool_identifier(CBM_GRAPH_DIALECT_KIRO, tier_tools[i], identifier, |
| 432 | sizeof(identifier)) && |
| 433 | yyjson_mut_arr_add_strcpy(doc, tools, identifier); |
| 434 | } |
| 435 | } |
| 436 | ok = ok && yyjson_mut_obj_add_val(doc, root, "tools", tools) && |
| 437 | yyjson_mut_obj_add_bool(doc, root, "includeMcpJson", false); |
| 438 | if (ok && access == CBM_GRAPH_ACCESS_DIRECT) { |
| 439 | yyjson_mut_val *servers = yyjson_mut_obj(doc); |
| 440 | yyjson_mut_val *server = yyjson_mut_obj(doc); |
| 441 | yyjson_mut_val *args = yyjson_mut_arr(doc); |
| 442 | ok = servers && server && args && |
| 443 | yyjson_mut_obj_add_strcpy(doc, server, "command", binary_path) && |
| 444 | yyjson_mut_arr_add_str(doc, args, "--tool-profile") && |
| 445 | yyjson_mut_arr_add_strcpy(doc, args, tier_server_profile(tier)) && |
| 446 | yyjson_mut_obj_add_val(doc, server, "args", args) && |
| 447 | yyjson_mut_obj_add_val(doc, servers, "codebase-memory-mcp", server) && |
| 448 | yyjson_mut_obj_add_val(doc, root, "mcpServers", servers); |
| 449 | } |
| 450 | char *result = ok ? yyjson_mut_write(doc, YYJSON_WRITE_PRETTY, NULL) : NULL; |
| 451 | yyjson_mut_doc_free(doc); |
| 452 | return result; |
| 453 | } |
| 454 | |
| 455 | /* Codex deserializes role files standalone: a server table without command/url |
| 456 | * is rejected as "invalid transport" and the whole role is dropped, so direct |
no test coverage detected