diff --git a/.agents/setup b/.agents/setup index 9a213acdeb20cedbf27c1791cccfd25035bc4170..a5af19f1ddeb53590d1193a0ffaf49e271d04194 100755 --- a/.agents/setup +++ b/.agents/setup @@ -4,6 +4,7 @@ set -euo pipefail if command -v apt-get >/dev/null 2>&1; then sudo apt-get update sudo apt-get install -y \ + asciidoc \ autoconf \ automake \ gcc \ diff --git a/src/main.c b/src/main.c index beb2e867fe1019bec30deafa51f4f3abc7522dc3..94ac1f2af61dafd75b96fe892e358c8ae11082cd 100644 --- a/src/main.c +++ b/src/main.c @@ -612,7 +612,60 @@ static int _agent_skill_command(int argc, char *argv[]) { "description: \"Communicates with the user and other contacts over XMPP/Jabber using xmppc. Use when asked to send, list, or receive Jabber/XMPP messages.\"\n" "---\n" "\n" - "Run `xmppc agent-skill` and follow the instructions it prints.\n"; + "Run `xmppc agent-skill` and follow the instructions it prints.\n" + "\n" + "For installing or updating xmppc itself, see `references/installation.md`.\n"; + + const char *installation_doc = + "# Installing xmppc for agent messaging\n" + "\n" + "Use this when xmppc is not installed, is too old, or does not have the\n" + "`agent-skill`, MAM `receive`, and `` behavior.\n" + "\n" + "Do not print secrets, password commands, or `~/.config/xmppc.conf` while\n" + "installing or testing. Runtime account policy belongs in\n" + "`~/.config/xmppc/AGENTS.md`.\n" + "\n" + "## Build dependencies\n" + "\n" + "On Debian/Ubuntu-like systems:\n" + "\n" + "```sh\n" + "sudo apt-get update\n" + "sudo apt-get install -y asciidoc autoconf automake gcc libglib2.0-dev libgpgme-dev libstrophe-dev libtool make pkg-config\n" + "```\n" + "\n" + "## Build from source\n" + "\n" + "```sh\n" + "git clone https://git.secluded.site/xmppc.git\n" + "cd xmppc\n" + "./bootstrap.sh\n" + "./configure\n" + "make -j$(nproc)\n" + "```\n" + "\n" + "## Install the binary\n" + "\n" + "Prefer the user's local binary directory when possible:\n" + "\n" + "```sh\n" + "mkdir -p ~/.local/bin\n" + "mv xmppc ~/.local/bin/xmppc\n" + "```\n" + "\n" + "If the environment expects a system-wide executable instead, use a privileged\n" + "location such as `/usr/local/bin/xmppc`:\n" + "\n" + "```sh\n" + "sudo mv xmppc /usr/local/bin/xmppc\n" + "```\n" + "\n" + "After installation, verify that the installed binary prints the agent contract:\n" + "\n" + "```sh\n" + "xmppc agent-skill\n" + "```\n"; if (argc == 2) { printf("%s", skill_text); @@ -628,9 +681,13 @@ static int _agent_skill_command(int argc, char *argv[]) { char *skill_dir = g_build_filename(home, ".config", "agents", "skills", "communicating-through-xmppc", NULL); char *skill_file = g_build_filename(skill_dir, "SKILL.md", NULL); + char *reference_dir = g_build_filename(skill_dir, "references", NULL); + char *installation_file = g_build_filename(reference_dir, "installation.md", NULL); - if (g_mkdir_with_parents(skill_dir, 0700) != 0) { + if (g_mkdir_with_parents(reference_dir, 0700) != 0) { fprintf(stderr, "Could not create skill directory: %s\n", skill_dir); + g_free(installation_file); + g_free(reference_dir); g_free(skill_file); g_free(skill_dir); return EXIT_FAILURE; @@ -640,12 +697,27 @@ static int _agent_skill_command(int argc, char *argv[]) { if (!g_file_set_contents(skill_file, pointer_skill, -1, &error)) { fprintf(stderr, "Could not write skill file: %s\n", error ? error->message : "unknown error"); g_clear_error(&error); + g_free(installation_file); + g_free(reference_dir); + g_free(skill_file); + g_free(skill_dir); + return EXIT_FAILURE; + } + + if (!g_file_set_contents(installation_file, installation_doc, -1, &error)) { + fprintf(stderr, "Could not write installation reference: %s\n", error ? error->message : "unknown error"); + g_clear_error(&error); + g_free(installation_file); + g_free(reference_dir); g_free(skill_file); g_free(skill_dir); return EXIT_FAILURE; } printf("Installed communicating-through-xmppc skill at %s\n", skill_file); + printf("Installed installation reference at %s\n", installation_file); + g_free(installation_file); + g_free(reference_dir); g_free(skill_file); g_free(skill_dir); return EXIT_SUCCESS;