zynk/cmd_code.h
hanez 739e3622b5 Commit links for !gitlog, full changelog link for !changelog, CMake, multi-file refactor
- !gitlog now shows a link to each commit in the repository, using the
  git remote URL converted from SSH/SCP to HTTPS
- !changelog now shows a 'Full changelog: <url>' link to CHANGELOG.md
  in the repository as the last message after all entries
- Removed 'full' keyword from !gitlog and !changelog (previously showed
  full commit messages and complete changelog entries)
- Switched build system from Make to CMake with feature toggles
  (-DWITH_<FEATURE>=ON/OFF)
- Refactored single-file codebase into dedicated header files: each
  command now lives in its own cmd_*.h file, with separate modules for
  database (db.h), IRC protocol (irc.h), networking (net.h), TLS (tls.h),
  and AI (ai.h)
- Updated README.md to reflect the simplified !gitlog and !changelog
  syntax and the new CMake build instructions

(0.40.0)
2026-07-23 01:46:37 +02:00

53 lines
1.9 KiB
C

#ifndef CMD_CODE_H
#define CMD_CODE_H
#include "zynk.h"
/*
* cmd_code - Handle the "!code <instruction>" command for AI code changes.
*
* Requires channel op and must be used in a channel (not PM). Wraps the
* instruction with context ("[CODE CHANGE REQUEST from op nick in #chan]")
* and passes it to ai_ask() with agent="build", which gives the AI full
* file-editing and command-execution capabilities. After the AI responds,
* try_compile_and_restart() is triggered to auto-deploy if compilation
* succeeds. Rate-limited.
*
* Parameters:
* s - The IRC session.
* msg - The raw message text.
* reply_target - Channel or nick to reply to.
* src_nick - The nick of the user who sent the command.
* tgt - The message target (channel or nick).
*
* Returns: 1 if matched, 0 otherwise.
*/
int cmd_code(Session *s, const char *msg, const char *reply_target, const char *src_nick, const char *tgt) {
if (strncmp(msg, "!code", 5) != 0) return 0;
if (msg[5] != ' ' && msg[5] != '\0') return 0;
if (tgt[0] != '#') {
irc_msg(s, reply_target, "!code can only be used in a channel");
return 1;
}
if (!chan_is_op(tgt, src_nick)) {
irc_msg(s, reply_target, "You need to be a channel op to use !code");
return 1;
}
const char *rest = msg[5] == ' ' ? msg + 6 : "";
while (*rest == ' ') rest++;
if (!*rest) {
irc_msg(s, reply_target, "Usage: !code <instruction for code change>");
return 1;
}
char question[2048];
snprintf(question, sizeof question,
"[CODE CHANGE REQUEST from op %s in %s] %s", src_nick, tgt, rest);
char *end = question + strlen(question);
while (end > question && end[-1] == ' ') end--;
*end = 0;
ai_ask(s, question, reply_target, src_nick, "build");
log_stamp(); fprintf(stderr, CLR_RED "CODE %s from %s (op in %s):" CLR_RESET " %s\n", reply_target, src_nick, tgt, rest);
return 1;
}
#endif