Compare commits

..

9 Commits

Author SHA1 Message Date
39352b10bc opencode: add oh-my-opencode as a plugin 2026-01-28 12:22:48 -05:00
c31a6cc09e opencode: use my fork of oh-my-opencode 2026-01-28 12:18:25 -05:00
cb031d3d66 Reapply "add oh-my-opencode"
This reverts commit 8297cd01f4.
2026-01-28 12:16:00 -05:00
5cbb10b245 opencode: move away from claude 2026-01-28 12:04:23 -05:00
8297cd01f4 Revert "add oh-my-opencode"
This reverts commit 2b912cc38e.
2026-01-28 11:49:04 -05:00
2b912cc38e add oh-my-opencode 2026-01-28 11:38:16 -05:00
60317ef61e update 2026-01-28 11:25:26 -05:00
0a868cf3dd opencode: add info about android app UI interaction 2026-01-27 23:26:01 -05:00
3c6c3592a3 grayjay 2026-01-27 13:52:12 -05:00
4 changed files with 169 additions and 49 deletions

146
flake.lock generated
View File

@@ -9,11 +9,11 @@
"systems": "systems_2" "systems": "systems_2"
}, },
"locked": { "locked": {
"lastModified": 1767386128, "lastModified": 1769353768,
"narHash": "sha256-BJDu7dIMauO2nYRSL4aI8wDNtEm2KOb7lDKP3hxdrpo=", "narHash": "sha256-zI+7cbMI4wMIR57jMjDSEsVb3grapTnURDxxJPYFIW0=",
"owner": "numtide", "owner": "numtide",
"repo": "blueprint", "repo": "blueprint",
"rev": "0ed984d51a3031065925ab08812a5434f40b93d4", "rev": "c7da5c70ad1c9b60b6f5d4f674fbe205d48d8f6c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -106,11 +106,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769306011, "lastModified": 1769594889,
"narHash": "sha256-yh27kFW0S03NM6Xi4gc9JN2gobLgW+oHAPro5lRrOVc=", "narHash": "sha256-15Sb7QhUEFrRAzRMxaiGxCQxddkFAydA5ZtYRoL/Z00=",
"owner": "nix-community", "owner": "nix-community",
"repo": "emacs-overlay", "repo": "emacs-overlay",
"rev": "ffd3a16e5417a68d55bc25a6e1ad66c95c2ad767", "rev": "4e58fc3fa871106900fab58a7ade8736c315d5af",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -151,6 +151,24 @@
"type": "github" "type": "github"
} }
}, },
"flake-utils": {
"inputs": {
"systems": "systems_4"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gitignore": { "gitignore": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -180,11 +198,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769289524, "lastModified": 1769579508,
"narHash": "sha256-6Cwtvzrw79cOk1lCzN2aKSVrpgSOSQoYhyMmhXXZjTA=", "narHash": "sha256-EE2bs7xFrC64qrj0N2zP6E6e/nmhcdw6v/grdYi+BiY=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "2539eba97a6df237d75617c25cd2dbef92df3d5b", "rev": "eec72f127831326b042d1f35003767a4ab6a9516",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -203,11 +221,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1768941735, "lastModified": 1769548169,
"narHash": "sha256-OyxsfXNcOkt06/kM+4bnuC8moDx+t7Qr+RB0BBa83Ig=", "narHash": "sha256-03+JxvzmfwRu+5JafM0DLbxgHttOQZkUtDWBmeUkN8Y=",
"owner": "nix-community", "owner": "nix-community",
"repo": "impermanence", "repo": "impermanence",
"rev": "69ecf31e8fddc9354a4b418f3a517445d486bb54", "rev": "7b1d382faf603b6d264f58627330f9faa5cba149",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -224,11 +242,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769273817, "lastModified": 1769596123,
"narHash": "sha256-+iyLihi/ynJokMgJZMRXuMuI6DPGUQRajz5ztNCHgnI=", "narHash": "sha256-kcElu+HiwNIJiaNH41IdemFaaGyU3TqI4ebx5CQMHFs=",
"owner": "Jovian-Experiments", "owner": "Jovian-Experiments",
"repo": "Jovian-NixOS", "repo": "Jovian-NixOS",
"rev": "98f988ad46e31f9956c5f6874dfb3580a7ff3969", "rev": "d6bf85533180720680544a0791c7334e315c4fd6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -249,11 +267,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769301952, "lastModified": 1769417433,
"narHash": "sha256-XxYnvAPv2kZBTUywng8mvX2OJtq0Dx3FDyta1NmSjRc=", "narHash": "sha256-0WZ7I/N9InaBHL96/qdiJxg8mqFW3vRla8Z062JmQFE=",
"owner": "nix-community", "owner": "nix-community",
"repo": "lanzaboote", "repo": "lanzaboote",
"rev": "4673781e286eeeb35fec07b01cad87d41d94a349", "rev": "1902463415745b992dbaf301b2a35a1277be1584",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -271,11 +289,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1769234232, "lastModified": 1769611617,
"narHash": "sha256-88lfPFXzCfxVhWJBq9RvwqvAa5IH+iLcR7f+gRl+8IM=", "narHash": "sha256-+bDjPaUXXvZ+eGNeqGcZQM1ontShZKIkhW5aiSM0SIk=",
"owner": "numtide", "owner": "numtide",
"repo": "llm-agents.nix", "repo": "llm-agents.nix",
"rev": "861ade6060a73482cfd08bd992fa687f910e5c7c", "rev": "08381f74f518ef4963c43b562cc17f9c134173d7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -298,11 +316,11 @@
"xwayland-satellite-unstable": "xwayland-satellite-unstable" "xwayland-satellite-unstable": "xwayland-satellite-unstable"
}, },
"locked": { "locked": {
"lastModified": 1769282225, "lastModified": 1769582851,
"narHash": "sha256-5rcscjSoahWOb/xTNCLlqh/PKfNwvAwcf2hQ7XLj5RI=", "narHash": "sha256-T2a9J3iZ+p+dSmrd8mGgehvXrzwnFlMF22BmBqYHkVg=",
"owner": "sodiboo", "owner": "sodiboo",
"repo": "niri-flake", "repo": "niri-flake",
"rev": "2efd11d9a6b5655c3b97beb666739eabcebd6171", "rev": "8942525e9d5c79f6b47cffef4992454c9b3f9b69",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -331,11 +349,11 @@
"niri-unstable": { "niri-unstable": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1768678265, "lastModified": 1769577126,
"narHash": "sha256-Ub8eed4DsfIDWyg30xEe+8bSxL/z5Af/gCjmvJ0V/Hs=", "narHash": "sha256-v9vz9Rj4MGwPuhGELdvpRKl2HH+xvkgat6VwL0L86Fg=",
"owner": "YaLTeR", "owner": "YaLTeR",
"repo": "niri", "repo": "niri",
"rev": "d7184a04b904e07113f4623610775ae78d32394c", "rev": "f30db163b5748e8cf95c05aba77d0d3736f40543",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -356,11 +374,11 @@
"systems": "systems_3" "systems": "systems_3"
}, },
"locked": { "locked": {
"lastModified": 1769244263, "lastModified": 1769590344,
"narHash": "sha256-kn4ylXn5G+/AutGVtDczPGjwKmsXQs+BqZB0IeyyeXw=", "narHash": "sha256-IO71Efl9r0mKH+ZSLe9Xj4ZzKp75TE8t8otPS57/O3I=",
"owner": "marienz", "owner": "marienz",
"repo": "nix-doom-emacs-unstraightened", "repo": "nix-doom-emacs-unstraightened",
"rev": "11401bae5bf33c20d1be6cb8c5fe90641f253f24", "rev": "3fc11d166b98a685b13de7f5f7ca787b8568b8b7",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -424,11 +442,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1769018530, "lastModified": 1769461804,
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=", "narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1", "rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -438,6 +456,28 @@
"type": "github" "type": "github"
} }
}, },
"oh-my-opencode": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1769620461,
"narHash": "sha256-0bkdu0vuxg6jrLY1Bo7SPLHsKBeClxznmDGMsxC/wt8=",
"owner": "titaniumtown",
"repo": "oh-my-opencode",
"rev": "95f5e85721a185c5b682cfa0157920c865849a73",
"type": "github"
},
"original": {
"owner": "titaniumtown",
"ref": "nix",
"repo": "oh-my-opencode",
"type": "github"
}
},
"pre-commit": { "pre-commit": {
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_2",
@@ -476,6 +516,7 @@
"nix-flatpak": "nix-flatpak", "nix-flatpak": "nix-flatpak",
"nixos-hardware": "nixos-hardware", "nixos-hardware": "nixos-hardware",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"oh-my-opencode": "oh-my-opencode",
"rust-overlay": "rust-overlay", "rust-overlay": "rust-overlay",
"zen-browser": "zen-browser" "zen-browser": "zen-browser"
} }
@@ -487,11 +528,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769309768, "lastModified": 1769568593,
"narHash": "sha256-AbOIlNO+JoqRJkK1VrnDXhxuX6CrdtIu2hSuy4pxi3g=", "narHash": "sha256-vf3cZf8imUlPzFtICa1uyReDzoPV0XhHOIRM3tqI5VY=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "140c9dc582cb73ada2d63a2180524fcaa744fad5", "rev": "6fe5039018d05cee5d01dda7df1c0846fb7943a4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -545,6 +586,21 @@
"type": "github" "type": "github"
} }
}, },
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": { "treefmt-nix": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@@ -553,11 +609,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1768158989, "lastModified": 1769515380,
"narHash": "sha256-67vyT1+xClLldnumAzCTBvU0jLZ1YBcf4vANRWP3+Ak=", "narHash": "sha256-CWWK3PaQ7zhr+Jcf5zyaTR2cfRBXPo09H7+5nWApL8s=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "e96d59dff5c0d7fddb9d113ba108f03c3ef99eca", "rev": "9911802c2822def2eec3d22e2cafd1619ede94a5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -604,11 +660,11 @@
"xwayland-satellite-unstable": { "xwayland-satellite-unstable": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1769279212, "lastModified": 1769356222,
"narHash": "sha256-LAd6DYp6bbnQqtzMm62BE/0IMy67A4CgyYVi4xvyD6s=", "narHash": "sha256-Q0BVubV9ZnmLs506EhBSPglM+YJK56wsQNbeecvWPUo=",
"owner": "Supreeeme", "owner": "Supreeeme",
"repo": "xwayland-satellite", "repo": "xwayland-satellite",
"rev": "3af3e3ab78d0eb96fb9b5161693811e050b90991", "rev": "cf14278b92b0a91d01587f09b4b00ea655ae24e6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -627,11 +683,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1769319042, "lastModified": 1769589275,
"narHash": "sha256-2MmX9m8ZZgXEakZ9us2CsxG8Uz6ZjaFM+Xe5Y7VrZTQ=", "narHash": "sha256-hU6J/bU8mHhJrV/asVDQ9oY7gcH/MMSOGtr4iOYy8lc=",
"owner": "0xc000022070", "owner": "0xc000022070",
"repo": "zen-browser-flake", "repo": "zen-browser-flake",
"rev": "500f06314aebde1174ca6da147ccf59259abf6c0", "rev": "a318ae926a6f96cce4cb8498ad986b33a6d44b21",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@@ -73,6 +73,12 @@
url = "github:numtide/llm-agents.nix"; url = "github:numtide/llm-agents.nix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
# wait for https://github.com/code-yeongyu/oh-my-opencode/pull/921 to be merged
oh-my-opencode = {
url = "github:titaniumtown/oh-my-opencode/nix";
inputs.nixpkgs.follows = "nixpkgs";
};
}; };
outputs = outputs =

