Skip to content
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
let
overlay = import ./nix/overlay.nix;
sourceInfoStable = import ./nix/sources/clawdbot-source.nix;
systems = [ "x86_64-linux" "aarch64-darwin" ];
systems = [ "x86_64-linux" "aarch64-linux" "aarch64-darwin" ];
in
flake-utils.lib.eachSystem systems (system:
let
Expand Down
40 changes: 22 additions & 18 deletions nix/modules/home-manager/clawdbot.nix
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let
};

mkTelegramConfig = inst: lib.optionalAttrs inst.providers.telegram.enable {
telegram = {
channels.telegram = {
enabled = true;
tokenFile = inst.providers.telegram.botTokenFile;
allowFrom = inst.providers.telegram.allowFrom;
Expand All @@ -48,7 +48,7 @@ let
messages = {
queue = {
mode = inst.routing.queue.mode;
byProvider = inst.routing.queue.byProvider;
byChannel = inst.routing.queue.byChannel;
};
};
};
Expand Down Expand Up @@ -211,14 +211,14 @@ let
description = "Queue mode when a run is active.";
};

byProvider = lib.mkOption {
byChannel = lib.mkOption {
type = lib.types.attrs;
default = {
telegram = "interrupt";
discord = "queue";
webchat = "queue";
};
description = "Per-provider queue mode overrides.";
description = "Per-channel queue mode overrides.";
};
};

Expand Down Expand Up @@ -300,13 +300,19 @@ let
configPath = "${cfg.stateDir}/clawdbot.json";
logPath = "/tmp/clawdbot/clawdbot-gateway.log";
gatewayPort = 18789;
gatewayPath = null;
gatewayPnpmDepsHash = lib.fakeHash;
providers = cfg.providers;
routing = cfg.routing;
launchd = cfg.launchd;
systemd = cfg.systemd;
plugins = cfg.plugins;
configOverrides = {};
config = {};
agent = {
model = cfg.defaults.model;
thinkingDefault = cfg.defaults.thinkingDefault;
};
appDefaults = {
enable = true;
attachExistingOnly = true;
Expand Down Expand Up @@ -807,20 +813,20 @@ let
};
Service = {
ExecStart = "${gatewayWrapper}/bin/clawdbot-gateway-${name} gateway --port ${toString inst.gatewayPort}";
WorkingDirectory = inst.stateDir;
WorkingDirectory = resolvePath inst.stateDir;
Restart = "always";
RestartSec = "1s";
Environment = [
"HOME=${homeDir}"
"CLAWDBOT_CONFIG_PATH=${inst.configPath}"
"CLAWDBOT_STATE_DIR=${inst.stateDir}"
"CLAWDBOT_CONFIG_PATH=${resolvePath inst.configPath}"
"CLAWDBOT_STATE_DIR=${resolvePath inst.stateDir}"
"CLAWDBOT_NIX_MODE=1"
"CLAWDIS_CONFIG_PATH=${inst.configPath}"
"CLAWDIS_STATE_DIR=${inst.stateDir}"
"CLAWDIS_CONFIG_PATH=${resolvePath inst.configPath}"
"CLAWDIS_STATE_DIR=${resolvePath inst.stateDir}"
"CLAWDIS_NIX_MODE=1"
];
StandardOutput = "append:${inst.logPath}";
StandardError = "append:${inst.logPath}";
StandardOutput = "append:${resolvePath inst.logPath}";
StandardError = "append:${resolvePath inst.logPath}";
};
Install = {
WantedBy = [ "default.target" ];
Expand Down Expand Up @@ -1083,18 +1089,17 @@ in {
description = "Queue mode when a run is active.";
};

byProvider = lib.mkOption {
byChannel = lib.mkOption {
type = lib.types.attrs;
default = {
telegram = "interrupt";
discord = "queue";
webchat = "queue";
};
description = "Per-provider queue mode overrides.";
description = "Per-channel queue mode overrides.";
};
};


launchd.enable = lib.mkOption {
type = lib.types.bool;
default = true;
Expand Down Expand Up @@ -1176,13 +1181,12 @@ in {
);

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}"}
run mkdir -p ${lib.concatStringsSep " " (lib.concatMap (item: item.dirs) instanceConfigs)}
${lib.optionalString (pluginStateDirsAll != []) "run mkdir -p ${lib.concatStringsSep " " pluginStateDirsAll}"}
'';

home.activation.clawdbotConfigFiles = lib.hm.dag.entryAfter [ "clawdbotDirs" ] ''
set -euo pipefail
${lib.concatStringsSep "\n" (map (item: "/bin/ln -sfn ${item.configFile} ${item.configPath}") instanceConfigs)}
${lib.concatStringsSep "\n" (map (item: "run ln -sfn ${item.configFile} ${item.configPath}") instanceConfigs)}
'';

home.activation.clawdbotPluginGuard = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
Expand Down
16 changes: 16 additions & 0 deletions nix/scripts/gateway-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@
set -e
mkdir -p "$out/lib/clawdbot" "$out/bin"

# Copy core files and bundled extensions (memory-core, etc.)
cp -r dist node_modules package.json ui "$out/lib/clawdbot/"
# Copy docs (includes workspace templates like AGENTS.md)
if [ -d "docs" ]; then
cp -r docs "$out/lib/clawdbot/"
fi
if [ -d "extensions" ]; then
cp -r extensions "$out/lib/clawdbot/"
fi

if [ -z "${STDENV_SETUP:-}" ]; then
echo "STDENV_SETUP is not set" >&2
Expand All @@ -17,6 +25,14 @@ bash -e -c '. "$STDENV_SETUP"; patchShebangs "$out/lib/clawdbot/node_modules/.bi
if [ -d "$out/lib/clawdbot/ui/node_modules/.bin" ]; then
bash -e -c '. "$STDENV_SETUP"; patchShebangs "$out/lib/clawdbot/ui/node_modules/.bin"'
fi
# Patch shebangs in extensions node_modules if present
if [ -d "$out/lib/clawdbot/extensions" ]; then
for ext_bin in "$out/lib/clawdbot/extensions"/*/node_modules/.bin; do
if [ -d "$ext_bin" ]; then
bash -e -c '. "$STDENV_SETUP"; patchShebangs "'"$ext_bin"'"'
fi
done
fi

# Work around missing dependency declaration in pi-coding-agent (strip-ansi).
# Ensure it is resolvable at runtime without changing upstream.
Expand Down
16 changes: 15 additions & 1 deletion scripts/update-pins.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,18 @@ if [[ -z "$release_tag" ]]; then
fi
log "Latest app release tag with asset: $release_tag"

# Update version strings in gateway package and check derivations
gateway_version="${release_tag#v}"
log "Updating gateway version to: $gateway_version"

gateway_file="$repo_root/nix/packages/clawdbot-gateway.nix"
tests_file="$repo_root/nix/checks/clawdbot-gateway-tests.nix"
options_file="$repo_root/nix/checks/clawdbot-config-options.nix"

perl -0pi -e "s|version = \"[^\"]+\";|version = \"${gateway_version}\";|" "$gateway_file"
perl -0pi -e "s|version = \"[^\"]+\";|version = \"${gateway_version}\";|" "$tests_file"
perl -0pi -e "s|version = \"[^\"]+\";|version = \"${gateway_version}\";|" "$options_file"

app_url=$(printf '%s' "$release_json" | jq -r '[.[] | select([.assets[]?.name | (test("^(Clawdbot|Clawdis)-.*\\.zip$") and (test("dSYM") | not))] | any)][0].assets[] | select(.name | (test("^(Clawdbot|Clawdis)-.*\\.zip$") and (test("dSYM") | not))) | .browser_download_url' | head -n 1 || true)
if [[ -z "$app_url" ]]; then
echo "Failed to resolve Clawdbot app asset URL from latest release" >&2
Expand Down Expand Up @@ -227,14 +239,16 @@ if git diff --quiet; then
fi

log "Committing updated pins"
git add "$source_file" "$app_file" "$repo_root/nix/generated/clawdbot-config-options.nix"
git add "$source_file" "$app_file" "$gateway_file" "$tests_file" "$options_file" \
"$repo_root/nix/generated/clawdbot-config-options.nix"
git commit -F - <<'EOF'
🤖 codex: bump clawdbot pins (no-issue)

What:
- pin clawdbot source to latest upstream main
- refresh macOS app pin to latest release asset
- update source and app hashes
- update version strings in gateway and check derivations
- regenerate config options from upstream schema

Why:
Expand Down