Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/codex/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ notify = [
"notify",
]

suppress_unstable_features_warning = true
web_search = "cached"

[features]
Expand Down
12 changes: 7 additions & 5 deletions config/codex/default.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{ config, ... }:
{ config, lib, ... }:
{
home.file.".codex/config.toml" = {
source = ./config.toml;
force = true;
};
# Use activation script instead of home.file symlink
# Codex CLI uses atomic writes that break symlinks, so we force-copy on each switch
home.activation.codexConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
$DRY_RUN_CMD cp -f ${./config.toml} ~/.codex/config.toml

@cubic-dev-ai cubic-dev-ai Bot Feb 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Activation script copies to ~/.codex/config.toml without ensuring ~/.codex exists, so on a clean install the activation will fail after removing home.file which previously created the directory.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/codex/default.nix, line 6:

<comment>Activation script copies to ~/.codex/config.toml without ensuring ~/.codex exists, so on a clean install the activation will fail after removing home.file which previously created the directory.</comment>

<file context>
@@ -1,7 +1,9 @@
+  # Use activation script instead of home.file symlink
+  # Codex CLI uses atomic writes that break symlinks, so we force-copy on each switch
+  home.activation.codexConfig = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
+    $DRY_RUN_CMD cp -f ${./config.toml} ~/.codex/config.toml
+    $DRY_RUN_CMD chmod 600 ~/.codex/config.toml
+  '';
</file context>
Suggested change
$DRY_RUN_CMD cp -f ${./config.toml} ~/.codex/config.toml
$DRY_RUN_CMD mkdir -p ~/.codex
$DRY_RUN_CMD cp -f ${./config.toml} ~/.codex/config.toml
Fix with Cubic

$DRY_RUN_CMD chmod 600 ~/.codex/config.toml
Comment on lines +6 to +7

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tilde (~) expansion may not work reliably in all contexts. Consider using '${config.home.homeDirectory}/.codex/config.toml' instead for consistency with other parts of the codebase.

Suggested change
$DRY_RUN_CMD cp -f ${./config.toml} ~/.codex/config.toml
$DRY_RUN_CMD chmod 600 ~/.codex/config.toml
$DRY_RUN_CMD cp -f ${./config.toml} ${config.home.homeDirectory}/.codex/config.toml
$DRY_RUN_CMD chmod 600 ${config.home.homeDirectory}/.codex/config.toml

Copilot uses AI. Check for mistakes.
'';
}
1 change: 1 addition & 0 deletions config/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
./k3s
./karabiner
./llm
./openclaw

@cubic-dev-ai cubic-dev-ai Bot Feb 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new module import ./openclaw points to a path that does not exist in the repository, which will cause Nix evaluation to fail with a missing path error.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/default.nix, line 19:

<comment>The new module import `./openclaw` points to a path that does not exist in the repository, which will cause Nix evaluation to fail with a missing path error.</comment>

<file context>
@@ -16,6 +16,7 @@
   ./k3s
   ./karabiner
   ./llm
+  ./openclaw
   ./opencode
   ./pi
</file context>
Fix with Cubic

./opencode
./pi
./serena
Expand Down
33 changes: 33 additions & 0 deletions config/openclaw/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
inputs,
...
}:
let
inherit (inputs) host;
homeDir = config.home.homeDirectory;

mode = if host.isKyber then "gateway" else "client";

