diff --git a/include/wolfram/temp_typed.h b/include/wolfram/temp_typed.h index 77ec117..d08173d 100644 --- a/include/wolfram/temp_typed.h +++ b/include/wolfram/temp_typed.h @@ -200,12 +200,10 @@ wf_status wf_agent_request_phone_verification(wf_agent *agent, wf_status wf_agent_request_phone_verification_typed(wf_agent *agent, const char *phone_number); -/* Issue revokeAccountCredentials. The atproto lexicon requires an `account` - * (at-identifier) input that this helper's signature does not carry, so this is - * an honest stub returning WF_ERR_INVALID_ARG with a TODO (AGENTS.md #3). */ -wf_status wf_agent_revoke_account_credentials(wf_agent *agent, const char *code, - const char *name, - const char *description); +/* Issue revokeAccountCredentials (procedure, input: account at-identifier). + * Returns wf_status only (the procedure returns no body). */ +wf_status wf_agent_revoke_account_credentials(wf_agent *agent, + const char *account); /* Issue revokeAccountCredentials carrying the lexicon-required `account` * (at-identifier) input. Returns wf_status only (the procedure returns no diff --git a/src/agent/temp_typed.c b/src/agent/temp_typed.c index 50b9121..71275be 100644 --- a/src/agent/temp_typed.c +++ b/src/agent/temp_typed.c @@ -532,21 +532,22 @@ wf_status wf_agent_request_phone_verification_typed(wf_agent *agent, return status; } -wf_status wf_agent_revoke_account_credentials(wf_agent *agent, const char *code, - const char *name, - const char *description) { - (void)code; - (void)name; - (void)description; - /* TODO: the atproto lexicon input for - * com.atproto.temp.revokeAccountCredentials is `account` (an - * at-identifier), which this helper signature does not carry. Implement - * once the wrapper accepts the account identifier rather than fabricating - * a request. Until then, fail honestly per AGENTS.md principle 3. */ - if (!agent) { +wf_status wf_agent_revoke_account_credentials(wf_agent *agent, + const char *account) { + if (!agent || !agent->client || !account || !account[0]) { return WF_ERR_INVALID_ARG; } - return WF_ERR_INVALID_ARG; + + wf_lex_com_atproto_temp_revoke_account_credentials_main_input input = {0}; + input.account = account; + + wf_agent_sync_auth(agent); + wf_response res = {0}; + wf_status status = + wf_lex_com_atproto_temp_revoke_account_credentials_main_call( + agent->client, &input, &res); + wf_response_free(&res); + return status; } wf_status wf_agent_add_reserved_handle(wf_agent *agent, const char *handle) { diff --git a/src/cli/main.c b/src/cli/main.c index 4abdf97..7115561 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -77,6 +77,7 @@ #include "wolfram/feedgen_typed.h" #include "wolfram/notification_typed.h" #include "wolfram/moderation_report_typed.h" +#include "wolfram/temp_typed.h" /* Global --json flag: when set, list/get commands print the raw JSON body * instead of human-readable text. Parsed in main() before dispatch. */ @@ -128,8 +129,10 @@ void usage_stream(FILE *out) { " unmute \n" "\n" " Identity & moderation:\n" - " resolve \n" - " labels subscribe [--cursor N] [--seconds N]\n" + " resolve \n" + " revoke-account-credentials " + "\n" + " labels subscribe [--cursor N] [--seconds N]\n" " moderation [labeler-did]\n" " moderation report --subject " "--reason [--reason-type ] [--cid ]\n" @@ -2012,6 +2015,34 @@ static int cmd_mutes(int argc, char **argv) { return finish_agent_response(agent, s, &res); } +/* wolfram revoke-account-credentials */ +static int cmd_revoke_account_credentials(int argc, char **argv) { + if (argc < 5) { + usage_stream(stderr); + return 0; + } + const char *service = argv[1]; + const char *handle = argv[2]; + const char *password = argv[3]; + const char *account = argv[4]; + + wf_agent *agent = agent_login_or_err(service, handle, password); + if (!agent) { + return 1; + } + + wf_status s = wf_agent_revoke_account_credentials(agent, account); + if (s != WF_OK) { + fprintf(stderr, "error: revokeAccountCredentials failed (status %d)\n", + (int)s); + wf_agent_free(agent); + return 1; + } + printf("revoked credentials for %s\n", account); + wf_agent_free(agent); + return 0; +} + /* wolfram list [limit] */ static int cmd_list(int argc, char **argv) { if (argc < 3) { @@ -2775,6 +2806,9 @@ int main(int argc, char **argv) { if (strcmp(cmd, "mutes") == 0) { return cmd_mutes(rest, cargv); } + if (strcmp(cmd, "revoke-account-credentials") == 0) { + return cmd_revoke_account_credentials(rest, cargv); + } if (strcmp(cmd, "mute") == 0) { return cmd_mute(rest, cargv); } diff --git a/test/test_temp_typed.c b/test/test_temp_typed.c index 314ea92..3d30a17 100644 --- a/test/test_temp_typed.c +++ b/test/test_temp_typed.c @@ -200,6 +200,16 @@ int main(void) { WF_ERR_INVALID_ARG); } + /* ---- revokeAccountCredentials argument validation ---- */ + { + WF_CHECK(wf_agent_revoke_account_credentials(NULL, "did:plc:a") == + WF_ERR_INVALID_ARG); + WF_CHECK(wf_agent_revoke_account_credentials(NULL, NULL) == + WF_ERR_INVALID_ARG); + WF_CHECK(wf_agent_revoke_account_credentials(NULL, "") == + WF_ERR_INVALID_ARG); + } + /* ---- revokeAccountCredentials (typed) argument validation ---- */ { WF_CHECK(wf_agent_revoke_account_credentials_typed(NULL, "did:plc:a") ==