From 4305c6a87d8a5f6657dbee0987e3c0e6d92a8464 Mon Sep 17 00:00:00 2001 From: johnnyfish Date: Thu, 7 May 2026 13:09:20 +0300 Subject: [PATCH] fix: slim credential docs in group CLAUDE.md and add onecli-gateway container skill --- CLAUDE.md | 6 +- container/skills/onecli-gateway/SKILL.md | 67 +++++++++++++++++++ .../skills/onecli-gateway/instructions.md | 7 ++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 container/skills/onecli-gateway/SKILL.md create mode 100644 container/skills/onecli-gateway/instructions.md diff --git a/CLAUDE.md b/CLAUDE.md index f33dca7..92824fb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -76,7 +76,7 @@ For ad-hoc queries from skills or scripts, use the in-tree wrapper rather than t | `src/channels/` | Channel adapter infra (registry, Chat SDK bridge); specific channel adapters are skill-installed from the `channels` branch | | `src/providers/` | Host-side provider container-config (`claude` baked in; `opencode` etc. installed from the `providers` branch) | | `container/agent-runner/src/` | Agent-runner: poll loop, formatter, provider abstraction, MCP tools, destinations | -| `container/skills/` | Container skills mounted into every agent session | +| `container/skills/` | Container skills mounted into every agent session (`onecli-gateway`, `welcome`, `self-customize`, `agent-browser`, `slack-formatting`) | | `groups//` | Per-agent-group filesystem (CLAUDE.md, skills, per-group `agent-runner-src/` overlay) | | `scripts/init-first-agent.ts` | Bootstrap the first DM-wired agent (used by `/init-first-agent` skill) | | `migrate-v2.sh` + `setup/migrate-v2/` | v1→v2 migration. Standalone script: `bash migrate-v2.sh`. Seeds DB, copies groups/sessions, installs channels, builds container, offers service switchover, then hands off to `/migrate-from-v1` skill for owner setup and CLAUDE.md cleanup. See [docs/migration-dev.md](docs/migration-dev.md). | @@ -100,7 +100,7 @@ A second tier (direct source-level self-edits via a draft/activate flow) is plan ## Secrets / Credentials / OneCLI -API keys, OAuth tokens, and auth credentials are managed by the OneCLI gateway. Secrets are injected into per-agent containers at request time — none are passed in env vars or through chat context. `src/onecli-approvals.ts`, `ensureAgent()` in `container-runner.ts`. Run `onecli --help`. +API keys, OAuth tokens, and auth credentials are managed by the OneCLI gateway. Secrets are injected into per-agent containers at request time — none are passed in env vars or through chat context. The container agent sees this via the `onecli-gateway` container skill (`container/skills/onecli-gateway/SKILL.md`), which teaches it how the proxy works, how to handle auth errors, and to never ask for raw credentials. Host-side wiring: `src/onecli-approvals.ts`, `ensureAgent()` in `container-runner.ts`. Run `onecli --help`. ### Gotcha: auto-created agents start in `selective` secret mode @@ -144,7 +144,7 @@ Four types of skills. See [CONTRIBUTING.md](CONTRIBUTING.md) for the full taxono - **Channel/provider install skills** — copy the relevant module(s) in from the `channels` or `providers` branch, wire imports, install pinned deps (e.g. `/add-discord`, `/add-slack`, `/add-whatsapp`, `/add-opencode`). - **Utility skills** — ship code files alongside `SKILL.md` (e.g. `/claw`). - **Operational skills** — instruction-only workflows (`/setup`, `/debug`, `/customize`, `/init-first-agent`, `/manage-channels`, `/init-onecli`, `/update-nanoclaw`). -- **Container skills** — loaded inside agent containers at runtime (`container/skills/`: `welcome`, `self-customize`, `agent-browser`, `slack-formatting`). +- **Container skills** — loaded inside agent containers at runtime (`container/skills/`: `onecli-gateway`, `welcome`, `self-customize`, `agent-browser`, `slack-formatting`). | Skill | When to Use | |-------|-------------| diff --git a/container/skills/onecli-gateway/SKILL.md b/container/skills/onecli-gateway/SKILL.md new file mode 100644 index 0000000..0c22c3e --- /dev/null +++ b/container/skills/onecli-gateway/SKILL.md @@ -0,0 +1,67 @@ +--- +name: onecli-gateway +description: >- + Handle credentials and authentication for external services. Use when you + hit a 401, 403, or app_not_connected error, or when the user asks you to + access an external service (Gmail, GitHub, Slack, Calendar, Stripe, etc.). + Do NOT use browser extensions or manual auth flows — make HTTP requests + directly; the OneCLI proxy injects credentials automatically. +--- + +# OneCLI Gateway: Credentials & Authentication + +Your container routes all HTTPS traffic through the OneCLI proxy, which +injects stored credentials (API keys, OAuth tokens) at the proxy boundary. +You never see or handle credential values directly. + +## Making Requests + +Call the real API URL. The proxy intercepts and injects credentials automatically. + +```bash +curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=5" +curl -s "https://api.github.com/user/repos?per_page=10" +curl -s "https://api.stripe.com/v1/charges?limit=5" +``` + +Any HTTP client (curl, fetch, axios, Python requests, Go net/http, git) honors +`HTTPS_PROXY` automatically. You do not need to set auth headers. + +If a tool or library validates credentials locally before making the request, +pass any placeholder value (a fake string). The proxy replaces it with real +credentials at request time. + +## When a Request Fails (401 / 403 / app_not_connected) + +### Step 1 — Show the user a connect link + +If the error response includes a `connect_url`, share it directly: + +> To connect [service], open this link: +> [connect_url from the error response] + +If there's no `connect_url`, tell the user to open the OneCLI dashboard and +connect the service there. + +Do NOT ask the user for API keys or tokens. Do NOT suggest pasting credentials +into chat. The fix is always connecting the service in OneCLI. + +### Step 2 — Retry after the user connects + +After showing the link, let the user know you'll retry once they've connected. +When they confirm (or after a reasonable pause), retry the original request. + +If the retry still fails, ask the user if they need help with the OneCLI setup. + +## Rules + +- **Never** say "I don't have access to X" without first making the HTTP + request through the proxy. +- **Never** use browser extensions, gcloud, or manual auth flows. The proxy + handles credentials for you. +- **Never** ask the user for API keys, tokens, or passwords directly. +- **Never** suggest the user open Gmail/Calendar/GitHub in their browser + when they ask you to read or interact with those services. You have API + access — use it. +- If the proxy returns a policy error (403 with a JSON body), respect the + block. Do not retry or circumvent it. diff --git a/container/skills/onecli-gateway/instructions.md b/container/skills/onecli-gateway/instructions.md new file mode 100644 index 0000000..26d347a --- /dev/null +++ b/container/skills/onecli-gateway/instructions.md @@ -0,0 +1,7 @@ +# Credentials & External Services + +Your HTTP requests go through the OneCLI proxy, which injects real credentials automatically. Just call any API directly (Gmail, GitHub, Slack, etc.) — the proxy adds auth before it reaches the service. + +Use any method: curl, Python, a CLI tool, whatever fits. If a tool checks for credentials locally, pass any placeholder value — the proxy replaces it with real credentials at request time. + +If you get a `401`/`403`/`app_not_connected`, run `/onecli-gateway` for the full error-handling flow. Never ask the user for API keys or tokens — if credentials are missing, the fix is connecting the service in OneCLI.