hydrateScript = pkgs.replaceVars ./hydrate.sh ({
sed = "${pkgs.gnused}/bin/sed";
template = ./openclaw.template.json;
inherit mode;
} // (if host.isKyber then {
chromium = pkgs.chromium;
openclaw = "${homeDir}/.bun";
} else {
chromium = "/unused";
openclaw = "/unused";
Comment on lines +22 to +23

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using '/unused' as placeholder values could cause confusion or issues if these paths are accidentally referenced. Consider using more explicit placeholder values like 'null' or empty strings, or restructure the code to only define these variables when host.isKyber is true.

Suggested change
chromium = "/unused";
openclaw = "/unused";
chromium = "";
openclaw = "";

Copilot uses AI. Check for mistakes.
}));
in
{
# Hydrate OpenClaw config from .env secrets
# Gateway mode on Kyber, client mode everywhere else
home.activation.hydrateOpenclawConfig = config.lib.dag.entryAfter [ "writeBoundary" ] ''
mkdir -p ${homeDir}/.openclaw
${pkgs.bash}/bin/bash ${hydrateScript} || true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The || true at the end of the bash command can mask potential failures during the OpenClaw configuration hydration. If the hydrateScript fails for any reason, the NixOS activation will still report success, potentially leading to a silently misconfigured OpenClaw. It's generally better to let the activation fail if a critical setup script fails, so the user is immediately aware of the problem.

    ${pkgs.bash}/bin/bash ${hydrateScript}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

The || true here will silently swallow all errors from the hydration script, including legitimate failures like permission errors or invalid config generation. Combined with line 36 in hydrate.sh that does exit 0 on missing GATEWAY_TOKEN, this creates a double-silent failure mode.

Consider removing the || true and handling specific expected failure cases in the script with appropriate exit codes, or at minimum log failures to a persistent location.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#712
File: config/openclaw/default.nix#L31
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
The `|| true` here will silently swallow all errors from the hydration script, including legitimate failures like permission errors or invalid config generation. Combined with line 36 in hydrate.sh that does `exit 0` on missing GATEWAY_TOKEN, this creates a double-silent failure mode.

Consider removing the `|| true` and handling specific expected failure cases in the script with appropriate exit codes, or at minimum log failures to a persistent location.

@cubic-dev-ai cubic-dev-ai Bot Feb 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The || true suffix will silently swallow all errors from the hydration script, including legitimate failures like permission errors or invalid config generation. Consider removing || true and handling specific expected failure cases in the script with appropriate exit codes, or at minimum log failures to a persistent location for debugging.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/openclaw/default.nix, line 31:

<comment>The `|| true` suffix will silently swallow all errors from the hydration script, including legitimate failures like permission errors or invalid config generation. Consider removing `|| true` and handling specific expected failure cases in the script with appropriate exit codes, or at minimum log failures to a persistent location for debugging.</comment>

<file context>
@@ -0,0 +1,33 @@
+  # Gateway mode on Kyber, client mode everywhere else
+  home.activation.hydrateOpenclawConfig = config.lib.dag.entryAfter [ "writeBoundary" ] ''
+    mkdir -p ${homeDir}/.openclaw
+    ${pkgs.bash}/bin/bash ${hydrateScript} || true
+  '';
+}
</file context>
Fix with Cubic

'';
}
71 changes: 46 additions & 25 deletions config/openclaw/hydrate.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env bash
# OpenClaw gateway start script with runtime secret injection
# OpenClaw config hydration with runtime secret injection
# Mode is set by nix: "gateway" for Kyber, "client" for macOS
# shellcheck source=/dev/null
set -euo pipefail

MODE="@mode@"

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MODE variable is set via template substitution but lacks validation. Consider adding a check after line 7 to ensure MODE is either 'gateway' or 'client' and exit with an error message if it's neither, preventing silent failures from misconfiguration.

Suggested change
MODE="@mode@"
MODE="@mode@"
case "$MODE" in
gateway|client)
;;
*)
echo "Error: invalid MODE '$MODE'. Expected 'gateway' or 'client'." >&2
exit 1
;;
esac

Copilot uses AI. Check for mistakes.
STATE_DIR="${OPENCLAW_STATE_DIR:-${HOME}/.openclaw}"
CONFIG="${OPENCLAW_CONFIG_PATH:-${STATE_DIR}/openclaw.json}"
TEMPLATE="@template@"
SECRETS_DIR="${HOME}/.config/openclaw"
LEGACY_SECRETS_DIR="${HOME}/.config/clawdbot"
ENV_FILE="${HOME}/dotfiles/.env"

# Source .env if it exists
Expand All @@ -29,33 +30,53 @@ read_secret() {
echo ""
}

