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
2 changes: 2 additions & 0 deletions home-manager/services/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let
docker = import ./docker { inherit lib pkgs; };
dockerPostgres = import ./docker-postgres { inherit pkgs; };
dotfilesUpdater = import ./dotfiles-updater { inherit pkgs; };
gasTown = import ./gas-town { inherit pkgs; };
makeUpdater = import ./make-updater { inherit pkgs; };
neversslKeepalive = import ./neverssl-keepalive { inherit pkgs; };
ollama = import ./ollama { inherit pkgs inputs; };
Expand All @@ -31,6 +32,7 @@ in
docker
dockerPostgres
dotfilesUpdater
gasTown
makeUpdater
neversslKeepalive
ollama
Expand Down
31 changes: 31 additions & 0 deletions home-manager/services/gas-town/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{ pkgs, ... }:

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

Accept the config argument to allow access to Home Manager configuration values.

{ config, pkgs, ... }:

let
inherit (pkgs) lib;
in
{
systemd.user.services.gas-town = lib.mkIf pkgs.stdenv.isLinux {
Unit = {
Description = "Gas Town daemon (dolt + tmux + worker orchestration)";
After = [ "network.target" ];

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

After=network.target does not guarantee usable network connectivity and is often a no-op in user units. If gt up requires network availability, consider switching to After=network-online.target plus Wants=network-online.target, or omit the dependency entirely if not needed.

Suggested change
After = [ "network.target" ];
Wants = [ "network-online.target" ];
After = [ "network-online.target" ];

Copilot uses AI. Check for mistakes.
};
Service = {
Type = "simple";

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

The service does not set WorkingDirectory. systemd services default to working directory / unless configured, which can cause gt status/init/rig to run in an unexpected directory (or fail due to permissions). Set WorkingDirectory = \"%h\"; (user unit) or cd to the desired directory at the top of start.sh to make service behavior deterministic.

Suggested change
Type = "simple";
Type = "simple";
WorkingDirectory = "%h";

Copilot uses AI. Check for mistakes.
Environment = [
"PATH=${
lib.makeBinPath [
pkgs.bash
pkgs.coreutils
pkgs.git
pkgs.tmux
]
}:$HOME/.local/bin:$HOME/go/bin:/usr/local/bin"
Comment on lines +14 to +21

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

Systemd Environment variables do not perform shell expansion, so literal $HOME will not work as intended. Use ${config.home.homeDirectory} for interpolation. Additionally, grep is used in start.sh and should be explicitly included in the PATH via pkgs.grep to ensure the service is hermetic and works correctly across different environments.

        "PATH=${\n          lib.makeBinPath [\n            pkgs.bash\n            pkgs.coreutils\n            pkgs.git\n            pkgs.grep\n            pkgs.tmux\n          ]\n        }:${config.home.homeDirectory}/.local/bin:${config.home.homeDirectory}/go/bin:/usr/local/bin"

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

In systemd unit files, Environment= values are not shell-expanded, so $HOME will typically remain literal. This can break PATH resolution for user-installed binaries (including gt). Use systemd specifiers like %h for the home directory (e.g., :%h/.local/bin:%h/go/bin) or set WorkingDirectory/ExecStart in a way that doesn't rely on $HOME expansion.

Suggested change
}:$HOME/.local/bin:$HOME/go/bin:/usr/local/bin"
}:%h/.local/bin:%h/go/bin:/usr/local/bin"

Copilot uses AI. Check for mistakes.
];
ExecStart = "${pkgs.bash}/bin/bash ${./start.sh}";
Comment on lines +13 to +23

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether `gt` is provisioned declaratively anywhere in repo-managed Nix modules.
# Expected: find an explicit package or module that installs/provides `gt` for this user service.

echo "== References to gt-daemon and PATH construction =="
rg -n --no-heading -C2 'gt-daemon|makeBinPath|PATH='

echo
echo "== References that may provision gt in Nix config =="
fd -e nix | xargs rg -n --no-heading '\b(gt|gas[Tt]own|gas-town)\b' | head -200

Repository: shunkakinoki/dotfiles

Length of output: 43432


🏁 Script executed:

cat -n home-manager/services/gt-daemon/start.sh | head -50

Repository: shunkakinoki/dotfiles

Length of output: 496


🏁 Script executed:

# Search for any references to installing or providing `gt` in the repo
rg -n 'pkgs\.gt|pkgs\.gas.*town|\"gt\"' --type nix

Repository: shunkakinoki/dotfiles

Length of output: 187


🏁 Script executed:

# Check if gt is mentioned in home-manager configuration
rg -n '\bgt\b' home-manager/services/gt-daemon/ -A2 -B2

Repository: shunkakinoki/dotfiles

Length of output: 1312


🏁 Script executed:

# Search for gas-town package or gt provisioning in nix files (corrected)
rg -n 'gas.*town|gastown' --type nix

Repository: shunkakinoki/dotfiles

Length of output: 47


🏁 Script executed:

# Check if there's a go package that installs gt
rg -n 'pkgs\.go' home-manager/services/gt-daemon/

Repository: shunkakinoki/dotfiles

Length of output: 47


🏁 Script executed:

# Look for any installation or provisioning of gt in home-manager modules
rg -n 'install.*gt|provision.*gt' --type nix

Repository: shunkakinoki/dotfiles

Length of output: 47


🏁 Script executed:

# Check what packages are available in the nix flake or configuration
fd -e "nix" -x grep -l "gas.*town\|gastown" {} \;

Repository: shunkakinoki/dotfiles

Length of output: 47


Add gt package to PATH declaration.

