OAuth providers
One provider supports OAuth login: GitHub Copilot. The OAuth token is stored GLOBALLY under
~/.cyberine/copilot.json (mode 0o600, dir 0o700) — same home as every other provider's
~/.cyberine/.env, so a login from one repo is usable from any directory.
| Command | Provider | Flow | Token stored |
|---|---|---|---|
cyberine auth login copilot | GitHub Copilot | device-code | ~/.cyberine/copilot.json |
cyberine auth logout copilot | GitHub Copilot | delete token store | removes ~/.cyberine/copilot.json |
cyberine auth login copilot # GitHub Copilot device-code; stores token to ~/.cyberine/copilot.json
CYBERINE_BUILD_FLEET=loop-copilot-build cyberine run "add a hello world function"
cyberine auth logout copilot # deletes the token store; a subsequent status check shows not-configuredThe Copilot token expires every ~30 minutes; getCopilotToken() automatically refreshes it using
the stored GitHub token, so you only need to run cyberine auth login copilot once per GitHub session.
A refresh failure (revoked token, GitHub outage) surfaces as a distinct "token refresh failed"
error instead of the generic "not authenticated" message, so a transient blip doesn't read as a
missing login. A pre-fix store at .local/auth/copilot.json (cwd-scoped) is migrated to the
global path automatically on first use after upgrading; no manual action needed.
Known limitation: logout only deletes the LOCAL token store — the underlying GitHub OAuth grant stays authorized (the device-code flow is a public client with no client secret, which GitHub's revocation endpoint requires). The logout command prints this caveat with a pointer to https://github.com/settings/connections/applications, where the grant can be revoked manually.
Regression smoke (offline — stubs the GitHub endpoints, no login or network needed):
npm run selftest:copilot-auth # global store path + legacy migration, per-write 0600/0700
# re-tightening, thrown-vs-null refresh failures, logout deletionThe gateway is an ON-DEMAND dev dependency: restart: "no" means it never comes back after a
machine reboot or Docker restart, and it publishes the uncommon host port 41400
(CYBERINE_GATEWAY_PORT) so it rarely collides. Drive it with the cyberine-project-devstack project skill instead
of raw docker compose — it frees the port (stopping our container, then killing any foreign
holder) and waits until the gateway answers:
.claude/skills/cyberine-project-devstack/scripts/devstack.sh up # free port + start, wait for HTTP 200
.claude/skills/cyberine-project-devstack/scripts/devstack.sh status # gateway + ContextQ state, port, health
.claude/skills/cyberine-project-devstack/scripts/devstack.sh down # stop (or just leave it — it won't survive a reboot)
.claude/skills/cyberine-project-devstack/scripts/devstack.sh up --with-contextq # also bring up the ContextQ memory stackSetting any GATEWAY_* / LOOP_MODEL_* env var (even to the documented defaults) opts the gateway
adapters in — a live local gateway at http://localhost:41400/v1 with the default master key and the
anthropic/claude + openai/gpt aliases now registers loop-gateway-a / loop-gateway-b instead of
being read as "unconfigured". To put Claude/GPT into the WRITING fleet too, add the gateway-backed
implementers to CYBERINE_BUILD_FLEET (they also need the gateway up):
docker compose up -d
CYBERINE_TASK="<your task>" CYBERINE_BUILD_FLEET="loop-deepseek-build,loop-claude-build,loop-gpt-build" \
npm run wf -- src/engine/implementTaskWorkflow.ts # races DeepSeek vs Claude vs GPT, DiffJudge picks the winnerAPI-key providers
deepseek, moonshot, xiaomi, minimax, openai, google, xai, groq, mistral, together, fireworks, azure, openrouter, anthropic. Key VALUES are never printed.
MiniMax mmx — text worker + image/speech tools
The MiniMax mmx CLI is two capabilities in Cyberine: a TEXT worker (mmx-text-build) and two multimedia IMPLEMENTER tools (mmximagegenerate, mmxspeechsynthesize). Auth is flexible — EITHER export...