🤖 codex: WIP agent-first templates (n/a)

What:
- add agent-first templates and human/agent steps
- embed full onboarding in README as single source of truth
- remove indirection docs and template step files

Why:
- make onboarding executable for zero-context agents

Tests:
- not run (docs/templates only)
This commit is contained in:
Josh Palmer 2026-01-02 16:46:44 +01:00
parent 13c0bfd00c
commit 80c87822c7
4 changed files with 155 additions and 60 deletions

View File

@ -7,12 +7,83 @@ Declarative Clawdis for macOS via Nix, designed to be **agentfirst**.
- This repo is a **public, generic** Nix package + Home Manager module for Clawdis.
- It does **not** include or depend on any personal `nixos-config` or private machine setup.
## Start here
## Agentfirst onboarding (the only supported path)
- AgentFirst Guide: `docs/agent-first.md`
- Operator Reference: `docs/operator-reference.md`
- RFC: `docs/rfc/2026-01-02-declarative-clawdis-nix.md`
This README is the **single source of truth**. Do not look for other docs.
### Humanintheloop (you must do these)
1) Create a Telegram bot token and save it to a file on disk.
- Recommended path: `/run/agenix/telegram-bot-token`
- If you do not use agenix, any readable file path works.
2) Send a Telegram message to your bot from the chat(s) you want to allow.
- This is required so chat IDs appear in Telegrams updates feed.
3) Provide these inputs to the agent (no guesswork):
- macOS version
- CPU architecture: `arm64` or `x86_64`
- Home Manager configuration name (e.g. `myuser`)
- Telegram bot token file path
- Telegram allowFrom chat IDs (list of ints)
Do not proceed unless all inputs above are provided.
### Agentonly steps (no human intervention)
1) Check if Determinate Nix is installed. If not, install it.
- If `nix --version` fails, run:
`curl -fsSL https://install.determinate.systems/nix | sh -s -- install`
2) Enable flakes in `~/.config/nix/nix.conf`.
- Ensure the directory exists: `mkdir -p ~/.config/nix`
- Ensure this line exists: `experimental-features = nix-command flakes`
3) Create a fresh local flake at `~/code/clawdis-local`.
4) Copy the template file from this repo:
- Source: `templates/agent-first/flake.nix`
- Target: `~/code/clawdis-local/flake.nix`
- Command: `cp templates/agent-first/flake.nix ~/code/clawdis-local/flake.nix`
5) Replace placeholders in `~/code/clawdis-local/flake.nix`:
- `<system>` = `aarch64-darwin` for arm64, `x86_64-darwin` for Intel
- `<user>` = Home Manager configuration name
- `<tokenPath>` = Telegram bot token file path
- `<allowFrom>` = spaceseparated list of ints
- Do not leave any placeholders in the file.
- After editing, re-open the file and verify there are no `<...>` strings left.
6) Validate the token file exists and is nonempty before proceeding.
- If the file does not exist or is empty, stop and ask the human to fix it.
7) If the human did not supply chat IDs, run the helper:
- File: `templates/agent-first/get-telegram-chat-ids.py`
- Command: `python3 templates/agent-first/get-telegram-chat-ids.py <tokenPath>`
- Ask the human to pick which chat IDs to allow.
- If the helper returns no chat IDs, stop and ask the human to send a message, then rerun the helper.
- If `python3` is missing, ask the human to install Xcode Command Line Tools.
8) Run Home Manager:
- If not installed: `nix run home-manager/release-24.11 -- init`
- If this command fails, stop and ask the human for approval to proceed.
- Then: `home-manager switch --flake .#<user>`
9) Verify:
- `launchctl print gui/$UID/com.nix-clawdis.gateway | grep state`
- `tail -n 50 ~/.clawdis/logs/clawdis-gateway.log`
10) Ask the human to send a test message and confirm a reply.
### Expected success signals
- `launchctl print` shows `state = running`.
- Log file contains no fatal errors on startup.
- Bot replies to a message in an allowlisted chat.
### Deterministic checklist (agent selftest)
The agents work is correct **only if** all checks pass:
- A new local flake exists at `~/code/clawdis-local`.
- That flake references `github:joshp123/nix-clawdis` as an input.
- Home Manager config enables `programs.clawdis` with Telegram enabled.
- Token is referenced by a file path (no inline secrets).
- `launchctl print gui/$UID/com.nix-clawdis.gateway | grep state` shows `state = running`.
- `~/.clawdis/logs/clawdis-gateway.log` shows startup without fatal errors.
- A real Telegram message in an allowlisted chat receives a bot response.
If any item fails, the setup is incomplete.
## Status
This repo is being rebuilt to be fully declarative and agentfirst. The RFC is the source of truth.
The RFC lives at `docs/rfc/2026-01-02-declarative-clawdis-nix.md` and defines success criteria.