View File

@@ -18,6 +18,7 @@
pkg: pkg:
builtins.elem (lib.getName pkg) [ builtins.elem (lib.getName pkg) [
"apple_cursor" "apple_cursor"
"grayjay"
]; ];
home.packages = home.packages =
@@ -34,6 +35,7 @@
[ [
tor-browser tor-browser
inputs.zen-browser.packages."${system}".twilight inputs.zen-browser.packages."${system}".twilight
grayjay
] ]
# music library management # music library management

View File

@@ -8,23 +8,30 @@
let let
# what model should be used in place of haiku? # what model should be used in place of haiku?
# glm 4.7-flash is an example # glm 4.7-flash is an example
haiku-model = "anthropic/claude-haiku-4-5"; haiku-model = "openrouter/z-ai/glm-4.7-flash";
opus-model = "openrouter/moonshotai/kimi-k2.5";
ohMyOpencodeConfig = { ohMyOpencodeConfig = {
"$schema" = "$schema" =
"https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json"; "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json";
agents = { agents = {
Sisyphus.model = "anthropic/claude-opus-4-5"; Sisyphus.model = opus-model;
librarian.model = haiku-model; librarian.model = haiku-model;
explore.model = haiku-model; explore.model = haiku-model;
oracle.model = "openrouter/openai/gpt-5.2"; oracle.model = "openrouter/openai/gpt-5.2";
frontend-ui-ux-engineer.model = "openrouter/google/gemini-3-pro-preview"; frontend-ui-ux-engineer.model = "openrouter/google/gemini-3-pro-preview";
document-writer.model = "anthropic/claude-sonnet-4-5"; document-writer.model = opus-model;
multimodal-looker.model = haiku-model; multimodal-looker.model = haiku-model;
}; };
}; };
in in
{ {
home.packages = [
inputs.oh-my-opencode.packages.${pkgs.stdenv.hostPlatform.system}.oh-my-opencode
];
xdg.configFile."opencode/oh-my-opencode.json".text = builtins.toJSON ohMyOpencodeConfig; xdg.configFile."opencode/oh-my-opencode.json".text = builtins.toJSON ohMyOpencodeConfig;
programs.opencode = { programs.opencode = {
@@ -50,17 +57,66 @@ in
## Nix ## Nix
For using `nix build` append `-L` to get better visibility into the logs. For using `nix build` append `-L` to get better visibility into the logs.
If you get an error that a file can't be found, always try to `git add` the file before trying other troubleshooting steps. If you get an error that a file can't be found, always try to `git add` the file before trying other troubleshooting steps.
## Android UI Interaction Workflow Summary
1. Taking Screenshots
adb exec-out screencap -p > /tmp/screen.png
Captures the current screen state as a PNG image.
2. Analyzing Screenshots
I delegate screenshot analysis to an explore agent rather than analyzing images directly:
mcp_task(subagent_type="explore", prompt="Analyze /tmp/screen.png. What screen is this? What elements are visible?")
The agent describes the UI, identifies elements, and estimates Y coordinates.
3. Getting Precise Element Coordinates
UI Automator dump - extracts the full UI hierarchy as XML:
adb shell uiautomator dump /sdcard/ui.xml && adb pull /sdcard/ui.xml /tmp/ui.xml
Then grep for specific elements:
# Find by text
grep -oP 'text="Login".*?bounds="[^"]*"' /tmp/ui.xml
# Find by class
grep -oP 'class="android.widget.EditText".*?bounds="[^"]*"' /tmp/ui.xml
Bounds format: [left,top][right,bottom] tap center: ((left+right)/2, (top+bottom)/2)
4. Tapping Elements
adb shell input tap X Y
Where X, Y are pixel coordinates from the bounds.
5. Text Input
adb shell input text "some_text"
Note: Special characters need escaping (\!, \;, etc.)
6. Other Gestures
# Swipe/scroll
adb shell input swipe startX startY endX endY duration_ms
# Key events
adb shell input keyevent KEYCODE_BACK
adb shell input keyevent KEYCODE_ENTER
7. WebView Limitation
- UI Automator can see WebView content if accessibility is enabled
- Touch events on iframe content (like Cloudflare Turnstile) often fail due to cross-origin isolation
- Form fields in WebViews work if you get exact bounds from the UI dump
Typical Flow
1. Take screenshot analyze with explore agent (get rough layout)
2. Dump UI hierarchy grep for exact element bounds
3. Calculate center coordinates from bounds
4. Tap/interact
5. Wait screenshot verify result
''; '';
settings = { settings = {
theme = "opencode"; theme = "opencode";
model = "anthropic/claude-opus-4-5"; model = opus-model;
# small model used for titles # small model used for titles
small_model = "openrouter/openai/gpt-oss-20b:free"; small_model = "openrouter/openai/gpt-oss-20b:free";
autoshare = false; autoshare = false;
autoupdate = true; autoupdate = true;
agent = { }; agent = { };
plugin = [ "oh-my-opencode" ];
provider = { provider = {
openrouter = { openrouter = {
models = { models = {