fcbbc4484d
Replace bottle.tokens (with Kind enum and hardcoded per-kind
route/auth tables) with bottle.cred_proxy.routes — each route
declares its own path, upstream, auth_scheme, token_ref, and
optional role[]. The manifest is now the source of truth for the
proxy's runtime route table; adding an upstream is a manifest edit,
not a code change.
Agent-side rewrites move from per-kind dispatch to per-role tags
on routes:
anthropic-base-url -> set ANTHROPIC_BASE_URL=<proxy><path>
npm-registry -> write ~/.npmrc registry=
git-insteadof -> write ~/.gitconfig [url] insteadOf, keyed
off route.upstream (suppressed when
bottle.git brokers the same host)
tea-login -> add a ~/.config/tea/config.yml login
Roles are a list (string accepted as sugar). A gitea route
typically carries ["git-insteadof", "tea-login"]. Singleton roles
(anthropic-base-url, npm-registry) appear on at most one route.
token_env slots are assigned per distinct TokenRef in declaration
order — two routes sharing a token_ref (e.g. github API + git
endpoints) share a slot.
Drops: TOKEN_KINDS, _KIND_ROUTES, _KIND_AUTH_SCHEME, _TOKEN_DEFAULT_HOST,
cred_proxy_route_path_for_gitea, the kind field on CredProxyUpstream,
and the kind-based hardcoding in pipelock_token_hosts (now derives
from route.UpstreamHost).
Legacy bottle.tokens manifests now die with a hint pointing at
bottle.cred_proxy.routes + this PRD. Tests rewritten end-to-end.
Docs + example.json + the dev ~/claude-bottle.json updated to match.
106 lines
3.0 KiB
JSON
106 lines
3.0 KiB
JSON
{
|
|
"bottles": {
|
|
"default": {
|
|
"env": {},
|
|
"egress": {
|
|
"allowlist": [
|
|
"github.com",
|
|
"objects.githubusercontent.com",
|
|
"registry.npmjs.org"
|
|
]
|
|
}
|
|
},
|
|
|
|
"gitea-dev": {
|
|
"env": {
|
|
"GITEA_TOKEN": "?paste your Gitea API token",
|
|
"GITHUB_TOKEN": "${GH_PAT}",
|
|
"GIT_AUTHOR_NAME": "Eric Diderich",
|
|
"NODE_ENV": "development"
|
|
},
|
|
"git": [
|
|
{
|
|
"Name": "claude-bottle",
|
|
"Upstream": "ssh://git@gitea.dideric.is:30009/didericis/claude-bottle.git",
|
|
"IdentityFile": "/Users/didericis/.ssh/id_ed25519_gitea",
|
|
"KnownHostKey": "ssh-ed25519 AAAA...",
|
|
"ExtraHosts": { "gitea.dideric.is": "100.78.141.42" }
|
|
}
|
|
],
|
|
"egress": {
|
|
"allowlist": [
|
|
"github.com",
|
|
"objects.githubusercontent.com",
|
|
"registry.npmjs.org",
|
|
"pypi.org",
|
|
"files.pythonhosted.org"
|
|
]
|
|
}
|
|
},
|
|
|
|
"agentic": {
|
|
"env": {
|
|
"GIT_AUTHOR_NAME": "Eric Diderich",
|
|
"NODE_ENV": "development"
|
|
},
|
|
"cred_proxy": {
|
|
"routes": [
|
|
{ "path": "/anthropic/",
|
|
"upstream": "https://api.anthropic.com",
|
|
"auth_scheme": "Bearer",
|
|
"token_ref": "CLAUDE_BOTTLE_OAUTH_TOKEN",
|
|
"role": "anthropic-base-url" },
|
|
|
|
{ "path": "/gh-api/",
|
|
"upstream": "https://api.github.com",
|
|
"auth_scheme": "Bearer",
|
|
"token_ref": "GH_PAT" },
|
|
{ "path": "/gh-git/",
|
|
"upstream": "https://github.com",
|
|
"auth_scheme": "Bearer",
|
|
"token_ref": "GH_PAT",
|
|
"role": "git-insteadof" },
|
|
|
|
{ "path": "/gitea/dideric/",
|
|
"upstream": "https://gitea.dideric.is",
|
|
"auth_scheme": "token",
|
|
"token_ref": "GITEA_TOKEN",
|
|
"role": ["git-insteadof", "tea-login"] },
|
|
|
|
{ "path": "/npm/",
|
|
"upstream": "https://registry.npmjs.org",
|
|
"auth_scheme": "Bearer",
|
|
"token_ref": "NPM_TOKEN",
|
|
"role": "npm-registry" }
|
|
]
|
|
}
|
|
}
|
|
},
|
|
|
|
"agents": {
|
|
"researcher": {
|
|
"bottle": "default",
|
|
"skills": [],
|
|
"prompt": "You are a research assistant. Read widely, summarise concisely, and cite sources by URL. Do not write code unless explicitly asked."
|
|
},
|
|
|
|
"gitea-helper": {
|
|
"bottle": "gitea-dev",
|
|
"skills": ["init-prd"],
|
|
"prompt": "You help maintain Gitea-hosted projects. Prefer small, focused commits. Follow Conventional Commits. Run tests before pushing."
|
|
},
|
|
|
|
"agentic-helper": {
|
|
"bottle": "agentic",
|
|
"skills": [],
|
|
"prompt": "You operate against APIs whose credentials live in a per-bottle cred-proxy sidecar. Your environ carries only proxy URLs."
|
|
},
|
|
|
|
"minimal": {
|
|
"bottle": "default",
|
|
"skills": [],
|
|
"prompt": ""
|
|
}
|
|
}
|
|
}
|