fix: sync refreshed OAuth tokens to process.env for container exec

Token refresh updated internal array and .env file but not process.env,
so docker exec -e kept injecting the stale startup token. Now syncs
to process.env after refresh. Container kill on refresh is no longer
needed since docker exec picks up the latest token each turn.
This commit is contained in:
Eyejoker
2026-03-31 13:34:21 +09:00
parent bfe164dece
commit 47d532e869
2 changed files with 15 additions and 39 deletions

View File

@@ -192,47 +192,13 @@ export function stopReviewerContainer(groupFolder: string): void {
} }
/** /**
* Remove all running reviewer containers so they are recreated on the next * No-op — container recreation is no longer needed after token refresh.
* reviewer turn with fresh credentials. Called after token rotation/refresh * Tokens are now synced to process.env, and `docker exec -e` injects
* because the persistent container's Claude Code SDK process holds the token * the latest token at each turn. Kept as a no-op to avoid breaking callers.
* that was baked in at `docker run` time — `docker exec -e` only updates the
* env for newly spawned processes, not the already-running SDK.
*/ */
export function recreateAllReviewerContainers(): void { export function recreateAllReviewerContainers(): void {
try { // Intentionally empty — docker exec -e picks up refreshed tokens
const output = execFileSync( // from process.env without needing to recreate the container.
CONTAINER_RUNTIME_BIN,
['ps', '--filter', 'name=ejclaw-reviewer-', '--format', '{{.Names}}'],
{ encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 10000 },
).trim();
const containers = output.split('\n').filter(Boolean);
if (containers.length === 0) {
logger.debug('No reviewer containers to recreate after token refresh');
return;
}
for (const name of containers) {
try {
execFileSync(CONTAINER_RUNTIME_BIN, ['rm', '-f', name], {
stdio: 'pipe',
timeout: 10000,
});
} catch {
/* already gone */
}
}
logger.info(
{ count: containers.length, names: containers },
'Removed reviewer containers after token refresh — will recreate on next turn',
);
} catch (err) {
logger.warn(
{ err },
'Failed to list/remove reviewer containers after token refresh',
);
}
} }
// ── Mount builder ───────────────────────────────────────────────── // ── Mount builder ─────────────────────────────────────────────────

View File

@@ -316,6 +316,16 @@ async function checkAndRefreshAll(): Promise<void> {
} }
if (anyRefreshed) { if (anyRefreshed) {
// Sync refreshed tokens to process.env so docker exec picks them up
const refreshedTokens = getAllTokens();
if (refreshedTokens.length > 0) {
process.env.CLAUDE_CODE_OAUTH_TOKEN = refreshedTokens[0].token;
if (refreshedTokens.length > 1) {
process.env.CLAUDE_CODE_OAUTH_TOKENS = refreshedTokens
.map((t) => t.token)
.join(',');
}
}
updateEnvTokens(); updateEnvTokens();
if (onTokenRefreshedCallback) { if (onTokenRefreshedCallback) {
try { try {