The start.sh script requires the gt command (lines 5, 6, 10, 11, 15), but it is not included in the explicit makeBinPath list. The service will only work if gt is already installed in $HOME/.local/bin, $HOME/go/bin, or /usr/local/bin, making startup nondeterministic and potentially causing restart loops. Include pkgs.gas-town (or equivalent) in the PATH if available, or document how gt must be provisioned.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@home-manager/services/gt-daemon/default.nix` around lines 13 - 23, The PATH
in the Environment block for the service omits the package that provides the gt
binary, making start.sh (invoked by ExecStart) non-deterministic; update the
PATH construction inside lib.makeBinPath to include the gt provider (e.g.,
pkgs.gas-town) so gt is available at runtime (or alternatively add a
comment/documentation that gt must be installed into $HOME/.local/bin or
$HOME/go/bin), ensuring start.sh can reliably find the gt command.

Restart = "always";
RestartSec = 30;
};
Comment on lines +23 to +26

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

The service does not set WorkingDirectory. systemd services default to working directory / unless configured, which can cause gt status/init/rig to run in an unexpected directory (or fail due to permissions). Set WorkingDirectory = \"%h\"; (user unit) or cd to the desired directory at the top of start.sh to make service behavior deterministic.

Copilot uses AI. Check for mistakes.
Install = {
WantedBy = [ "default.target" ];
};
};
}
15 changes: 15 additions & 0 deletions home-manager/services/gas-town/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

# Initialize Gas Town if not already set up
if ! gt status >/dev/null 2>&1; then
gt init
fi

# Add dotfiles rig if not already present
if ! gt rig list 2>/dev/null | grep -q dotfiles; then

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

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

grep -q dotfiles can produce false positives (e.g., matching my-dotfiles), which could prevent the rig from being added when required. Prefer an exact match (e.g., anchoring with grep -qx) or a more structured check based on gt rig list output format.

Suggested change
if ! gt rig list 2>/dev/null | grep -q dotfiles; then
if ! gt rig list 2>/dev/null | grep -qx 'dotfiles'; then

Copilot uses AI. Check for mistakes.
gt rig add dotfiles --adopt
fi
Comment on lines +10 to +12

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use stricter rig-name matching to avoid false positives.

Line 10’s grep -q dotfiles can match partial names (for example, dotfiles-old), which may skip gt rig add when the exact rig is absent.

Suggested fix
-if ! gt rig list 2>/dev/null | grep -q dotfiles; then
+if ! gt rig list 2>/dev/null | grep -Eq '(^|[[:space:]])dotfiles([[:space:]]|$)'; then
   gt rig add dotfiles --adopt
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ! gt rig list 2>/dev/null | grep -q dotfiles; then
gt rig add dotfiles --adopt
fi
if ! gt rig list 2>/dev/null | grep -Eq '(^|[[:space:]])dotfiles([[:space:]]|$)'; then
gt rig add dotfiles --adopt
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@home-manager/services/gt-daemon/start.sh` around lines 10 - 12, The current
check using "gt rig list ... | grep -q dotfiles" can match substrings like
"dotfiles-old"; change the matching to require an exact line match so the
presence of the "dotfiles" rig is detected correctly (e.g., replace the grep
invocation in the condition with a strict match such as grep -qx 'dotfiles' or
an equivalent exact-line check), leaving the "gt rig add dotfiles --adopt" call
unchanged.


# Start the daemon (blocks - runs dolt+tmux+daemon)
exec gt up
5 changes: 5 additions & 0 deletions spec/coverage_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ It 'has spec file for home-manager/services/dotfiles-updater/update.sh'
The path "spec/dotfiles_updater_spec.sh" should be exist
End

It 'has spec file for home-manager/services/gas-town/start.sh'
The path "spec/gas_town_spec.sh" should be exist
End

It 'has spec file for home-manager/services/make-updater/update.sh'
The path "spec/make_updater_spec.sh" should be exist
End
Expand Down Expand Up @@ -278,6 +282,7 @@ home-manager/services/docker-postgres/start-postgres.sh
home-manager/services/docker/docker-setup.sh
home-manager/services/docker/setup-docker.sh
home-manager/services/dotfiles-updater/update.sh
home-manager/services/gas-town/start.sh
home-manager/services/make-updater/update.sh
home-manager/services/neverssl-keepalive/keepalive.sh
install.sh
Expand Down
50 changes: 50 additions & 0 deletions spec/gas_town_spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
# shellcheck disable=SC2329

Describe 'gas-town/start.sh'
SCRIPT="$PWD/home-manager/services/gas-town/start.sh"

Describe 'script properties'
It 'uses bash shebang'
When run bash -c "head -1 '$SCRIPT'"
The output should include '#!/usr/bin/env bash'
End

It 'uses strict mode'
When run bash -c "head -5 '$SCRIPT'"
The output should include 'set -euo pipefail'
End
End

Describe 'initialization'
It 'checks gt status before init'
When run bash -c "grep 'gt status' '$SCRIPT'"
The output should include 'gt status'
End

It 'runs gt init if not set up'
When run bash -c "grep 'gt init' '$SCRIPT'"
The output should include 'gt init'
End
End

Describe 'rig setup'
It 'checks for dotfiles rig'
When run bash -c "grep 'gt rig list' '$SCRIPT'"
The output should include 'gt rig list'
End

It 'adds dotfiles rig with adopt flag'
When run bash -c "grep 'gt rig add dotfiles --adopt' '$SCRIPT'"
The output should include 'gt rig add dotfiles --adopt'
End
End

Describe 'daemon startup'
It 'starts with exec gt up'
When run bash -c "grep 'exec gt up' '$SCRIPT'"
The output should include 'exec gt up'
End
End

End
Loading