Rename clawdis to clawdbot everywhere

This commit is contained in:
DJTBOT 2026-01-04 13:00:10 +01:00
parent 82ee44aea4
commit 97127c98fe
17 changed files with 197 additions and 197 deletions

View File

@ -64,7 +64,7 @@ What I need you to do:
1. Check if Determinate Nix is installed (if not, install it)
2. Create a local flake at ~/code/clawdbot-local using templates/agent-first/flake.nix
3. Create a docs dir next to the config (e.g., ~/code/clawdbot-local/documents) with AGENTS.md, SOUL.md, TOOLS.md
- If ~/.clawdis/workspace already has these files, adopt them into the documents dir first
- If ~/.clawdbot/workspace already has these files, adopt them into the documents dir first
3. Help me create a Telegram bot (@BotFather) and get my chat ID (@userinfobot)
4. Set up secrets (bot token, Anthropic key) - plain files at ~/.secrets/ is fine
5. Fill in the template placeholders and run home-manager switch
@ -85,7 +85,7 @@ Use this for the simplest setup. For richer config (pergroup overrides), use
```nix
{
programs.clawdis = {
programs.clawdbot = {
enable = true;
providers.telegram = {
enable = true;
@ -109,20 +109,20 @@ Then: `home-manager switch --flake .#youruser`
## Small but useful config (sensible defaults)
This is still singleinstance, but uses `instances.default` to unlock pergroup mention rules.
If `instances` is set, you dont need `programs.clawdis.enable`.
If `instances` is set, you dont need `programs.clawdbot.enable`.
Group mention overrides below mirror upstream Clawdbot config.
Secrets are shown using `/run/agenix/...` (from a repo with your agenix secrets), but any file path works.
Docs are managed from `./documents` and symlinked into the workspace on each switch.
```nix
{
programs.clawdis = {
programs.clawdbot = {
documents = ./documents;
instances.default = {
enable = true;
package = pkgs.clawdis; # batteries-included
stateDir = "~/.clawdis";
workspaceDir = "~/.clawdis/workspace";
package = pkgs.clawdbot; # batteries-included
stateDir = "~/.clawdbot";
workspaceDir = "~/.clawdbot/workspace";
providers.telegram = {
enable = true;
@ -190,7 +190,7 @@ let
prod = {
enable = true;
# Prod gateway pin (comes from nix-clawdbot input @ v0.1.0 above).
package = inputs.nix-clawdbot.packages.${pkgs.system}.clawdis-gateway;
package = inputs.nix-clawdbot.packages.${pkgs.system}.clawdbot-gateway;
providers.telegram.enable = true;
providers.telegram.botTokenFile = "/run/agenix/telegram-prod";
providers.telegram.allowFrom = [ 12345678 ];
@ -199,10 +199,10 @@ let
};
in {
# Pinned macOS app (POC: no local app builds, uses nix-clawdbot @ v0.1.0 above).
programs.clawdis.appPackage =
inputs.nix-clawdbot.packages.${pkgs.system}.clawdis-app;
programs.clawdis.documents = ./documents;
programs.clawdis.instances = {
programs.clawdbot.appPackage =
inputs.nix-clawdbot.packages.${pkgs.system}.clawdbot-app;
programs.clawdbot.documents = ./documents;
programs.clawdbot.instances = {
prod = prod;
dev = prod // {
# Dev uses the same pinned macOS app (from nix-clawdbot input),
@ -247,7 +247,7 @@ your-plugin/
Example implementation: `examples/hello-world-plugin`.
**`flake.nix` (minimal `clawdisPlugin`):**
**`flake.nix` (minimal `clawdbotPlugin`):**
```nix
{
@ -255,7 +255,7 @@ Example implementation: `examples/hello-world-plugin`.
let
pkgs = import nixpkgs { system = builtins.currentSystem; };
in {
clawdisPlugin = {
clawdbotPlugin = {
name = "hello-world";
skills = [ ./skills/hello-world ];
packages = [ pkgs.hello ]; # example CLI
@ -289,14 +289,14 @@ perplugin `config`.
Goal: Make this repo a nixclawdbotnative plugin with the standard contract.
Contract to implement:
1) Add clawdisPlugin output in flake.nix:
1) Add clawdbotPlugin output in flake.nix:
- name
- skills (paths to SKILL.md dirs)
- packages (CLI packages to put on PATH)
- needs (stateDirs + requiredEnv)
Example:
clawdisPlugin = {
clawdbotPlugin = {
name = "my-plugin";
skills = [ ./skills/my-plugin ];
packages = [ self.packages.${system}.default ];
@ -351,8 +351,8 @@ Deliverables: flake output, env overrides, AGENTS.md, skill update.
## How it wires up
- Nix pulls the plugin, reads `clawdisPlugin`, and installs the CLI(s).
- Skills are symlinked into `~/.clawdis/skills/<plugin>/<skill>`.
- Nix pulls the plugin, reads `clawdbotPlugin`, and installs the CLI(s).
- Skills are symlinked into `~/.clawdbot/skills/<plugin>/<skill>`.
- Clawdbot loads managed skills automatically at runtime.
- Any plugin services run as **userlevel** launchd agents (no sudo).
- MVP scope: tools/skills should come **from plugins only** (no adhoc installs).
@ -360,8 +360,8 @@ Deliverables: flake output, env overrides, AGENTS.md, skill update.
## What you get
- Launchd keeps the gateway alive (`com.steipete.clawdis.gateway`)
- Logs at `/tmp/clawdis/clawdis-gateway.log`
- Launchd keeps the gateway alive (`com.steipete.clawdbot.gateway`)
- Logs at `/tmp/clawdbot/clawdbot-gateway.log`
- Message your bot in Telegram, get a response
- All the tools: whisper, spotify_player, camsnap, peekaboo, and more
@ -381,9 +381,9 @@ Deliverables: flake output, env overrides, AGENTS.md, skill update.
| Package | Contents |
| --- | --- |
| `clawdis` (default) | Gateway + app + full toolchain |
| `clawdis-gateway` | Gateway CLI only |
| `clawdis-app` | macOS app only |
| `clawdbot` (default) | Gateway + app + full toolchain |
| `clawdbot-gateway` | Gateway CLI only |
| `clawdbot-app` | macOS app only |
## Plugin collisions (override policy)
@ -407,13 +407,13 @@ We should warn on collisions so its obvious.
```bash
# Check service
launchctl print gui/$UID/com.steipete.clawdis.gateway | grep state
launchctl print gui/$UID/com.steipete.clawdbot.gateway | grep state
# View logs
tail -50 /tmp/clawdis/clawdis-gateway.log
tail -50 /tmp/clawdbot/clawdbot-gateway.log
# Restart
launchctl kickstart -k gui/$UID/com.steipete.clawdis.gateway
launchctl kickstart -k gui/$UID/com.steipete.clawdbot.gateway
# Rollback
home-manager generations # list

View File

@ -61,19 +61,19 @@ Nongoals:
- **Package derivation**: builds Clawdbot gateway from a pinned source.
- **App bundle**: installs Clawdbot.app from a pinned DMG matching the gateway version.
- **Home Manager module**: declarative config, writes `~/.clawdis/clawdis.json`, manages services.
- **Home Manager module**: declarative config, writes `~/.clawdbot/clawdbot.json`, manages services.
- **Flake outputs**:
- `packages.<system>.clawdis` (default batteriesincluded bundle)
- `packages.<system>.clawdis-gateway`
- `packages.<system>.clawdis-app`
- `packages.<system>.clawdis-tools-base`
- `packages.<system>.clawdis-tools-extended`
- `homeManagerModules.clawdis`
- `darwinModules.clawdis` (if needed)
- `packages.<system>.clawdbot` (default batteriesincluded bundle)
- `packages.<system>.clawdbot-gateway`
- `packages.<system>.clawdbot-app`
- `packages.<system>.clawdbot-tools-base`
- `packages.<system>.clawdbot-tools-extended`
- `homeManagerModules.clawdbot`
- `darwinModules.clawdbot` (if needed)
## 5) Configuration model (public contract)
The Home Manager module is the public contract. It must expose a small, explicit option set (enable, token path, allowlist) and render a deterministic `~/.clawdis/clawdis.json`.
The Home Manager module is the public contract. It must expose a small, explicit option set (enable, token path, allowlist) and render a deterministic `~/.clawdbot/clawdbot.json`.
The design constraint: users should not have to write arbitrary JSON. The module is the supported configuration surface for v1.
@ -124,8 +124,8 @@ No changes to personal `nixos-config` are made in this repo; this is a plan only
This RFC is complete when:
- The repo is public with a clear README and agentfirst guide.
- Telegramfirst quickstart works on macOS with a real bot token.
- `nix run .#clawdis` installs gateway + app + tools.
- Launchd uses `com.steipete.clawdis.gateway` and logs to `/tmp/clawdis/clawdis-gateway.log`.
- `nix run .#clawdbot` installs gateway + app + tools.
- Launchd uses `com.steipete.clawdbot.gateway` and logs to `/tmp/clawdbot/clawdbot-gateway.log`.
- App runs in attachonly mode (does not spawn its own gateway).
- Smoke test: user sends a Telegram message in an allowlisted chat and receives a response.

View File

@ -3,5 +3,5 @@
This plugin is intentionally tiny.
Knobs
- CLAWDIS_USER (optional): name to greet
- CLAWDBOT_USER (optional): name to greet

View File

@ -22,7 +22,7 @@
drv = self.packages.${system}.default;
};
clawdisPlugin = {
clawdbotPlugin = {
name = "hello-world";
skills = [ ./skills/hello-world ];
packages = [ self.packages.${system}.default ];

View File

@ -1,3 +1,3 @@
module github.com/acme/hello-world-clawdis
module github.com/acme/hello-world-clawdbot
go 1.22

View File

@ -6,7 +6,7 @@ import (
)
func main() {
name := os.Getenv("CLAWDIS_USER")
name := os.Getenv("CLAWDBOT_USER")
if name == "" {
name = "human"
}

View File

@ -21,20 +21,20 @@
in
{
packages = {
clawdis-gateway = pkgs.clawdis-gateway;
clawdis-app = pkgs.clawdis-app;
clawdis = pkgs.clawdis;
clawdis-tools-base = pkgs.clawdis-tools-base;
clawdis-tools-extended = pkgs.clawdis-tools-extended;
default = pkgs.clawdis;
clawdbot-gateway = pkgs.clawdbot-gateway;
clawdbot-app = pkgs.clawdbot-app;
clawdbot = pkgs.clawdbot;
clawdbot-tools-base = pkgs.clawdbot-tools-base;
clawdbot-tools-extended = pkgs.clawdbot-tools-extended;
default = pkgs.clawdbot;
};
apps = {
clawdis = flake-utils.lib.mkApp { drv = pkgs.clawdis-gateway; };
clawdbot = flake-utils.lib.mkApp { drv = pkgs.clawdbot-gateway; };
};
checks = pkgs.lib.optionalAttrs pkgs.stdenv.isDarwin {
gateway = pkgs.clawdis-gateway;
gateway = pkgs.clawdbot-gateway;
};
devShells.default = pkgs.mkShell {
@ -47,7 +47,7 @@
}
) // {
overlays.default = overlay;
homeManagerModules.clawdis = import ./nix/modules/home-manager/clawdis.nix;
darwinModules.clawdis = import ./nix/modules/darwin/clawdis.nix;
homeManagerModules.clawdbot = import ./nix/modules/home-manager/clawdbot.nix;
darwinModules.clawdbot = import ./nix/modules/darwin/clawdbot.nix;
};
}

View File

@ -2,6 +2,6 @@
{
config = lib.mkIf (config ? home-manager) {
home-manager.sharedModules = [ ../home-manager/clawdis.nix ];
home-manager.sharedModules = [ ../home-manager/clawdbot.nix ];
};
}

View File

@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage: clawdbot-reload [test|prod|both]
Re-render Clawdbot config via Home Manager (no sudo) and restart gateway(s).
Defaults to: test
EOF
}
instance="${1:-test}"
case "$instance" in
test) labels=("com.steipete.clawdbot.gateway.nix-test") ;;
prod) labels=("com.steipete.clawdbot.gateway.nix") ;;
both) labels=("com.steipete.clawdbot.gateway.nix" "com.steipete.clawdbot.gateway.nix-test") ;;
-h|--help) usage; exit 0 ;;
*) usage; exit 1 ;;
esac
if command -v hm-apply >/dev/null 2>&1; then
hm-apply
elif [[ -n "${CLAWDBOT_RELOAD_HM_CMD:-}" ]]; then
eval "$CLAWDBOT_RELOAD_HM_CMD"
else
echo "[clawdbot-reload] no Home Manager command available." >&2
echo "[clawdbot-reload] install hm-apply or set CLAWDBOT_RELOAD_HM_CMD." >&2
exit 1
fi
for label in "${labels[@]}"; do
/bin/launchctl kickstart -k "gui/$UID/$label"
done