View File

@ -1,57 +1,5 @@
# AgentFirst Guide (single prompt + deterministic checklist)
# AgentFirst Guide
This repo is designed to be executed by a coding agent with **zero context**. Use the prompt below exactly asis.
Single source of instructions: `templates/agent-first/steps.md`.
## Copypaste prompt (the only supported onboarding path)
```text
You are setting up Clawdis on macOS using the public nix-clawdis repo.
Requirements:
- Everything must be declarative and reproducible.
- Do NOT touch any personal nixos-config or private repo.
- Use a fresh, local flake directory (e.g. ~/code/clawdis-local).
- Use Home Manager for user-level config.
Inputs (ask me to fill these in if missing):
- macOS version:
- Home Manager configuration name (e.g. "myuser"):
- Telegram bot token file path:
- Telegram allowFrom chat IDs (list of ints):
Steps you must perform:
1) Check if Determinate Nix is installed; install it if missing.
2) Enable flakes in ~/.config/nix/nix.conf.
3) Create a local flake at ~/code/clawdis-local (do not use any personal config repo).
4) Add nix-clawdis as a flake input and enable the Home Manager module.
5) Wire the Telegram token file path and allowFrom list declaratively.
6) Run home-manager switch for the configured user.
7) Verify launchd status and logs:
- launchctl print gui/$UID/com.nix-clawdis.gateway | grep state
- tail -n 50 ~/.clawdis/logs/clawdis-gateway.log
8) Smoke test: send a Telegram message in an allowlisted chat and confirm the bot replies.
Constraints:
- Telegram-first only.
- No ad-hoc JSON edits; config must be derived from Nix options.
- Secrets must be passed as a file path (agenix-style).
Deliverables:
- A working Clawdis gateway running via launchd.
- A single, reproducible local flake that can be rebuilt on another machine.
- A short summary of what was changed and how to verify it again.
```
## Deterministic checklist (agent selftest)
The agents work is correct **only if** all checks pass:
- A new local flake exists at `~/code/clawdis-local`.
- That flake references `github:joshp123/nix-clawdis` as an input.
- Home Manager config enables `programs.clawdis` with Telegram enabled.
- Token is referenced by a file path (no inline secrets).
- `launchctl print gui/$UID/com.nix-clawdis.gateway | grep state` shows `state = running`.
- `~/.clawdis/logs/clawdis-gateway.log` shows startup without fatal errors.
- A real Telegram message in an allowlisted chat receives a bot response.
If any item fails, the setup is incomplete.
This guide intentionally contains **no code blocks**. All code lives in files under `templates/agent-first/`.

View File

@ -0,0 +1,34 @@
{
description = "Clawdis local";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
nix-clawdis.url = "github:joshp123/nix-clawdis";
};
outputs = { self, nixpkgs, home-manager, nix-clawdis }:
let
system = "<system>";
pkgs = import nixpkgs { inherit system; };
in {
homeManagerConfigurations.<user> = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
nix-clawdis.homeManagerModules.clawdis
{
programs.clawdis = {
enable = true;
providers.telegram = {
enable = true;
botTokenFile = "<tokenPath>";
allowFrom = [ <allowFrom> ];
};
routing.queue.mode = "interrupt";
};
}
];
};
};
}

View File

@ -0,0 +1,42 @@
import json
import sys
import urllib.request
def die(msg):
print(msg, file=sys.stderr)
sys.exit(1)
if len(sys.argv) != 2:
die("Usage: python3 get-telegram-chat-ids.py <tokenPath>")
token_path = sys.argv[1]
try:
with open(token_path, "r", encoding="utf-8") as f:
token = f.read().strip()
except FileNotFoundError:
die(f"Token file not found: {token_path}")
if not token:
die("Token file is empty")
url = f"https://api.telegram.org/bot{token}/getUpdates"
try:
with urllib.request.urlopen(url) as resp:
data = json.loads(resp.read().decode("utf-8"))
except Exception as exc:
die(f"Failed to call Telegram API: {exc}")
results = data.get("result", [])
chat_ids = []
for entry in results:
msg = entry.get("message") or entry.get("edited_message")
if not msg:
continue
chat = msg.get("chat") or {}
cid = chat.get("id")
if cid is not None and cid not in chat_ids:
chat_ids.append(cid)
print("Chat IDs:")
for cid in chat_ids:
print(cid)