| 1688 | /* ── OpenCode MCP config (JSON with "mcp" key) ───────────────── */ |
| 1689 | |
| 1690 | int cbm_upsert_opencode_mcp(const char *binary_path, const char *config_path) { |
| 1691 | if (!binary_path || !config_path) { |
| 1692 | return CLI_ERR; |
| 1693 | } |
| 1694 | |
| 1695 | yyjson_mut_doc *mdoc = yyjson_mut_doc_new(NULL); |
| 1696 | if (!mdoc) { |
| 1697 | return CLI_ERR; |
| 1698 | } |
| 1699 | |
| 1700 | yyjson_doc *doc = read_json_file(config_path); |
| 1701 | yyjson_mut_val *root; |
| 1702 | if (doc) { |
| 1703 | root = yyjson_val_mut_copy(mdoc, yyjson_doc_get_root(doc)); |
| 1704 | yyjson_doc_free(doc); |
| 1705 | } else { |
| 1706 | root = yyjson_mut_obj(mdoc); |
| 1707 | } |
| 1708 | if (!root) { |
| 1709 | yyjson_mut_doc_free(mdoc); |
| 1710 | return CLI_ERR; |
| 1711 | } |
| 1712 | yyjson_mut_doc_set_root(mdoc, root); |
| 1713 | |
| 1714 | /* Get or create "mcp" object */ |
| 1715 | yyjson_mut_val *mcp = yyjson_mut_obj_get(root, "mcp"); |
| 1716 | if (!mcp || !yyjson_mut_is_obj(mcp)) { |
| 1717 | mcp = yyjson_mut_obj(mdoc); |
| 1718 | yyjson_mut_obj_add_val(mdoc, root, "mcp", mcp); |
| 1719 | } |
| 1720 | |
| 1721 | yyjson_mut_obj_remove_key(mcp, "codebase-memory-mcp"); |
| 1722 | |
| 1723 | yyjson_mut_val *entry = yyjson_mut_obj(mdoc); |
| 1724 | yyjson_mut_obj_add_bool(mdoc, entry, "enabled", true); |
| 1725 | yyjson_mut_obj_add_str(mdoc, entry, "type", "local"); |
| 1726 | yyjson_mut_val *cmd_arr = yyjson_mut_arr(mdoc); |
| 1727 | yyjson_mut_arr_add_str(mdoc, cmd_arr, binary_path); |
| 1728 | yyjson_mut_obj_add_val(mdoc, entry, "command", cmd_arr); |
| 1729 | yyjson_mut_obj_add_val(mdoc, mcp, "codebase-memory-mcp", entry); |
| 1730 | |
| 1731 | int rc = write_json_file(config_path, mdoc); |
| 1732 | yyjson_mut_doc_free(mdoc); |
| 1733 | return rc; |
| 1734 | } |
| 1735 | |
| 1736 | int cbm_remove_opencode_mcp(const char *config_path) { |
| 1737 | if (!config_path) { |
no test coverage detected