View File

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }:
let
cfg = config.programs.clawdis;
cfg = config.programs.clawdbot;
homeDir = config.home.homeDirectory;
appPackage = if cfg.appPackage != null then cfg.appPackage else cfg.package;
@ -33,53 +33,53 @@ let
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Enable this Clawdis instance.";
description = "Enable this Clawdbot instance.";
};
package = lib.mkOption {
type = lib.types.package;
default = cfg.package;
description = "Clawdis batteries-included package.";
description = "Clawdbot batteries-included package.";
};
stateDir = lib.mkOption {
type = lib.types.str;
default = if name == "default"
then "${homeDir}/.clawdis"
else "${homeDir}/.clawdis-${name}";
description = "State directory for this Clawdis instance (logs, sessions, config).";
then "${homeDir}/.clawdbot"
else "${homeDir}/.clawdbot-${name}";
description = "State directory for this Clawdbot instance (logs, sessions, config).";
};
workspaceDir = lib.mkOption {
type = lib.types.str;
default = "${config.stateDir}/workspace";
description = "Workspace directory for this Clawdis instance.";
description = "Workspace directory for this Clawdbot instance.";
};
configPath = lib.mkOption {
type = lib.types.str;
default = "${config.stateDir}/clawdis.json";
description = "Path to generated Clawdis config JSON.";
default = "${config.stateDir}/clawdbot.json";
description = "Path to generated Clawdbot config JSON.";
};
logPath = lib.mkOption {
type = lib.types.str;
default = if name == "default"
then "/tmp/clawdis/clawdis-gateway.log"
else "/tmp/clawdis/clawdis-gateway-${name}.log";
description = "Log path for this Clawdis gateway instance.";
then "/tmp/clawdbot/clawdbot-gateway.log"
else "/tmp/clawdbot/clawdbot-gateway-${name}.log";
description = "Log path for this Clawdbot gateway instance.";
};
gatewayPort = lib.mkOption {
type = lib.types.int;
default = 18789;
description = "Gateway port used by the Clawdis desktop app.";
description = "Gateway port used by the Clawdbot desktop app.";
};
gatewayPath = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Local path to Clawdis gateway source (dev only).";
description = "Local path to Clawdbot gateway source (dev only).";
};
gatewayPnpmDepsHash = lib.mkOption {
@ -165,27 +165,27 @@ let
launchd.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Run Clawdis gateway via launchd (macOS).";
description = "Run Clawdbot gateway via launchd (macOS).";
};
launchd.label = lib.mkOption {
type = lib.types.str;
default = if name == "default"
then "com.steipete.clawdis.gateway"
else "com.steipete.clawdis.gateway.${name}";
then "com.steipete.clawdbot.gateway"
else "com.steipete.clawdbot.gateway.${name}";
description = "launchd label for this instance.";
};
app.install.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Install Clawdis.app for this instance.";
description = "Install Clawdbot.app for this instance.";
};
app.install.path = lib.mkOption {
type = lib.types.str;
default = "${homeDir}/Applications/Clawdis.app";
description = "Destination path for this instance's Clawdis.app bundle.";
default = "${homeDir}/Applications/Clawdbot.app";
description = "Destination path for this instance's Clawdbot.app bundle.";
};
appDefaults = {
@ -205,7 +205,7 @@ let
configOverrides = lib.mkOption {
type = lib.types.attrs;
default = {};
description = "Additional Clawdis config to merge into the generated JSON.";
description = "Additional Clawdbot config to merge into the generated JSON.";
};
};
};
@ -215,8 +215,8 @@ let
package = cfg.package;
stateDir = cfg.stateDir;
workspaceDir = cfg.workspaceDir;
configPath = "${cfg.stateDir}/clawdis.json";
logPath = "/tmp/clawdis/clawdis-gateway.log";
configPath = "${cfg.stateDir}/clawdbot.json";
logPath = "/tmp/clawdbot/clawdbot-gateway.log";
gatewayPort = 18789;
providers = cfg.providers;
routing = cfg.routing;
@ -230,7 +230,7 @@ let
app = {
install = {
enable = false;
path = "${homeDir}/Applications/Clawdis.app";
path = "${homeDir}/Applications/Clawdbot.app";
};
};
};
@ -240,7 +240,7 @@ let
else lib.optionalAttrs cfg.enable { default = defaultInstance; };
enabledInstances = lib.filterAttrs (_: inst: inst.enable) instances;
managedSkillsDir = "${homeDir}/.clawdis/skills";
managedSkillsDir = "${homeDir}/.clawdbot/skills";
documentsEnabled = cfg.documents != null;
@ -261,19 +261,19 @@ let
documentsAssertions = lib.optionals documentsEnabled [
{
assertion = builtins.pathExists cfg.documents;
message = "programs.clawdis.documents must point to an existing directory.";
message = "programs.clawdbot.documents must point to an existing directory.";
}
{
assertion = builtins.pathExists (cfg.documents + "/AGENTS.md");
message = "Missing AGENTS.md in programs.clawdis.documents.";
message = "Missing AGENTS.md in programs.clawdbot.documents.";
}
{
assertion = builtins.pathExists (cfg.documents + "/SOUL.md");
message = "Missing SOUL.md in programs.clawdis.documents.";
message = "Missing SOUL.md in programs.clawdbot.documents.";
}
{
assertion = builtins.pathExists (cfg.documents + "/TOOLS.md");
message = "Missing TOOLS.md in programs.clawdis.documents.";
message = "Missing TOOLS.md in programs.clawdbot.documents.";
}
];
@ -282,7 +282,7 @@ let
let
guardLine = file: ''
if [ -e "${file}" ] && [ ! -L "${file}" ]; then
echo "Clawdis documents are managed by Nix. Please adopt ${file} into your documents directory and re-run." >&2
echo "Clawdbot documents are managed by Nix. Please adopt ${file} into your documents directory and re-run." >&2
exit 1
fi
'';
@ -325,13 +325,13 @@ let
];
reportText = lib.concatStringsSep "\n" reportLines;
in
pkgs.writeText "clawdis-tools-report.md" reportText
pkgs.writeText "clawdbot-tools-report.md" reportText
else
null;
toolsWithReport =
if documentsEnabled then
pkgs.runCommand "clawdis-tools-with-report.md" {} ''
pkgs.runCommand "clawdbot-tools-with-report.md" {} ''
cat ${cfg.documents + "/TOOLS.md"} > $out
echo "" >> $out
cat ${toolsReport} >> $out
@ -360,15 +360,15 @@ let
resolvePlugin = plugin: let
flake = builtins.getFlake plugin.source;
clawdisPlugin =
if flake ? clawdisPlugin then flake.clawdisPlugin
else throw "clawdisPlugin missing in ${plugin.source}";
needs = clawdisPlugin.needs or {};
clawdbotPlugin =
if flake ? clawdbotPlugin then flake.clawdbotPlugin
else throw "clawdbotPlugin missing in ${plugin.source}";
needs = clawdbotPlugin.needs or {};
in {
source = plugin.source;
name = clawdisPlugin.name or (throw "clawdisPlugin.name missing in ${plugin.source}");
skills = clawdisPlugin.skills or [];
packages = clawdisPlugin.packages or [];
name = clawdbotPlugin.name or (throw "clawdbotPlugin.name missing in ${plugin.source}");
skills = clawdbotPlugin.skills or [];
packages = clawdbotPlugin.packages or [];
needs = {
stateDirs = needs.stateDirs or [];
requiredEnv = needs.requiredEnv or [];
@ -390,7 +390,7 @@ let
if duplicates == []
then ordered
else lib.warn
"programs.clawdis.instances.${instName}: duplicate plugin names detected (${lib.concatStringsSep ", " duplicates}); last entry wins."
"programs.clawdbot.instances.${instName}: duplicate plugin names detected (${lib.concatStringsSep ", " duplicates}); last entry wins."
ordered
) enabledInstances;
@ -437,11 +437,11 @@ let
let missing = missingFor p;
in {
assertion = missing == [];
message = "programs.clawdis.instances.${instName}: plugin ${p.name} missing required env: ${lib.concatStringsSep ", " missing}";
message = "programs.clawdbot.instances.${instName}: plugin ${p.name} missing required env: ${lib.concatStringsSep ", " missing}";
};
mkConfigAssertion = p: {
assertion = !(configMissingStateDir p);
message = "programs.clawdis.instances.${instName}: plugin ${p.name} provides settings but declares no stateDirs (needed for config.json).";
message = "programs.clawdbot.instances.${instName}: plugin ${p.name} provides settings but declares no stateDirs (needed for config.json).";
};
in
(map mkAssertion plugins) ++ (map mkConfigAssertion plugins)
@ -451,7 +451,7 @@ let
let
skillEntriesFor = p:
map (skillPath: {
name = ".clawdis/skills/${p.name}/${builtins.baseNameOf skillPath}";
name = ".clawdbot/skills/${p.name}/${builtins.baseNameOf skillPath}";
value = { source = skillPath; recursive = true; };
}) p.skills;
allEntries =
@ -513,7 +513,7 @@ let
lib.flatten (lib.concatLists (lib.mapAttrsToList (_: plugins:
map (p:
map (skillPath:
".clawdis/skills/${p.name}/${builtins.baseNameOf skillPath}"
".clawdbot/skills/${p.name}/${builtins.baseNameOf skillPath}"
) p.skills
) plugins
) resolvedPluginsByInstance));
@ -531,10 +531,10 @@ let
mkInstanceConfig = name: inst: let
gatewayPackage =
if inst.gatewayPath != null then
pkgs.callPackage ../../packages/clawdis-gateway.nix {
pkgs.callPackage ../../packages/clawdbot-gateway.nix {
gatewaySrc = builtins.path {
path = inst.gatewayPath;
name = "clawdis-gateway-src";
name = "clawdbot-gateway-src";
};
pnpmDepsHash = inst.gatewayPnpmDepsHash;
}
@ -547,7 +547,7 @@ let
(lib.recursiveUpdate baseConfig (lib.recursiveUpdate (mkTelegramConfig inst) (mkRoutingConfig inst)))
inst.configOverrides;
configJson = builtins.toJSON mergedConfig;
gatewayWrapper = pkgs.writeShellScriptBin "clawdis-gateway-${name}" ''
gatewayWrapper = pkgs.writeShellScriptBin "clawdbot-gateway-${name}" ''
set -euo pipefail
if [ "${toString (pluginPackages != [])}" = "true" ]; then
@ -569,7 +569,7 @@ let
export ANTHROPIC_API_KEY
fi
exec "${gatewayPackage}/bin/clawdis" "$@"
exec "${gatewayPackage}/bin/clawdbot" "$@"
'';
in {
homeFile = {
@ -585,7 +585,7 @@ let
config = {
Label = inst.launchd.label;
ProgramArguments = [
"${gatewayWrapper}/bin/clawdis-gateway-${name}"
"${gatewayWrapper}/bin/clawdbot-gateway-${name}"
"gateway"
"--port"
"${toString inst.gatewayPort}"
@ -597,10 +597,10 @@ let
StandardErrorPath = inst.logPath;
EnvironmentVariables = {
HOME = homeDir;
CLAWDIS_CONFIG_PATH = inst.configPath;
CLAWDIS_STATE_DIR = inst.stateDir;
CLAWDIS_IMAGE_BACKEND = "sips";
CLAWDIS_NIX_MODE = "1";
CLAWDBOT_CONFIG_PATH = inst.configPath;
CLAWDBOT_STATE_DIR = inst.stateDir;
CLAWDBOT_IMAGE_BACKEND = "sips";
CLAWDBOT_NIX_MODE = "1";
};
};
};
@ -616,7 +616,7 @@ let
else {
name = lib.removePrefix "${homeDir}/" inst.app.install.path;
value = {
source = "${appPackage}/Applications/Clawdis.app";
source = "${appPackage}/Applications/Clawdbot.app";
recursive = true;
force = true;
};
@ -636,46 +636,46 @@ let
assertions = lib.flatten (lib.mapAttrsToList (name: inst: [
{
assertion = !inst.providers.telegram.enable || inst.providers.telegram.botTokenFile != "";
message = "programs.clawdis.instances.${name}.providers.telegram.botTokenFile must be set when Telegram is enabled.";
message = "programs.clawdbot.instances.${name}.providers.telegram.botTokenFile must be set when Telegram is enabled.";
}
{
assertion = !inst.providers.telegram.enable || (lib.length inst.providers.telegram.allowFrom > 0);
message = "programs.clawdis.instances.${name}.providers.telegram.allowFrom must be non-empty when Telegram is enabled.";
message = "programs.clawdbot.instances.${name}.providers.telegram.allowFrom must be non-empty when Telegram is enabled.";
}
]) enabledInstances);
in {
options.programs.clawdis = {
enable = lib.mkEnableOption "Clawdis (batteries-included)";
options.programs.clawdbot = {
enable = lib.mkEnableOption "Clawdbot (batteries-included)";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.clawdis;
description = "Clawdis batteries-included package.";
default = pkgs.clawdbot;
description = "Clawdbot batteries-included package.";
};
appPackage = lib.mkOption {
type = lib.types.nullOr lib.types.package;
default = null;
description = "Optional Clawdis app package (defaults to package if unset).";
description = "Optional Clawdbot app package (defaults to package if unset).";
};
installApp = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Install Clawdis.app at the default location.";
description = "Install Clawdbot.app at the default location.";
};
stateDir = lib.mkOption {
type = lib.types.str;
default = "${homeDir}/.clawdis";
description = "State directory for Clawdis (logs, sessions, config).";
default = "${homeDir}/.clawdbot";
description = "State directory for Clawdbot (logs, sessions, config).";
};
workspaceDir = lib.mkOption {
type = lib.types.str;
default = "${homeDir}/.clawdis/workspace";
description = "Workspace directory for Clawdis agent skills.";
default = "${homeDir}/.clawdbot/workspace";
description = "Workspace directory for Clawdbot agent skills.";
};
documents = lib.mkOption {
@ -754,20 +754,20 @@ in {
launchd.enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Run Clawdis gateway via launchd (macOS).";
description = "Run Clawdbot gateway via launchd (macOS).";
};
instances = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule instanceModule);
default = {};
description = "Named Clawdis instances (prod/test).";
description = "Named Clawdbot instances (prod/test).";
};
reloadScript = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Install clawdis-reload helper for no-sudo config refresh + gateway restart.";
description = "Install clawdbot-reload helper for no-sudo config refresh + gateway restart.";
};
};
};
@ -776,7 +776,7 @@ in {
assertions = assertions ++ [
{
assertion = lib.length (lib.attrNames appDefaultsEnabled) <= 1;
message = "Only one Clawdis instance may enable appDefaults.";
message = "Only one Clawdbot instance may enable appDefaults.";
}
] ++ documentsAssertions ++ pluginAssertions ++ pluginSkillAssertions;
@ -785,8 +785,8 @@ in {
home.file =
(lib.listToAttrs (map (item: item.homeFile) instanceConfigs))
// (lib.optionalAttrs (pkgs.stdenv.hostPlatform.isDarwin && appPackage != null && cfg.installApp) {
"Applications/Clawdis.app" = {
source = "${appPackage}/Applications/Clawdis.app";
"Applications/Clawdbot.app" = {
source = "${appPackage}/Applications/Clawdbot.app";
recursive = true;
force = true;
};
@ -796,33 +796,33 @@ in {
// pluginSkillsFiles
// pluginConfigFiles
// (lib.optionalAttrs cfg.reloadScript.enable {
".local/bin/clawdis-reload" = {
".local/bin/clawdbot-reload" = {
executable = true;
source = ./clawdis-reload.sh;
source = ./clawdbot-reload.sh;
};
});
home.activation.clawdisDocumentGuard = lib.mkIf documentsEnabled (
home.activation.clawdbotDocumentGuard = lib.mkIf documentsEnabled (
lib.hm.dag.entryBefore [ "writeBoundary" ] ''
set -euo pipefail
${documentsGuard}
''
);
home.activation.clawdisDirs = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
home.activation.clawdbotDirs = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
/bin/mkdir -p ${lib.concatStringsSep " " (lib.concatMap (item: item.dirs) instanceConfigs)}
${lib.optionalString (pluginStateDirsAll != []) "/bin/mkdir -p ${lib.concatStringsSep " " pluginStateDirsAll}"}
'';
home.activation.clawdisPluginGuard = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
home.activation.clawdbotPluginGuard = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
set -euo pipefail
${pluginGuards}
'';
home.activation.clawdisAppDefaults = lib.mkIf (pkgs.stdenv.hostPlatform.isDarwin && appDefaults != {}) (
home.activation.clawdbotAppDefaults = lib.mkIf (pkgs.stdenv.hostPlatform.isDarwin && appDefaults != {}) (
lib.hm.dag.entryAfter [ "writeBoundary" ] ''
/usr/bin/defaults write com.steipete.Clawdis clawdis.gateway.attachExistingOnly -bool ${lib.boolToString (appDefaults.attachExistingOnly or true)}
/usr/bin/defaults write com.steipete.Clawdis gatewayPort -int ${toString (appDefaults.gatewayPort or 18789)}
/usr/bin/defaults write com.steipete.Clawdbot clawdbot.gateway.attachExistingOnly -bool ${lib.boolToString (appDefaults.attachExistingOnly or true)}
/usr/bin/defaults write com.steipete.Clawdbot gatewayPort -int ${toString (appDefaults.gatewayPort or 18789)}
''
);

View File

@ -1,36 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage: clawdis-reload [test|prod|both]
Re-render Clawdis config via Home Manager (no sudo) and restart gateway(s).
Defaults to: test
EOF
}
instance="${1:-test}"
case "$instance" in
test) labels=("com.steipete.clawdis.gateway.nix-test") ;;
prod) labels=("com.steipete.clawdis.gateway.nix") ;;
both) labels=("com.steipete.clawdis.gateway.nix" "com.steipete.clawdis.gateway.nix-test") ;;
-h|--help) usage; exit 0 ;;
*) usage; exit 1 ;;
esac
if command -v hm-apply >/dev/null 2>&1; then
hm-apply
elif [[ -n "${CLAWDIS_RELOAD_HM_CMD:-}" ]]; then
eval "$CLAWDIS_RELOAD_HM_CMD"
else
echo "[clawdis-reload] no Home Manager command available." >&2
echo "[clawdis-reload] install hm-apply or set CLAWDIS_RELOAD_HM_CMD." >&2
exit 1
fi
for label in "${labels[@]}"; do
/bin/launchctl kickstart -k "gui/$UID/$label"
done

View File

@ -1,20 +1,20 @@
self: super:
let
sourceInfo = import ./sources/clawdis-source.nix;
clawdisGateway = super.callPackage ./packages/clawdis-gateway.nix {
sourceInfo = import ./sources/clawdbot-source.nix;
clawdbotGateway = super.callPackage ./packages/clawdbot-gateway.nix {
inherit sourceInfo;
};
clawdisApp = super.callPackage ./packages/clawdis-app.nix { };
clawdbotApp = super.callPackage ./packages/clawdbot-app.nix { };
toolSets = import ./tools/extended.nix { pkgs = super; };
clawdisBundle = super.callPackage ./packages/clawdis-batteries.nix {
clawdis-gateway = clawdisGateway;
clawdis-app = clawdisApp;
clawdbotBundle = super.callPackage ./packages/clawdbot-batteries.nix {
clawdbot-gateway = clawdbotGateway;
clawdbot-app = clawdbotApp;
extendedTools = toolSets.base;
};
in {
clawdis-gateway = clawdisGateway;
clawdis-app = clawdisApp;
clawdis = clawdisBundle;
clawdis-tools-base = toolSets.base;
clawdis-tools-extended = toolSets.extended;
clawdbot-gateway = clawdbotGateway;
clawdbot-app = clawdbotApp;
clawdbot = clawdbotBundle;
clawdbot-tools-base = toolSets.base;
clawdbot-tools-extended = toolSets.extended;
}

View File

@ -4,11 +4,11 @@
}:
stdenvNoCC.mkDerivation {
pname = "clawdis-app";
pname = "clawdbot-app";
version = "2.0.0-beta4";
src = fetchzip {
url = "https://github.com/clawdbot/clawdbot/releases/download/v2.0.0-beta4/Clawdis-2.0.0-beta4.zip";
url = "https://github.com/clawdbot/clawdbot/releases/download/v2.0.0-beta4/Clawdbot-2.0.0-beta4.zip";
hash = "sha256-Oa7cejVFfZtJBSmjDaRjqocVyXo+WeS/xucGpJFDzIg=";
stripRoot = false;
};
@ -18,12 +18,12 @@ stdenvNoCC.mkDerivation {
installPhase = ''
runHook preInstall
mkdir -p $out/Applications
app_path="$(find "$src" -maxdepth 2 -name 'Clawdis.app' -print -quit)"
app_path="$(find "$src" -maxdepth 2 -name 'Clawdbot.app' -print -quit)"
if [ -z "$app_path" ]; then
echo "Clawdis.app not found in $src" >&2
echo "Clawdbot.app not found in $src" >&2
exit 1
fi
cp -R "$app_path" "$out/Applications/Clawdis.app"
cp -R "$app_path" "$out/Applications/Clawdbot.app"
runHook postInstall
'';

View File

@ -1,13 +1,13 @@
{ lib
, buildEnv
, clawdis-gateway
, clawdis-app
, clawdbot-gateway
, clawdbot-app
, extendedTools
}:
buildEnv {
name = "clawdis-2.0.0-beta4";
paths = [ clawdis-gateway clawdis-app ] ++ extendedTools;
name = "clawdbot-2.0.0-beta4";
paths = [ clawdbot-gateway clawdbot-app ] ++ extendedTools;
pathsToLink = [ "/bin" "/Applications" ];
meta = with lib; {

View File

@ -15,7 +15,7 @@
assert gatewaySrc == null || pnpmDepsHash != null;
stdenv.mkDerivation (finalAttrs: {
pname = "clawdis-gateway";
pname = "clawdbot-gateway";
version = "2.0.0-beta4";
src = if gatewaySrc != null then gatewaySrc else fetchFromGitHub sourceInfo;
@ -53,13 +53,13 @@ stdenv.mkDerivation (finalAttrs: {
installPhase = ''
runHook preInstall
mkdir -p $out/lib/clawdis $out/bin
mkdir -p $out/lib/clawdbot $out/bin
cp -r dist node_modules package.json ui $out/lib/clawdis/
cp -r dist node_modules package.json ui $out/lib/clawdbot/
makeWrapper ${nodejs_22}/bin/node $out/bin/clawdis \
--add-flags "$out/lib/clawdis/dist/index.js" \
--set-default CLAWDIS_NIX_MODE "1"
makeWrapper ${nodejs_22}/bin/node $out/bin/clawdbot \
--add-flags "$out/lib/clawdbot/dist/index.js" \
--set-default CLAWDBOT_NIX_MODE "1"
runHook postInstall
'';
@ -69,6 +69,6 @@ stdenv.mkDerivation (finalAttrs: {
homepage = "https://github.com/clawdbot/clawdbot";
license = licenses.mit;
platforms = platforms.darwin;
mainProgram = "clawdis";
mainProgram = "clawdbot";
};
})

View File

@ -18,7 +18,7 @@
homeConfigurations."<user>" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
nix-clawdbot.homeManagerModules.clawdis
nix-clawdbot.homeManagerModules.clawdbot
{
# Required for Home Manager standalone
home.username = "<user>";
@ -26,7 +26,7 @@
home.stateVersion = "24.11";
programs.home-manager.enable = true;
programs.clawdis = {
programs.clawdbot = {
# REPLACE: path to your managed documents directory
documents = ./documents;
instances.default = {