# Load secrets from files or environment
CLIPROXY_API_KEY="${OPENCLAW_CLIPROXY_API_KEY:-${CLIPROXY_API_KEY:-$(read_secret "${SECRETS_DIR}/cliproxy-key" "${LEGACY_SECRETS_DIR}/cliproxy-key")}}"
TELEGRAM_TOKEN="${OPENCLAW_TELEGRAM_TOKEN:-${TELEGRAM_TOKEN:-$(read_secret "${SECRETS_DIR}/telegram-token" "${LEGACY_SECRETS_DIR}/telegram-token")}}"
GATEWAY_TOKEN="${OPENCLAW_GATEWAY_TOKEN:-${GATEWAY_TOKEN:-$(read_secret "${SECRETS_DIR}/gateway-token" "${LEGACY_SECRETS_DIR}/gateway-token")}}"
ANTHROPIC_API_KEY="${OPENCLAW_ANTHROPIC_API_KEY:-${ANTHROPIC_API_KEY:-$(read_secret "${SECRETS_DIR}/anthropic-key" "${LEGACY_SECRETS_DIR}/anthropic-key")}}"
# Load gateway token (required for both modes)
GATEWAY_TOKEN="${OPENCLAW_GATEWAY_TOKEN:-${GATEWAY_TOKEN:-$(read_secret "${SECRETS_DIR}/gateway-token")}}"

