Symptoms before this PR:
- After ~60 min of workspace uptime, every git push/clone returns 401
- PMM, DevRel, Social Media Brand and other content agents infinite-loop
status reports back to PMs ("I tried, GH_TOKEN dead")
- PM A2A queues overflow with retry-status messages (depth 27 on Marketing
Lead, 18 on Dev Lead, 11 on Core Platform Lead at peak)
Root cause:
- GH_TOKEN/GITHUB_TOKEN injected at provision time has a ~60 min TTL
(GitHub App installation tokens cap at one hour)
- Workspace env is frozen at container start — no in-process mechanism
to refresh after expiry
- The credential-helper architecture exists in the codebase but was
never wired up at template boot. Specifically the claude-code template:
- did not COPY the helper scripts into the image
- did not configure git credential.helper at boot
- did not start the background refresh daemon
- did not run initial gh auth login
Fix:
1. Dockerfile COPYs scripts/molecule-git-token-helper.sh and
scripts/molecule-gh-token-refresh.sh into /app/scripts/
2. entrypoint.sh (root half) configures git credential helper for
github.com and creates the per-user token cache directory
3. entrypoint.sh (agent half) starts the refresh daemon under a
respawn loop and runs initial `gh auth login --with-token`
The helper hits the platform's /admin/github-installation-token endpoint
(fallback to env-var GH_TOKEN when platform unreachable). The refresh
daemon calls _refresh_gh every ~45 min ± 2 min jitter so cli auth and
helper cache stay warm even when no git operation triggers a refresh.
Acceptance:
- After this image deploys, `gh api /user` from inside a workspace
should keep returning 200 even after >60 min uptime
- Marketing Lead / Dev Lead a2a queues should drain to <5 within one
cycle of the new image rolling
Follow-up issues to file (not in this PR):
- Replicate this wiring in the other 7 template repos (autogen, crewai,
deepagents, gemini-cli, hermes, langgraph, openclaw)
- Lift the wiring into the molecule-runtime PyPI package so future
templates inherit it instead of re-implementing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Removes the .auth-token file (containing a live API key) from git history.
The file was committed in the initial commit (b8859da, Apr 16) but is now
replaced with an empty placeholder in this branch.
Also adds .github/workflows/publish-image.yml for GHCR image publishing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The .auth-token file committed in b8859da contains a live API key.
Remove it from git history and add CI publish-image workflow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Recovered from prior work. Previously pushed commit 03c6929
was lost during reset-to-origin/main divergence resolution.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude Code supports two auth paths that use different env vars:
- OAuth (via `claude login`) → CLAUDE_CODE_OAUTH_TOKEN, tied to a
Claude Code subscription
- Direct API key → ANTHROPIC_API_KEY, pay-as-you-go via the Anthropic
Console
Previously the template only listed CLAUDE_CODE_OAUTH_TOKEN, hiding the
API-key path and forcing API-key users to override manually. Now
models[] exposes both as distinct dropdown entries — users pick the
one matching the credential they have; canvas auto-suggests the right
env var.
Model IDs differ intentionally:
- OAuth entries use CLI aliases (sonnet/opus/haiku — resolve to latest)
- API-key entries use explicit versioned ids (claude-sonnet-4-6, etc.)
claude CLI accepts either auth style transparently — OAuth wins when
both are set, which preserves existing workspace behaviour.
Paired with Molecule-AI/molecule-core#1526 (platform + canvas).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the scripts required by validate-workspace-template.yml:
- .molecule-ci/scripts/validate-workspace-template.py
- .molecule-ci/scripts/requirements.txt
Co-authored-by: Molecule AI Plugin-Dev <plugin-dev@agents.moleculesai.app>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds standard credential gitignore (.env / *.pem / .secrets/ / .auth_token).
Per-CEO directive 2026-04-16: every plugin and template repo should
gitignore credentials so self-hosters can't accidentally commit real
tokens to public repos.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>