diff --git a/flake.lock b/flake.lock index 1e6fb662..2a381e75 100644 --- a/flake.lock +++ b/flake.lock @@ -121,6 +121,21 @@ "type": "github" } }, + "crane": { + "locked": { + "lastModified": 1785782307, + "narHash": "sha256-MPaRdVkf6zZP5fCPxYCi8Dr4pZzgmXzg8T9nVEbp3Mw=", + "owner": "ipetkov", + "repo": "crane", + "rev": "2c71e194474d13de031d729b729c968ddbe3507f", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "fenix": { "inputs": { "nixpkgs": [ @@ -223,6 +238,27 @@ } }, "flake-parts_4": { + "inputs": { + "nixpkgs-lib": [ + "mcp-rss", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1785627969, + "narHash": "sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "427bf4bd9435fdf21321c8cc628c24efc14c0f7a", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_5": { "inputs": { "nixpkgs-lib": [ "nixos-facter-detection-modules", @@ -243,7 +279,7 @@ "type": "github" } }, - "flake-parts_5": { + "flake-parts_6": { "inputs": { "nixpkgs-lib": [ "nur", @@ -264,7 +300,7 @@ "type": "github" } }, - "flake-parts_6": { + "flake-parts_7": { "inputs": { "nixpkgs-lib": [ "stylix", @@ -413,6 +449,28 @@ "type": "github" } }, + "mcp-rss": { + "inputs": { + "crane": "crane", + "flake-parts": "flake-parts_4", + "nixpkgs": "nixpkgs_3", + "rust-overlay": "rust-overlay_2" + }, + "locked": { + "lastModified": 1787132607, + "narHash": "sha256-3fc5b8dkMNPFCDfUU6VwaaKTeOzooqhLFfZ5sShe6Zs=", + "owner": "haras-unicorn", + "repo": "mcp-rss", + "rev": "95a5ace3eee1a0ea9030d5d238280fc92e8b8380", + "type": "github" + }, + "original": { + "owner": "haras-unicorn", + "ref": "refs/tags/v0.2.0", + "repo": "mcp-rss", + "type": "github" + } + }, "musnix": { "inputs": { "nixpkgs": [ @@ -542,7 +600,7 @@ }, "nixos-facter-detection-modules": { "inputs": { - "flake-parts": "flake-parts_4", + "flake-parts": "flake-parts_5", "import-tree": "import-tree_2", "nix-unit": "nix-unit", "nixpkgs": [ @@ -613,6 +671,22 @@ } }, "nixpkgs_3": { + "locked": { + "lastModified": 1787051493, + "narHash": "sha256-1V6B5OkuysJ/atgFNNm/4r8ATH3XdEGS5jub1mbLj10=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "2f14835f889c23ae4a95a63279878240d2a4f18e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-26.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { "locked": { "lastModified": 1783148766, "narHash": "sha256-uslt2pqShTIXDdAHRHv2QkYLsVdY8Oqwz0EA48/RSM8=", @@ -628,7 +702,7 @@ "type": "github" } }, - "nixpkgs_4": { + "nixpkgs_5": { "locked": { "lastModified": 1783224372, "narHash": "sha256-FGQ8TfSm9WviNE/fQAWsKs+y4GkX8fU4EScewpw54Y8=", @@ -641,7 +715,7 @@ "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" } }, - "nixpkgs_5": { + "nixpkgs_6": { "locked": { "lastModified": 1783224372, "narHash": "sha256-FGQ8TfSm9WviNE/fQAWsKs+y4GkX8fU4EScewpw54Y8=", @@ -654,7 +728,7 @@ "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" } }, - "nixpkgs_6": { + "nixpkgs_7": { "locked": { "lastModified": 1780203844, "narHash": "sha256-K5sT4jTpGs15ADhviMKNBH38REpPf5Q6mM1+N6cArVE=", @@ -672,7 +746,7 @@ }, "noctalia": { "inputs": { - "nixpkgs": "nixpkgs_4" + "nixpkgs": "nixpkgs_5" }, "locked": { "lastModified": 1783730119, @@ -691,7 +765,7 @@ }, "nur": { "inputs": { - "flake-parts": "flake-parts_5", + "flake-parts": "flake-parts_6", "nixpkgs": [ "nixpkgs" ] @@ -743,11 +817,12 @@ "import-tree": "import-tree", "llm-agents": "llm-agents", "mcp-nix": "mcp-nix", + "mcp-rss": "mcp-rss", "musnix": "musnix", "nix-index-database": "nix-index-database", "nix-vscode-extensions": "nix-vscode-extensions", "nixos-facter-detection-modules": "nixos-facter-detection-modules", - "nixpkgs": "nixpkgs_3", + "nixpkgs": "nixpkgs_4", "nixpkgs-unstable": "nixpkgs-unstable", "noctalia": "noctalia", "nur": "nur", @@ -793,9 +868,30 @@ "type": "github" } }, + "rust-overlay_2": { + "inputs": { + "nixpkgs": [ + "mcp-rss", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1787022047, + "narHash": "sha256-wNlYM/obKOkkRELrOfto1JT5CRANR6hB/RjOELp223U=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "b32685dd7c5a965aa8273adb7ddaf7f5b40d0faa", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, "spicetify-nix": { "inputs": { - "nixpkgs": "nixpkgs_5", + "nixpkgs": "nixpkgs_6", "systems": "systems_2" }, "locked": { @@ -819,9 +915,9 @@ "base16-helix": "base16-helix", "base16-vim": "base16-vim", "firefox-gnome-theme": "firefox-gnome-theme", - "flake-parts": "flake-parts_6", + "flake-parts": "flake-parts_7", "gnome-shell": "gnome-shell", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_7", "nur": "nur_2", "systems": "systems_3", "tinted-kitty": "tinted-kitty", diff --git a/flake.nix b/flake.nix index c12c2303..ca7fe05b 100644 --- a/flake.nix +++ b/flake.nix @@ -45,6 +45,9 @@ # NOTE: https://github.com/haras-unicorn/mcp-nix/blob/v0.1.3/README.md mcp-nix.url = "github:haras-unicorn/mcp-nix/refs/tags/v0.1.3"; + + # NOTE: https://github.com/haras-unicorn/mcp-rss/blob/v0.2.0/README.md + mcp-rss.url = "github:haras-unicorn/mcp-rss/refs/tags/v0.2.0"; }; outputs = diff --git a/src/modules/ai/zeroclaw/AGENTS.md b/src/modules/ai/zeroclaw/agent/AGENTS.md similarity index 100% rename from src/modules/ai/zeroclaw/AGENTS.md rename to src/modules/ai/zeroclaw/agent/AGENTS.md diff --git a/src/modules/ai/zeroclaw/IDENTITY.md b/src/modules/ai/zeroclaw/agent/IDENTITY.md similarity index 100% rename from src/modules/ai/zeroclaw/IDENTITY.md rename to src/modules/ai/zeroclaw/agent/IDENTITY.md diff --git a/src/modules/ai/zeroclaw/SOUL.md b/src/modules/ai/zeroclaw/agent/SOUL.md similarity index 100% rename from src/modules/ai/zeroclaw/SOUL.md rename to src/modules/ai/zeroclaw/agent/SOUL.md diff --git a/src/modules/ai/zeroclaw/TOOLS.md b/src/modules/ai/zeroclaw/agent/TOOLS.md similarity index 100% rename from src/modules/ai/zeroclaw/TOOLS.md rename to src/modules/ai/zeroclaw/agent/TOOLS.md diff --git a/src/modules/ai/zeroclaw/USER.md b/src/modules/ai/zeroclaw/agent/USER.md similarity index 98% rename from src/modules/ai/zeroclaw/USER.md rename to src/modules/ai/zeroclaw/agent/USER.md index 316f5cdf..174fef7c 100644 --- a/src/modules/ai/zeroclaw/USER.md +++ b/src/modules/ai/zeroclaw/agent/USER.md @@ -1,4 +1,4 @@ -# Sarah +# USER.md 28, trans woman, software engineer. diff --git a/src/modules/ai/zeroclaw/cron/DIGEST.md b/src/modules/ai/zeroclaw/cron/DIGEST.md new file mode 100644 index 00000000..bad9b25c --- /dev/null +++ b/src/modules/ai/zeroclaw/cron/DIGEST.md @@ -0,0 +1,31 @@ +# DIGEST.md + +Shared digest: fetch rules and cron job instructions. + +## Cron Job Instructions + +When running the digest cron job: + +1. Read `DIGEST.md` from your workspace to get feeds, filters and preferences + and last run date. +2. Get all articles from feeds via `rss__get_articles` with `time_from` as the + last time this job ran from `DIGEST.md` if it exists. +3. Fetch all the fetched articles with `rss__fetch_article`. +4. Use `memory_store` to remember all the fetched articles that pass filters + from `DIGEST.md` in your workspace. Use keys like + `digest:-` and set values as the article summary in + 1-2 sentences with the link to the article at the end in the following + format: `# \n\n<summary-paragraph>\n\nLink: <link>\n`. +5. Generate a report summarizing new items grouped by theme, newest first. +6. Write down when the cron job started in the workspace `DIGEST.md`. +7. Deliver the report to the configured channel. +8. If nothing is new, report a single line. If fetch fails, state plainly. + +## Rules + +- Report Language: English. +- Links: Keep item links in reports. +- On failure: Say so plainly. Never fabricate items. +- Tools: Never use `http_request` or `web_fetch` tools to fetch feeds or + articles. Always use `rss__get_articles` to fetch feeds and + `rss__fetch_article` to fetch articles. diff --git a/src/modules/ai/zeroclaw/default.nix b/src/modules/ai/zeroclaw/default.nix index 4e8a286f..16aa91af 100644 --- a/src/modules/ai/zeroclaw/default.nix +++ b/src/modules/ai/zeroclaw/default.nix @@ -9,6 +9,7 @@ # MATRIX_HOMESERVER # MATRIX_USER_ID # MATRIX_PEER +# MATRIX_DIGEST_ROOM # GIT_USER # GIT_EMAIL # GIT_SSH_KEY @@ -101,7 +102,11 @@ in risk_profile = "main"; runtime_profile = "main"; channels = [ "matrix.main" ]; - mcp_bundles = [ "dev" ]; + mcp_bundles = [ + "dev" + "digest" + ]; + cron_jobs = [ "digest" ]; }; schema_version = 3; @@ -255,6 +260,9 @@ in "TodoWrite" "mcp_resources" + "rss__get_articles" + "rss__fetch_article" + "nixos__nix" "nixos__nix_versions" @@ -481,16 +489,44 @@ in ]; }; } + { + name = "rss"; + transport = "stdio"; + command = lib.getExe inputs.mcp-rss.packages.${system}.mcp-rss; + } ]; }; - mcp_bundles.dev = { - servers = [ - "nixos" - "nix" - "git" - "github" - ]; + mcp_bundles = { + dev = { + servers = [ + "nixos" + "nix" + "git" + "github" + ]; + }; + digest = { + servers = [ + "rss" + ]; + }; + }; + + cron = { + digest = { + job_type = "agent"; + schedule = { + kind = "cron"; + expr = "0 6 * * *"; + }; + prompt = builtins.readFile ./cron/DIGEST.md; + delivery = { + mode = "announce"; + channel = "matrix.main"; + to = "$MATRIX_DIGEST_ROOM"; + }; + }; }; web_search = { @@ -627,11 +663,11 @@ in mv -f "${dataDir}/.config.toml.tmp" "${dataDir}/config.toml" mkdir -p ${agentWorkspaceDir} - install -m 0644 ${./AGENTS.md} "${agentWorkspaceDir}/AGENTS.md" - install -m 0644 ${./IDENTITY.md} "${agentWorkspaceDir}/IDENTITY.md" - install -m 0644 ${./SOUL.md} "${agentWorkspaceDir}/SOUL.md" - install -m 0644 ${./TOOLS.md} "${agentWorkspaceDir}/TOOLS.md" - install -m 0644 ${./USER.md} "${agentWorkspaceDir}/USER.md" + install -m 0644 ${./agent/AGENTS.md} "${agentWorkspaceDir}/AGENTS.md" + install -m 0644 ${./agent/IDENTITY.md} "${agentWorkspaceDir}/IDENTITY.md" + install -m 0644 ${./agent/SOUL.md} "${agentWorkspaceDir}/SOUL.md" + install -m 0644 ${./agent/TOOLS.md} "${agentWorkspaceDir}/TOOLS.md" + install -m 0644 ${./agent/USER.md} "${agentWorkspaceDir}/USER.md" ''; script = '' zeroclaw daemon