Skip to content

Commit dcac23f

Browse files
authored
feat(home): agy を共通モジュールにして macmini にも入れる (#595)
1 parent ec11911 commit dcac23f

4 files changed

Lines changed: 66 additions & 23 deletions

File tree

nix/flake.nix

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,10 @@
737737
homeModules = roles.macminiHeadless;
738738
specialArgs = {
739739
inherit user;
740+
# hosts/macmini.nix and its home layer both take this; without it the whole macmini
741+
# configuration stops evaluating, which is where it was found — nothing in CI builds
742+
# this closure, so it went unnoticed until something needed the mini again.
743+
nixpkgsAgents = nixpkgs-agents;
740744
claudeAcp = claude-acp.packages.${system}.default;
741745
sopsNix = sops-nix;
742746
# 母艦からのリモートビルドを受ける側。接続してくるユーザーが trusted-users に

nix/home/darwin.nix

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,10 @@
44
lib,
55
user,
66
nixpkgsUnstable,
7-
nixpkgsAgents,
87
secureEnclaveKey,
98
...
109
}:
1110
let
12-
# The rolling lineage the agent CLIs ride on (same one cli.nix uses). gemini-cli belongs here
13-
# rather than on the pinned channel: Google refuses old clients outright — 0.42 answers
14-
# "This client is no longer supported" and hands back no model at all — so a pinned version of
15-
# this particular tool is a version that stops working on Google's schedule, not ours.
16-
agentPkgs = import ../lib/unstable-pkgs.nix {
17-
nixpkgsUnstable = nixpkgsAgents;
18-
inherit (pkgs.stdenv.hostPlatform) system;
19-
};
20-
2111
# Bound here rather than inline in home.packages because the LaunchAgent below
2212
# needs the path too, and both must point at the same store path.
2313
mechvibes-dx = pkgs.callPackage ../pkgs/mechvibes-dx.nix { };
@@ -37,6 +27,7 @@ in
3727
../modules/home/darwin-services.nix
3828
../modules/home/darwin-apps.nix
3929
../modules/home/darwin-ai-client.nix
30+
../modules/home/agy.nix
4031
];
4132

4233
# Nothing puts an .app under ~/Applications any more: bundles come from environment.systemPackages
@@ -219,18 +210,6 @@ in
219210
# mac-specific packages
220211
home.packages = with pkgs; [
221212
bun # generate/type-check karabiner.ts config
222-
# agy: Google's terminal agent, for agents that want a second model rather than a browser.
223-
# Auth is the account's own OAuth, which is what the AI Pro subscription applies to; an API
224-
# key would be separately billed and the subscription does not cover it.
225-
#
226-
# Not gemini-cli, which was tried first and is over: Google answers it with "this client is
227-
# no longer supported" and hands back no model at all, whatever the version. nixpkgs marks
228-
# the package for removal for the same reason. Antigravity is where that account went.
229-
#
230-
# Signing in through an automated browser is not the alternative, and was also tried: Google
231-
# returns the sign-in flow to its first step for anything driven over CDP, whatever the
232-
# password is. OAuth is a different road — the human consents in their own browser, once.
233-
agentPkgs.antigravity-cli
234213
pngpaste # needed for macOS image paste in obsidian.nvim / img-clip
235214
syncthing # Syncthing CLI (the resident is the LaunchAgent in services.syncthing)
236215
xcodegen # generate .xcodeproj from project.yml (Mac-only, since meta.platforms = darwin in Linux nixpkgs)

nix/home/macmini.nix

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ let
2020
};
2121
in
2222
{
23-
imports = [ ../modules/home/darwin-agent-state-sync.nix ];
23+
imports = [
24+
../modules/home/darwin-agent-state-sync.nix
25+
../modules/home/agy.nix
26+
];
2427

2528
# macmini-specific layer. The base CLI/zsh/XDG set inherits home/common.nix
2629
# composed on the flake side (no sops/age keys are brought in).

nix/modules/home/agy.nix

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Antigravity CLI component (ECS: profile). Google's terminal agent, `agy`.
2+
#
3+
# This is how a second model is reached from here. Not the browser: signing in to Gemini through
4+
# an automated browser does not work, and was tried — Google returns the sign-in flow to its first
5+
# step for anything driven over CDP, whatever the password is. And not gemini-cli, which was also
6+
# tried and is over: it answers "this client is no longer supported" after authenticating, at any
7+
# version, and nixpkgs marks it for removal for the same reason. Auth is the account's own OAuth
8+
# (one interactive `agy` per machine), which is what the AI Pro subscription applies to.
9+
#
10+
# The rolling agents lineage on purpose: Google refuses old clients outright, so pinning this
11+
# particular tool would only decide in advance the day it stops working.
12+
{
13+
config,
14+
lib,
15+
pkgs,
16+
nixpkgsAgents,
17+
...
18+
}:
19+
let
20+
agentPkgs = import ../../lib/unstable-pkgs.nix {
21+
nixpkgsUnstable = nixpkgsAgents;
22+
inherit (pkgs.stdenv.hostPlatform) system;
23+
};
24+
25+
# Declared keys only. Pro rather than Flash by default because this is the tool reached for a
26+
# second opinion, where the answer matters more than what it costs; `--model` picks another per
27+
# call (`agy models` lists them, Claude and gpt-oss included).
28+
settings = {
29+
model = "gemini-3.1-pro-high";
30+
enableTelemetry = false;
31+
};
32+
33+
wanted = pkgs.writeText "agy-settings.json" (builtins.toJSON settings);
34+
settingsFile = "${config.home.homeDirectory}/.gemini/antigravity-cli/settings.json";
35+
in
36+
{
37+
home.packages = [ agentPkgs.antigravity-cli ];
38+
39+
# Merged rather than linked: agy owns this file and writes to it as it runs (every directory
40+
# trusted lands here). A read-only store symlink would be a file it cannot update, so the keys
41+
# declared above are merged into whatever it already has, and everything else is left alone.
42+
home.activation.agySettings = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
43+
$DRY_RUN_CMD ${pkgs.python3}/bin/python3 - <<'PY'
44+
import json, pathlib
45+
46+
target = pathlib.Path("${settingsFile}")
47+
target.parent.mkdir(parents=True, exist_ok=True)
48+
try:
49+
current = json.loads(target.read_text())
50+
except (FileNotFoundError, json.JSONDecodeError):
51+
current = {}
52+
merged = {**current, **json.loads(pathlib.Path("${wanted}").read_text())}
53+
if merged != current:
54+
target.write_text(json.dumps(merged, indent=2) + "\n")
55+
PY
56+
'';
57+
}

0 commit comments

Comments
 (0)