# Chromium path (injected by nix)
CHROMIUM_PATH="@chromium@/bin/chromium"
if [ -z "${GATEWAY_TOKEN}" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium

The early exit with exit 0 when GATEWAY_TOKEN is missing will silently skip OpenClaw configuration without any persistent indication of failure. In client mode (macOS), this means users might not realize their OpenClaw isn't configured. Consider either:

  1. Creating a placeholder config file with an error marker that OpenClaw can detect
  2. Using a non-zero exit code and handling it gracefully in the activation script with || true
  3. Logging to a file in ~/.openclaw/ that persists beyond stderr

The current approach could lead to confusing "OpenClaw not working" issues that are hard to debug.

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#712
File: config/openclaw/hydrate.sh#L36
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
The early exit with `exit 0` when GATEWAY_TOKEN is missing will silently skip OpenClaw configuration without any persistent indication of failure. In client mode (macOS), this means users might not realize their OpenClaw isn't configured. Consider either:
1. Creating a placeholder config file with an error marker that OpenClaw can detect
2. Using a non-zero exit code and handling it gracefully in the activation script with `|| true`
3. Logging to a file in ~/.openclaw/ that persists beyond stderr

The current approach could lead to confusing "OpenClaw not working" issues that are hard to debug.

echo "Warning: OPENCLAW_GATEWAY_TOKEN not set, skipping OpenClaw hydration" >&2
exit 0

@cubic-dev-ai cubic-dev-ai Bot Feb 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Exiting with exit 0 (success) when GATEWAY_TOKEN is not set means the OpenClaw configuration hydration will silently fail. This can lead to unexpected behavior or non-functional components without clear indication during the activation process. Consider using a non-zero exit code to signal failure, or log to a persistent location in ~/.openclaw/ for debugging.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/openclaw/hydrate.sh, line 38:

<comment>Exiting with `exit 0` (success) when GATEWAY_TOKEN is not set means the OpenClaw configuration hydration will silently fail. This can lead to unexpected behavior or non-functional components without clear indication during the activation process. Consider using a non-zero exit code to signal failure, or log to a persistent location in `~/.openclaw/` for debugging.</comment>

<file context>
@@ -29,33 +30,53 @@ read_secret() {
-CHROMIUM_PATH="@chromium@/bin/chromium"
+if [ -z "${GATEWAY_TOKEN}" ]; then
+  echo "Warning: OPENCLAW_GATEWAY_TOKEN not set, skipping OpenClaw hydration" >&2
+  exit 0
+fi
 
</file context>
Fix with Cubic

fi
Comment on lines +38 to +39

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Exiting with 0 (success) when the GATEWAY_TOKEN is not set means that the OpenClaw configuration hydration will silently fail if this critical token is missing. This can lead to unexpected behavior or non-functional components without clear indication during the NixOS activation process. It's best to exit with a non-zero status to signal a failure.

Suggested change
exit 0
fi
echo "Warning: OPENCLAW_GATEWAY_TOKEN not set, skipping OpenClaw hydration" >&2
exit 1


# Create state directory if needed
mkdir -p "$STATE_DIR"

# Generate config from template with secret substitution
@sed@ \
-e "s|__CLIPROXY_API_KEY__|${CLIPROXY_API_KEY}|g" \
-e "s|__TELEGRAM_TOKEN__|${TELEGRAM_TOKEN}|g" \
-e "s|__GATEWAY_TOKEN__|${GATEWAY_TOKEN}|g" \
-e "s|__CHROMIUM_PATH__|${CHROMIUM_PATH}|g" \
-e "s|__HOME__|${HOME}|g" \
"$TEMPLATE" >"$CONFIG"
if [ "$MODE" = "gateway" ]; then
# Gateway mode (Kyber): hydrate full template and start gateway
CLIPROXY_API_KEY="${OPENCLAW_CLIPROXY_API_KEY:-${CLIPROXY_API_KEY:-$(read_secret "${SECRETS_DIR}/cliproxy-key")}}"
TELEGRAM_TOKEN="${OPENCLAW_TELEGRAM_TOKEN:-${TELEGRAM_TOKEN:-$(read_secret "${SECRETS_DIR}/telegram-token")}}"
ANTHROPIC_API_KEY="${OPENCLAW_ANTHROPIC_API_KEY:-${ANTHROPIC_API_KEY:-$(read_secret "${SECRETS_DIR}/anthropic-key")}}"
CHROMIUM_PATH="@chromium@/bin/chromium"

echo "Generated openclaw config at $CONFIG" >&2
@sed@ \
-e "s|__CLIPROXY_API_KEY__|${CLIPROXY_API_KEY}|g" \
-e "s|__TELEGRAM_TOKEN__|${TELEGRAM_TOKEN}|g" \
-e "s|__GATEWAY_TOKEN__|${GATEWAY_TOKEN}|g" \
-e "s|__CHROMIUM_PATH__|${CHROMIUM_PATH}|g" \
-e "s|__HOME__|${HOME}|g" \
"$TEMPLATE" >"$CONFIG"

# Export Anthropic API key for OpenClaw
if [ -n "$ANTHROPIC_API_KEY" ]; then
export ANTHROPIC_API_KEY
fi
echo "Generated openclaw gateway config at $CONFIG" >&2

if [ -n "$ANTHROPIC_API_KEY" ]; then
export ANTHROPIC_API_KEY
fi

exec @openclaw@/bin/openclaw gateway --port 18789 "$@"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High

In gateway mode, this exec replaces the shell process with the openclaw gateway command. However, this script is called during home-manager activation (line 31 of config/openclaw/default.nix), not as a persistent service starter. This means the gateway will start during activation and then be orphaned or terminated when activation completes.

Should this be a systemd service instead? Or should the exec be removed so this script only hydrates the config without starting the service?

Fix in Cursor • Fix in Claude

Prompt for Agent
Task: Address review feedback left on GitHub.
Repository: shunkakinoki/dotfiles#712
File: config/openclaw/hydrate.sh#L64
Action: Open this file location in your editor, inspect the highlighted code, and resolve the issue described below.

Feedback:
In gateway mode, this `exec` replaces the shell process with the openclaw gateway command. However, this script is called during home-manager activation (line 31 of config/openclaw/default.nix), not as a persistent service starter. This means the gateway will start during activation and then be orphaned or terminated when activation completes.

Should this be a systemd service instead? Or should the exec be removed so this script only hydrates the config without starting the service?

@cubic-dev-ai cubic-dev-ai Bot Feb 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Using exec to start the gateway during home-manager activation is problematic. This replaces the shell process with the openclaw gateway command, but since this runs during activation (not as a persistent service), the gateway will either be orphaned or terminated when activation completes. Consider either making this a systemd service, or removing the exec so the script only hydrates the config without attempting to start the gateway.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/openclaw/hydrate.sh, line 64:

<comment>Using `exec` to start the gateway during home-manager activation is problematic. This replaces the shell process with the openclaw gateway command, but since this runs during activation (not as a persistent service), the gateway will either be orphaned or terminated when activation completes. Consider either making this a systemd service, or removing the exec so the script only hydrates the config without attempting to start the gateway.</comment>

<file context>
@@ -29,33 +30,53 @@ read_secret() {
+    export ANTHROPIC_API_KEY
+  fi
+
+  exec @openclaw@/bin/openclaw gateway --port 18789 "$@"
 
-# Start OpenClaw gateway
</file context>
Fix with Cubic


# Start OpenClaw gateway
exec @openclaw@/bin/openclaw gateway --port 18789 "$@"
else
# Client mode (macOS): generate remote config with gateway token
cat >"$CONFIG" <<EOF
{
"gateway": {
"mode": "remote",
"remote": {
"transport": "direct",
"url": "wss://kyber.tail950b36.ts.net",
"token": "${GATEWAY_TOKEN}"
}
}
}
EOF

echo "Generated openclaw client config at $CONFIG" >&2
fi
2 changes: 1 addition & 1 deletion dotagents
1 change: 0 additions & 1 deletion home-manager/modules/openclaw/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ in
# Only enable on kyber (gateway host)
lib.mkIf (host.isKyber) {
# Ensure OpenClaw directories exist
# Note: Node symlink is managed by fnm module
home.activation.openclawSetup = config.lib.dag.entryAfter [ "writeBoundary" ] ''
mkdir -p /tmp/openclaw
mkdir -p ${homeDir}/.openclaw
Expand Down
1 change: 1 addition & 0 deletions nix-darwin/config/dock.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"/Applications/Ghostty.app"
"/Applications/Linear.app"
"/Applications/Tailscale.app"
"/Applications/Codex.app"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The pull request description states "Remove duplicate Codex app entry in persistent dock applications". However, this change adds "/Applications/Codex.app" to the list. This directly contradicts the stated purpose of the PR. Please clarify if the intention was to add or remove this entry, and adjust the code or description accordingly. If the goal was to remove a duplicate, this line should not be added.

      "/Applications/Cursor.app"

@cubic-dev-ai cubic-dev-ai Bot Feb 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This change adds /Applications/Codex.app to the dock persistent applications, but the PR description states the intention is to "Remove duplicate Codex app entry". The code contradicts the stated purpose. Please clarify if the intention was to add or remove this entry, and adjust the code or description accordingly.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At nix-darwin/config/dock.nix, line 33:

<comment>This change adds `/Applications/Codex.app` to the dock persistent applications, but the PR description states the intention is to "Remove duplicate Codex app entry". The code contradicts the stated purpose. Please clarify if the intention was to add or remove this entry, and adjust the code or description accordingly.</comment>

<file context>
@@ -30,6 +30,7 @@
       "/Applications/Ghostty.app"
       "/Applications/Linear.app"
       "/Applications/Tailscale.app"
+      "/Applications/Codex.app"
       "/Applications/Cursor.app"
       "/Applications/Visual Studio Code.app"
</file context>
Fix with Cubic

"/Applications/Cursor.app"
"/Applications/Visual Studio Code.app"
"/Applications/Visual Studio Code - Insiders.app"
Expand Down
5 changes: 0 additions & 5 deletions spec/openclaw_hydrate_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ When run bash -c "grep 'SECRETS_DIR=' '$SCRIPT'"
The output should include '.config/openclaw'
End

It 'keeps legacy ~/.config/clawdbot fallback'
When run bash -c "grep 'LEGACY_SECRETS_DIR=' '$SCRIPT'"
The output should include '.config/clawdbot'
End

It 'reads from dotfiles .env file'
When run bash -c "grep 'ENV_FILE=' '$SCRIPT'"
The output should include 'dotfiles/.env'
Expand Down
Loading