From 25c045148976e4b57ec25189cda8bb6da5b47ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9B=A2=E5=AD=90?= Date: Sat, 9 May 2026 03:55:06 +0000 Subject: [PATCH] feat: cfg skill with topic-based docs (general/contract/onboarding/admin) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cfg skill — general usage (default), lists other topics cfg skill contract — API endpoints, KV layout, auth flow cfg skill onboarding — step-by-step new agent setup cfg skill admin — admin operations & user management --- packages/cfg/package.json | 2 +- packages/cfg/src/cli.ts | 2 +- packages/cfg/src/commands.ts | 226 ++++++++++++++++++++++++++--------- 3 files changed, 169 insertions(+), 61 deletions(-) diff --git a/packages/cfg/package.json b/packages/cfg/package.json index 5d64edf..76ecb19 100644 --- a/packages/cfg/package.json +++ b/packages/cfg/package.json @@ -1,6 +1,6 @@ { "name": "@shazhou/cfg", - "version": "1.2.0", + "version": "1.3.0", "type": "module", "bin": { "cfg": "./dist/cli.js" diff --git a/packages/cfg/src/cli.ts b/packages/cfg/src/cli.ts index e6db535..ac01c13 100644 --- a/packages/cfg/src/cli.ts +++ b/packages/cfg/src/cli.ts @@ -105,7 +105,7 @@ switch (cmd) { showHelp(); break; case "skill": - showSkill(); + showSkill(args[0]); break; default: console.error(`Unknown command: ${cmd}`); diff --git a/packages/cfg/src/commands.ts b/packages/cfg/src/commands.ts index ccd4187..a0a463d 100644 --- a/packages/cfg/src/commands.ts +++ b/packages/cfg/src/commands.ts @@ -399,28 +399,23 @@ export async function cmdProfileUnset(args: string[]): Promise { console.log(`✓ ${key} deleted from public profile`); } -export function showSkill(): void { - console.log(`# cfg — Config Service CLI Skill +export function showSkill(topic?: string): void { + const topics: Record = { + general: `# cfg — General Usage -## Overview -cfg is the CLI for config.shazhou.work, a centralized config/secret management service +cfg is the CLI for config.shazhou.work — centralized config & secret management for the 沙洲家族 agent network. Built on Cloudflare Workers + KV. -## Architecture -- **Scopes**: shared (admin-only write, all read), personal (own agent read/write) +## Concepts +- **Scopes**: shared (admin-only write, all read) and personal (own agent read/write) - **Resolution**: personal overrides shared (personal > shared fallback) -- **Caching**: local cache with auto-sync (fresh for 1 day, retry after 2h on failure) -- **Auth**: Bearer token per agent, stored via \`cfg token \` +- **Caching**: local cache with auto-sync (fresh 1 day, retry 2h after failure) +- **Profile**: public key-value pairs visible to all agents, writable only by owner ## Shell Setup -Add to .bashrc / .zshrc / .profile: - eval $(cfg env) + eval $(cfg env) Add to .bashrc / .zshrc / .profile -This exports all config keys (where env=true) as environment variables. - -## Common Workflows - -### Read/Write Config +## Commands cfg get Read from cache (auto-syncs if stale) cfg get --remote Read directly from server cfg set Write to personal scope @@ -429,65 +424,178 @@ This exports all config keys (where env=true) as environment variables. cfg set --no-env Won't be exported by cfg env cfg unset Delete from personal scope cfg unset --shared Delete from shared scope (admin only) - -### List & Sync - cfg list List all keys with scope/flags (from cache) + cfg list List all keys with scope/flags cfg sync Force sync from server cfg env Output export statements for shell - -### Flags - cfg flags Show current flags (env, secret) - cfg flags --no-env Set no-env flag - cfg flags --secret Set secret flag - cfg flags --no-secret Remove secret flag - -### Public Profile -Public profile is visible to all authenticated agents. Each agent can only write their own. + cfg flags [--env|--no-env] [--secret|--no-secret] cfg profile Show your own public profile cfg profile Show another agent's public profile cfg profile set Set a key in your public profile cfg profile unset Delete a key from your public profile cfg profiles List all agents with public profiles - -Example profile keys: contact, role, telegram_id, github, description - -### Admin (requires admin role) - cfg admin agents List all registered agents - cfg admin add [--admin] Create token for new agent - cfg admin remove Revoke all tokens for an agent - cfg admin refresh Revoke + recreate token - cfg admin inspect View an agent's resolved config - -### Token Management cfg token Save auth token locally ## Environment Variables CFG_TOKEN Auth token (overrides saved token) CFG_ENDPOINT API endpoint (default: https://config.shazhou.work) -## API Endpoints (for direct HTTP access) - GET /config List all resolved keys - GET /config/:key Read key (personal > shared fallback) - PUT /config/:key?scope=... Write key (scope: personal|shared) - PATCH /config/:key?scope=... Update flags only - DELETE /config/:key?scope=... Delete key - POST /config/sync Full sync (all resolved key-values) - GET /profiles List agents with public profiles - GET /profile/:id Get agent's public profile - GET /profile/:id/:key Get single public profile key - PUT /profile/:id/:key Set own public profile key - DELETE /profile/:id/:key Delete own public profile key - GET /admin/agents List all agents (admin) - POST /admin/token Create agent token (admin) - DELETE /admin/token/:id Revoke agent tokens (admin) - GET /admin/agent/:id Inspect agent config (admin) - GET /health Health check (no auth) - ## Tips -- Use --secret for sensitive values (API keys, tokens) — they're masked in the web UI +- Use --secret for API keys, tokens — masked in the web UI - Use --no-env for config that shouldn't pollute the shell environment -- Profile is great for agent contact info, roles, and public metadata -- Cache is at ~/.config/cfg/cache.json, token at ~/.config/cfg/config.json`); +- Profile is great for contact info, roles, and public metadata +- Cache lives at ~/.config/cfg/cache.json`, + + contract: `# cfg — API Contract + +Base URL: https://config.shazhou.work +Auth: Bearer token in Authorization header + +## KV Storage Layout + auth:{sha256(token)} → { agent_id, role } + agent_tokens:{agent_id} → [hash1, hash2, ...] + shared:{key} → { value, updated_at, env, secret } + personal:{agent_id}:{key} → { value, updated_at, env, secret } + public:{agent_id}:{key} → { value, updated_at, env: false, secret: false } + +## Config Endpoints (auth required) + GET /config List/sync all resolved keys + ?scope=shared|personal to filter + GET /config/:key Read key (personal > shared fallback) + PUT /config/:key?scope=personal Write key + ?scope=shared (admin only) + Body: { value, env?, secret? } + PATCH /config/:key?scope=... Update flags only (env, secret) + Body: { env?, secret? } + DELETE /config/:key?scope=... Delete key + POST /config/sync Full sync — all resolved key-values + +## Profile Endpoints (auth required) + GET /profiles List agent_ids with public profiles + GET /profile/:agent_id All public keys for an agent + GET /profile/:agent_id/:key Single public key + PUT /profile/:agent_id/:key Set (own profile only, 403 otherwise) + Body: { value } + DELETE /profile/:agent_id/:key Delete (own profile only) + +## Admin Endpoints (admin role required) + GET /admin/agents List all registered agents + POST /admin/token Create token + Body: { agent_id, role? } + Returns: { agent_id, role, token } + DELETE /admin/token/:agent_id Revoke all tokens for agent + GET /admin/agent/:agent_id Inspect agent's resolved config + +## Public Endpoints (no auth) + GET /health → { status: "ok" } + GET / Web UI (HTML) + +## Response Format + Success: { key, value, scope, env, secret, updated_at } + Error: { error: "message" } with appropriate HTTP status + Sync: { agent_id, role, secrets: { key: { value, scope, env, secret, updated_at } } } + +## Auth Flow + 1. Admin creates token via POST /admin/token → returns raw token + 2. Agent stores token via \`cfg token \` + 3. All requests include Authorization: Bearer + 4. Server hashes token with SHA-256, looks up auth:{hash} in KV`, + + onboarding: `# cfg — Agent Onboarding + +Step-by-step guide for new agents joining the 沙洲家族 network. + +## Prerequisites +- Node.js 18+ or Bun installed +- An agent token (ask an admin to run: cfg admin add ) + +## Step 1: Install cfg + bun install -g @shazhou/cfg + # or: npm install -g @shazhou/cfg + +## Step 2: Save your token + cfg token + +## Step 3: First sync + cfg sync + # Should show: ✓ Synced N keys (agent: your_id) + +## Step 4: Set up shell integration +Add to your .bashrc / .zshrc / .profile: + export PATH="$HOME/.bun/bin:$PATH" + eval $(cfg env) + +Then reload: source ~/.bashrc + +## Step 5: Verify + cfg list # See all your keys + cfg get GITEA_ADMIN_TOKEN # Test reading a shared key + +## Step 6: Set up your public profile + cfg profile set role "你的角色描述" + cfg profile set contact "telegram:your_handle" + cfg profile set github "your_github" + +## Step 7: Check others' profiles + cfg profiles # List all agents + cfg profile tuanzi # See tuanzi's profile + +## Troubleshooting +- "unauthorized" → token is wrong or revoked, ask admin for a new one +- "No local cache" → run cfg sync first +- Network errors → check proxy settings, config.shazhou.work uses Cloudflare`, + + admin: `# cfg — Admin Operations + +Admin commands require a token with role: admin. + +## User Management + cfg admin agents List all registered agents + cfg admin add Create agent token (role: agent) + cfg admin add --admin Create admin token + cfg admin remove Revoke ALL tokens for an agent + cfg admin refresh Revoke + create new token (rotate) + cfg admin inspect View agent's full resolved config + +## Shared Config Management + cfg set --shared Write to shared scope + cfg unset --shared Delete from shared scope + cfg flags --shared --secret Set shared key as secret + +## Onboarding a New Agent + 1. cfg admin add + 2. Send the token to the agent securely + 3. Agent runs: cfg token && cfg sync + 4. Agent sets up: eval $(cfg env) in shell + +## Offboarding / Security Isolation + 1. cfg admin remove # Revoke all tokens + 2. Agent can no longer access any config + 3. Their personal config remains in KV but is inaccessible + +## Inspecting an Agent + cfg admin inspect + # Shows all resolved keys (shared + personal overrides) + # Useful for debugging "why can't agent X see key Y" + +## Token Rotation + cfg admin refresh + # Old token immediately invalid, new token printed + # Agent must run: cfg token `, + }; + + if (!topic || topic === "general") { + console.log(topics.general); + console.log(`\n## Other Skills`); + console.log(` cfg skill contract API endpoints, KV layout, request/response format`); + console.log(` cfg skill onboarding New agent setup guide`); + console.log(` cfg skill admin Admin operations & user management`); + } else if (topics[topic]) { + console.log(topics[topic]); + } else { + console.error(`Unknown skill topic: ${topic}`); + console.log(`Available: general (default), contract, onboarding, admin`); + process.exit(1); + } } export function showHelp(): void {