fix(opencode): the auth check is the binary, and create takes the adapter's verdict (Issue #60, Linux item 3)

opencode 2.x needs no login: a fresh HOME runs a free default model and a
local provider has no key, while 2.x keeps no auth.json. auth_ok is now
"opencode on PATH or under <HOME>/.opencode/bin". `python -m lib_py.agents
auth-ok <agent>` exits with an adapter's verdict, and create's opencode
branch uses it (same 7 lines) instead of its own auth.json/key test and
`opencode --version`, which wrote a line to the real opencode log.
test_a4's opencode block now pins the binary rule (decision D1, required
by the brief's item 3 and by both reviewers). Other agents are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-18 13:38:58 +00:00
1 parent 7803d47026
commit d17cd80bd9
5 files changed
+100 -17

No files matched your search

+9
View File
@@ -117,6 +117,15 @@ def main():
print(adapter.resume_spec(binary, uuid, materialized=mat))
sys.exit(0)
elif cmd == 'auth-ok':
# auth-ok <agent>: exit 0 when the adapter's auth_ok() holds, else 1.
agent_name = sys.argv[2] if len(sys.argv) > 2 else ''
adapter = get_adapter(agent_name)
if not adapter:
print(f"ERROR: unknown agent {agent_name!r}", file=sys.stderr)
sys.exit(1)
sys.exit(0 if adapter.auth_ok() else 1)
elif cmd == 'exit-key':
agent_name = sys.argv[2] if len(sys.argv) > 2 else ''
adapter = get_adapter(agent_name)
@@ -39,13 +39,6 @@ def _ro_connect(db: str):
# (binary, HOME, XDG_DATA_HOME) -> the db `debug paths` printed for them.
_DB_PATHS = {}
_PROVIDER_ENV_VARS = (
'ANTHROPIC_API_KEY',
'OPENAI_API_KEY',
'GEMINI_API_KEY',
'GROQ_API_KEY'
)
class OpenCodeAgentAdapter(BaseAgentAdapter):
@property
def name(self) -> str:
@@ -322,11 +315,10 @@ class OpenCodeAgentAdapter(BaseAgentAdapter):
return f"{binary} --auto --standalone"
def auth_ok(self, run_cmd: Optional[Any] = None) -> bool:
if any(os.environ.get(v) for v in _PROVIDER_ENV_VARS):
return True
# opencode 2.x needs no login: a fresh HOME runs a free default model
# and local providers have no key, so the binary is the whole check.
home = os.environ.get("HOME_DIR") or os.environ.get("HOME") or os.path.expanduser("~")
auth_file = f"{home}/.local/share/opencode/auth.json"
return os.path.exists(auth_file)
return bool(shutil.which("opencode")) or os.path.exists(f"{home}/.opencode/bin/opencode")
def discover(self, ctx: DiscoveryContext) -> list:
db = self._resolve_db(ctx)