mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-15 18:59:33 +01:00
fix(custom-model): give a session its own env values back when the selection goes
Applying a custom model writes the endpoint's values over the keys it injects, and clearing the model unset those keys. A session that had set one of them itself lost that value: its own DSH_HOME, CODEX_HOME, GROK_HOME or GEMINI_API_KEY was gone once the model was cleared, and so was CLAUDE_CONFIG_DIR, which silently moved a Claude session onto the default account. Switching endpoints did the same. setCustomModel() now records what the session held under each injected key and restores it on clear and on switch. Quick-start passes the caller's values to the Session constructor so they are seen before the selection lands. The selection overwrites the only other copy, tmux's setenv, so the session's own home directory has to survive a Codeman restart on its own. __customModel therefore stores that one path, the single exception to persisting keys only, and recovery runs it through clampEnvOverridesForOwner() so a revoked grant cannot bring it back. Any other own value, a credential included, stays in memory only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa463d9d28
commit
10d43b993e
12 files changed
+335
-43
No files matched your search
+13
-7
@@ -104,6 +104,7 @@ import { RunSummaryTracker } from '../run-summary.js';
|
||||
import { PlanOrchestrator } from '../plan-orchestrator.js';
|
||||
import { OrchestratorLoop } from '../orchestrator-loop.js';
|
||||
import { getLifecycleLog } from '../session-lifecycle-log.js';
|
||||
import { clampEnvOverridesForOwner } from '../session-env-clamp.js';
|
||||
import {
|
||||
applyWorkspaceHooks,
|
||||
pruneAgentSessionPreambles,
|
||||
@@ -1532,12 +1533,10 @@ export class WebServer extends EventEmitter {
|
||||
}
|
||||
try {
|
||||
// Boot recovery omits both `workingDir` (no reason to re-answer a trust dialog that
|
||||
// already fired once) and the session-env real-home lookup: the injected VALUES are
|
||||
// never persisted, so after a real restart the session can no longer carry its
|
||||
// allowlisted `DSH_HOME` either (`getEnvOverridesForPersist()` keeps only
|
||||
// `CLAUDE_CODE_*`/`CLAUDE_CONFIG_DIR`): the lookup could only ever hit on the first
|
||||
// apply in-process. Real-home resolution therefore falls back to the SERVER's
|
||||
// `DSH_HOME` or the recipe's `realHomeFallback` (~/.dsh).
|
||||
// already fired once) and the session-env real-home lookup: the first apply already
|
||||
// linked this directory from the session's own home, and `linkRealHomeEntry()` keeps
|
||||
// what is there. Only a directory someone removed gets its links again, from the
|
||||
// SERVER's `DSH_HOME` or the recipe's `realHomeFallback` (~/.dsh).
|
||||
return applyCustomModelInjection(
|
||||
entry,
|
||||
endpoint,
|
||||
@@ -1559,18 +1558,25 @@ export class WebServer extends EventEmitter {
|
||||
* while the new recipe writes one, and clearing it later could then never delete the
|
||||
* generated dir. `envKeys` is the UNION of saved and applied keys: the tmux session may
|
||||
* still carry `setenv`s from both, and a clear has to unset every one.
|
||||
*
|
||||
* `ownEnv` is always passed, empty for a record saved before it existed: `_envOverrides`
|
||||
* holds what the previous run injected, and only this record says what was the session's
|
||||
* own. It meets the owner's grant again, like every other env override rebuilt from disk.
|
||||
*/
|
||||
private async _restoreCustomModel(session: Session, saved: CustomModelBookkeeping): Promise<void> {
|
||||
const ownEnv = (await clampEnvOverridesForOwner(session.owner, saved.ownEnv)) ?? {};
|
||||
const applied = await this._rebuildCustomModelEnv(session, saved);
|
||||
if (!applied) {
|
||||
// Endpoint gone or CLI unregistered: restore the bookkeeping exactly as saved, which
|
||||
// is what a later clear needs.
|
||||
session.setCustomModel(saved);
|
||||
session.setCustomModel({ ...saved, ownEnv });
|
||||
return;
|
||||
}
|
||||
session.setCustomModel(
|
||||
{
|
||||
...saved,
|
||||
ownEnv,
|
||||
homeEnvVar: applied.homeEnvVar ?? saved.homeEnvVar,
|
||||
// Prefer the current recipe's dir; keep the saved one when the recipe writes none,
|
||||
// so a clear can still delete a directory an older recipe created.
|
||||
configDir: applied.configDir ?? saved.configDir,
|
||||
|
||||
Reference in new issue
Block a user