aicodeman 1.28.2 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/attachment-registry.d.ts +20 -0
- package/dist/attachment-registry.d.ts.map +1 -1
- package/dist/attachment-registry.js +75 -10
- package/dist/attachment-registry.js.map +1 -1
- package/dist/config/cli-registry/schema.d.ts +25 -0
- package/dist/config/cli-registry/schema.d.ts.map +1 -1
- package/dist/config/cli-registry/schema.js +43 -0
- package/dist/config/cli-registry/schema.js.map +1 -1
- package/dist/config/cli-registry/stock.d.ts.map +1 -1
- package/dist/config/cli-registry/stock.js +157 -2
- package/dist/config/cli-registry/stock.js.map +1 -1
- package/dist/config/cli-registry/types.d.ts +60 -0
- package/dist/config/cli-registry/types.d.ts.map +1 -1
- package/dist/custom-model-hosts.d.ts +39 -0
- package/dist/custom-model-hosts.d.ts.map +1 -0
- package/dist/custom-model-hosts.js +35 -0
- package/dist/custom-model-hosts.js.map +1 -0
- package/dist/custom-model-injection-apply.d.ts +49 -0
- package/dist/custom-model-injection-apply.d.ts.map +1 -0
- package/dist/custom-model-injection-apply.js +77 -0
- package/dist/custom-model-injection-apply.js.map +1 -0
- package/dist/custom-model-injection.d.ts +79 -0
- package/dist/custom-model-injection.d.ts.map +1 -0
- package/dist/custom-model-injection.js +169 -0
- package/dist/custom-model-injection.js.map +1 -0
- package/dist/docker-hosts.d.ts +42 -0
- package/dist/docker-hosts.d.ts.map +1 -1
- package/dist/docker-hosts.js +18 -0
- package/dist/docker-hosts.js.map +1 -1
- package/dist/generated-artifact-attachments.d.ts +3 -0
- package/dist/generated-artifact-attachments.d.ts.map +1 -1
- package/dist/generated-artifact-attachments.js +18 -8
- package/dist/generated-artifact-attachments.js.map +1 -1
- package/dist/mux-interface.d.ts +7 -0
- package/dist/mux-interface.d.ts.map +1 -1
- package/dist/remote-files.d.ts +145 -0
- package/dist/remote-files.d.ts.map +1 -0
- package/dist/remote-files.js +347 -0
- package/dist/remote-files.js.map +1 -0
- package/dist/remote-hosts.d.ts +12 -0
- package/dist/remote-hosts.d.ts.map +1 -1
- package/dist/remote-hosts.js +7 -1
- package/dist/remote-hosts.js.map +1 -1
- package/dist/remote-ssh-limiter.d.ts +42 -0
- package/dist/remote-ssh-limiter.d.ts.map +1 -0
- package/dist/remote-ssh-limiter.js +84 -0
- package/dist/remote-ssh-limiter.js.map +1 -0
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +8 -1
- package/dist/session-manager.js.map +1 -1
- package/dist/session.d.ts +79 -2
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +163 -2
- package/dist/session.js.map +1 -1
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +27 -13
- package/dist/tmux-manager.js.map +1 -1
- package/dist/types/api.d.ts +6 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/api.js.map +1 -1
- package/dist/types/session.d.ts +30 -0
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/session.js.map +1 -1
- package/dist/web/middleware/auth.d.ts +11 -1
- package/dist/web/middleware/auth.d.ts.map +1 -1
- package/dist/web/middleware/auth.js +69 -1
- package/dist/web/middleware/auth.js.map +1 -1
- package/dist/web/public/admin-ui.js.gz +0 -0
- package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
- package/dist/web/public/{app.78bf0bf8.js → app.556be563.js} +7 -7
- package/dist/web/public/app.556be563.js.br +0 -0
- package/dist/web/public/app.556be563.js.gz +0 -0
- package/dist/web/public/approvals-ui.js.gz +0 -0
- package/dist/web/public/constants.258b140f.js.gz +0 -0
- package/dist/web/public/cron-ui.js.gz +0 -0
- package/dist/web/public/entrance-animations.js.gz +0 -0
- package/dist/web/public/home-sessions.js.gz +0 -0
- package/dist/web/public/i18n.561ca09c.js.gz +0 -0
- package/dist/web/public/image-input.cd4b97c4.js.gz +0 -0
- package/dist/web/public/index.html +14 -7
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/input-cjk.8bc46081.js +1 -0
- package/dist/web/public/input-cjk.8bc46081.js.br +0 -0
- package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
- package/dist/web/public/{keyboard-accessory.1d0dda9b.js → keyboard-accessory.2cf04f17.js} +38 -3
- package/dist/web/public/keyboard-accessory.2cf04f17.js.br +0 -0
- package/dist/web/public/keyboard-accessory.2cf04f17.js.gz +0 -0
- package/dist/web/public/mobile-handlers.6f354a87.js.gz +0 -0
- package/dist/web/public/mobile-overview.js.gz +0 -0
- package/dist/web/public/mobile.e9d0b53e.css.gz +0 -0
- package/dist/web/public/notification-manager.36ea4624.js.gz +0 -0
- package/dist/web/public/orchestrator-panel.js.gz +0 -0
- package/dist/web/public/panels-ui.5b07ad14.js.gz +0 -0
- package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
- package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
- package/dist/web/public/readmymind-ui.js.gz +0 -0
- package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
- package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
- package/dist/web/public/session-lineage.js.gz +0 -0
- package/dist/web/public/{session-ui.5d0a7b15.js → session-ui.42b81477.js} +13 -13
- package/dist/web/public/session-ui.42b81477.js.br +0 -0
- package/dist/web/public/session-ui.42b81477.js.gz +0 -0
- package/dist/web/public/settings-ui.e0c7f6b4.js.gz +0 -0
- package/dist/web/public/{styles.5d36726d.css → styles.6add175d.css} +1 -1
- package/dist/web/public/styles.6add175d.css.br +0 -0
- package/dist/web/public/{styles.5d36726d.css.gz → styles.6add175d.css.gz} +0 -0
- package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/tab-rail-resize.42c24949.js.gz +0 -0
- package/dist/web/public/terminal-keycode229-recovery.6ea8fe37.js.gz +0 -0
- package/dist/web/public/terminal-ui.38c49244.js +2 -0
- package/dist/web/public/terminal-ui.38c49244.js.br +0 -0
- package/dist/web/public/terminal-ui.38c49244.js.gz +0 -0
- package/dist/web/public/ultracode-panel.js.gz +0 -0
- package/dist/web/public/ultracode-windows.js.gz +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
- package/dist/web/public/vendor/marked.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-predictive-echo.bd6882b8.js.gz +0 -0
- package/dist/web/public/vendor/xterm-zerolag-input.6fee72f2.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/voice-input.c4b51eb6.js.gz +0 -0
- package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
- package/dist/web/public/webview-tabs.js +56 -4
- package/dist/web/public/webview-tabs.js.br +0 -0
- package/dist/web/public/webview-tabs.js.gz +0 -0
- package/dist/web/route-helpers.d.ts +20 -0
- package/dist/web/route-helpers.d.ts.map +1 -1
- package/dist/web/route-helpers.js +29 -2
- package/dist/web/route-helpers.js.map +1 -1
- package/dist/web/routes/case-routes.d.ts.map +1 -1
- package/dist/web/routes/case-routes.js +23 -6
- package/dist/web/routes/case-routes.js.map +1 -1
- package/dist/web/routes/custom-model-routes.d.ts +18 -0
- package/dist/web/routes/custom-model-routes.d.ts.map +1 -0
- package/dist/web/routes/custom-model-routes.js +136 -0
- package/dist/web/routes/custom-model-routes.js.map +1 -0
- package/dist/web/routes/file-routes.d.ts.map +1 -1
- package/dist/web/routes/file-routes.js +484 -100
- package/dist/web/routes/file-routes.js.map +1 -1
- package/dist/web/routes/index.d.ts +1 -0
- package/dist/web/routes/index.d.ts.map +1 -1
- package/dist/web/routes/index.js +1 -0
- package/dist/web/routes/index.js.map +1 -1
- package/dist/web/routes/session-routes.d.ts.map +1 -1
- package/dist/web/routes/session-routes.js +81 -1
- package/dist/web/routes/session-routes.js.map +1 -1
- package/dist/web/routes/ws-routes.d.ts.map +1 -1
- package/dist/web/routes/ws-routes.js +26 -2
- package/dist/web/routes/ws-routes.js.map +1 -1
- package/dist/web/schemas.d.ts +20 -0
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +31 -0
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +8 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +65 -3
- package/dist/web/server.js.map +1 -1
- package/dist/web/webview-proxy.d.ts +41 -0
- package/dist/web/webview-proxy.d.ts.map +1 -1
- package/dist/web/webview-proxy.js +102 -1
- package/dist/web/webview-proxy.js.map +1 -1
- package/package.json +2 -2
- package/dist/web/public/app.78bf0bf8.js.br +0 -0
- package/dist/web/public/app.78bf0bf8.js.gz +0 -0
- package/dist/web/public/input-cjk.87f14251.js +0 -1
- package/dist/web/public/input-cjk.87f14251.js.br +0 -0
- package/dist/web/public/input-cjk.87f14251.js.gz +0 -0
- package/dist/web/public/keyboard-accessory.1d0dda9b.js.br +0 -0
- package/dist/web/public/keyboard-accessory.1d0dda9b.js.gz +0 -0
- package/dist/web/public/session-ui.5d0a7b15.js.br +0 -0
- package/dist/web/public/session-ui.5d0a7b15.js.gz +0 -0
- package/dist/web/public/styles.5d36726d.css.br +0 -0
- package/dist/web/public/terminal-ui.0cbe8637.js +0 -2
- package/dist/web/public/terminal-ui.0cbe8637.js.br +0 -0
- package/dist/web/public/terminal-ui.0cbe8637.js.gz +0 -0
package/dist/web/server.js
CHANGED
|
@@ -56,6 +56,9 @@ import { subagentWatcher, } from '../subagent-watcher.js';
|
|
|
56
56
|
import { imageWatcher } from '../image-watcher.js';
|
|
57
57
|
import { workflowRunWatcher, summarizeRun } from '../workflow-run-watcher.js';
|
|
58
58
|
import { attachmentRegistry, buildFileThumbnailRoute, registerExternalAttachment } from '../attachment-registry.js';
|
|
59
|
+
import { getCli } from '../config/cli-registry/registry.js';
|
|
60
|
+
import { readCustomModelHosts } from '../custom-model-hosts.js';
|
|
61
|
+
import { applyCustomModelInjection, customModelConfigDir, removeConfigDir } from '../custom-model-injection-apply.js';
|
|
59
62
|
import { registerGeneratedArtifactAttachment } from '../generated-artifact-attachments.js';
|
|
60
63
|
import { buildDetectedAttachmentHistoryItem, buildExternalAttachmentHistoryItem, } from '../session-attachment-history.js';
|
|
61
64
|
import { TranscriptWatcher } from '../transcript-watcher.js';
|
|
@@ -103,12 +106,13 @@ import { SseEvent } from './sse-events.js';
|
|
|
103
106
|
import { getLatestPlanUsage, setLatestCodexPlanUsage } from './plan-usage-latest.js';
|
|
104
107
|
import { telemetrySignature } from '../usage-telemetry.js';
|
|
105
108
|
import { readCodexPlanUsage, resolveCodexBinaryPath } from '../utils/codex-cli-resolver.js';
|
|
106
|
-
import { registerAuthMiddleware, registerSecurityHeaders, registerHostGuard } from './middleware/auth.js';
|
|
109
|
+
import { registerAuthMiddleware, registerSecurityHeaders, registerHostGuard, isLostWebviewRootFrame, sendLostWebviewFramePage, } from './middleware/auth.js';
|
|
107
110
|
import { isMultiUserMode } from '../config/multiuser.js';
|
|
108
111
|
import { bootstrapInitialAdmin, hasUsers, resolveClaudeModeForUsername } from '../user-store.js';
|
|
109
112
|
import { installRouteErrorHandler } from './route-error-handler.js';
|
|
110
113
|
import { isExplicitlyEnabled, isLoopbackBindHost, buildHostPolicy } from './network-auth-policy.js';
|
|
111
|
-
import { registerPushRoutes, registerTeamRoutes, registerMuxRoutes, registerFileRoutes, registerScheduledRoutes, registerHookEventRoutes, registerApprovalRoutes, registerReadMyMindRoutes, registerStatusTelemetryRoutes, registerSystemRoutes, registerCaseRoutes, registerSessionRoutes, registerRespawnRoutes, registerRalphRoutes, registerPlanRoutes, registerClipboardRoutes, registerSearchRoutes, registerOrchestratorRoutes, registerCronRoutes, registerMeRoutes, registerAdminRoutes, registerWsRoutes, registerVoiceRoutes, registerWebviewRoutes, registerTabLayoutRoutes, tryWebviewRefererFallback, } from './routes/index.js';
|
|
114
|
+
import { registerPushRoutes, registerTeamRoutes, registerMuxRoutes, registerFileRoutes, registerScheduledRoutes, registerHookEventRoutes, registerApprovalRoutes, registerReadMyMindRoutes, registerStatusTelemetryRoutes, registerSystemRoutes, registerCaseRoutes, registerSessionRoutes, registerRespawnRoutes, registerRalphRoutes, registerPlanRoutes, registerClipboardRoutes, registerSearchRoutes, registerOrchestratorRoutes, registerCronRoutes, registerMeRoutes, registerAdminRoutes, registerWsRoutes, registerVoiceRoutes, registerWebviewRoutes, registerTabLayoutRoutes, registerCustomModelRoutes, tryWebviewRefererFallback, } from './routes/index.js';
|
|
115
|
+
import { isLostWebviewFrameNavigation } from './webview-proxy.js';
|
|
112
116
|
import { CronService } from '../cron/cron-service.js';
|
|
113
117
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
114
118
|
// Bounded, predictable shape for SSE client identifiers: alphanumerics, `_`, `-`.
|
|
@@ -648,7 +652,15 @@ export class WebServer extends EventEmitter {
|
|
|
648
652
|
});
|
|
649
653
|
// Security headers + CORS
|
|
650
654
|
registerSecurityHeaders(this.app, this.https, this.basePath);
|
|
651
|
-
this.app.get('/', async (
|
|
655
|
+
this.app.get('/', async (req, reply) => {
|
|
656
|
+
// A web-tab frame that reloaded on its dashboard's landing page. The proxy's
|
|
657
|
+
// runtime shim maps `/webview/<cap>/` to exactly `/`, so that reload asks for
|
|
658
|
+
// Codeman's own root as an iframe navigation, and it used to get the app
|
|
659
|
+
// shell rendered inside the web tab. Only the credential-free form is taken
|
|
660
|
+
// (nothing in Codeman frames its root; the sandboxed frame has no cookie and
|
|
661
|
+
// no Authorization); under a password the auth hook has answered it already.
|
|
662
|
+
if (isLostWebviewRootFrame(req))
|
|
663
|
+
return sendLostWebviewFramePage(reply);
|
|
652
664
|
return reply
|
|
653
665
|
.header('Cache-Control', 'no-cache')
|
|
654
666
|
.type('text/html; charset=utf-8')
|
|
@@ -813,6 +825,12 @@ export class WebServer extends EventEmitter {
|
|
|
813
825
|
// genuinely unknown `/api` paths still get the envelope below.
|
|
814
826
|
if (await tryWebviewRefererFallback(req, reply, this.basePath))
|
|
815
827
|
return reply;
|
|
828
|
+
// An authenticated web-tab frame (Basic auth, or trusted mode with a cookie)
|
|
829
|
+
// that navigated itself off its proxy prefix: the runtime shim masks the
|
|
830
|
+
// prefix so the page's router sees its own path, and a reload of that page
|
|
831
|
+
// lands here. The unauthenticated form is answered in the auth middleware.
|
|
832
|
+
if (!req.url.startsWith('/api') && isLostWebviewFrameNavigation(req))
|
|
833
|
+
return sendLostWebviewFramePage(reply);
|
|
816
834
|
if (req.url.startsWith('/api')) {
|
|
817
835
|
return reply.code(404).send(createErrorResponse(ApiErrorCode.NOT_FOUND, notFound));
|
|
818
836
|
}
|
|
@@ -890,6 +908,7 @@ export class WebServer extends EventEmitter {
|
|
|
890
908
|
registerOrchestratorRoutes(this.app, ctx);
|
|
891
909
|
registerWebviewRoutes(this.app, ctx, this.basePath);
|
|
892
910
|
registerTabLayoutRoutes(this.app, ctx);
|
|
911
|
+
registerCustomModelRoutes(this.app);
|
|
893
912
|
// Cron: build the service from the same context, recompute
|
|
894
913
|
// due times for any persisted jobs, then expose it to its routes.
|
|
895
914
|
this.cronService = new CronService(ctx);
|
|
@@ -986,6 +1005,30 @@ export class WebServer extends EventEmitter {
|
|
|
986
1005
|
}
|
|
987
1006
|
});
|
|
988
1007
|
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Recovery half of Custom Model Endpoint Profiles: the env values a selection injects
|
|
1010
|
+
* are never persisted (they carry the API key), so they are computed again from the
|
|
1011
|
+
* endpoint store, through the SAME apply path the route uses. Undefined when the
|
|
1012
|
+
* endpoint is gone or the CLI is unregistered: the bookkeeping is still restored so
|
|
1013
|
+
* the selection can be cleared, and the pane keeps running on tmux's retained env.
|
|
1014
|
+
*/
|
|
1015
|
+
async _rebuildCustomModelEnv(session, saved) {
|
|
1016
|
+
const entry = getCli(session.mode);
|
|
1017
|
+
if (!entry)
|
|
1018
|
+
return undefined;
|
|
1019
|
+
const endpoint = (await readCustomModelHosts(getDataDir())).find((h) => h.id === saved.endpointId);
|
|
1020
|
+
if (!endpoint) {
|
|
1021
|
+
console.warn(`[WebServer] custom-model endpoint ${saved.endpointId} no longer exists; selection kept for clearing`);
|
|
1022
|
+
return undefined;
|
|
1023
|
+
}
|
|
1024
|
+
try {
|
|
1025
|
+
return applyCustomModelInjection(entry, endpoint, saved.modelId, session.id)?.envOverrides;
|
|
1026
|
+
}
|
|
1027
|
+
catch (err) {
|
|
1028
|
+
console.warn('[WebServer] Failed to rebuild custom-model env on recovery:', err);
|
|
1029
|
+
return undefined;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
989
1032
|
/** Persists full session state including respawn config to state.json */
|
|
990
1033
|
_persistSessionStateNow(session) {
|
|
991
1034
|
// See session-manager.updateSessionState: __envOverrides is an internal disk-only
|
|
@@ -995,10 +1038,14 @@ export class WebServer extends EventEmitter {
|
|
|
995
1038
|
// __attachmentHistory keeps the private (externalPath-bearing) history on disk,
|
|
996
1039
|
// separate from the sanitized public attachmentHistory in toState().
|
|
997
1040
|
const attachmentHistory = session.getAttachmentHistoryForPersist();
|
|
1041
|
+
// __customModel keeps the selection's bookkeeping (injected env KEYS, config dir,
|
|
1042
|
+
// launch model; never the values) so recovery can restore and later clear it.
|
|
1043
|
+
const customModel = session.getCustomModelForPersist();
|
|
998
1044
|
const state = {
|
|
999
1045
|
...base,
|
|
1000
1046
|
...(envOverrides ? { __envOverrides: envOverrides } : {}),
|
|
1001
1047
|
...(attachmentHistory ? { __attachmentHistory: attachmentHistory } : {}),
|
|
1048
|
+
...(customModel ? { __customModel: customModel } : {}),
|
|
1002
1049
|
};
|
|
1003
1050
|
const controller = this.respawnControllers.get(session.id);
|
|
1004
1051
|
if (controller) {
|
|
@@ -1177,6 +1224,9 @@ export class WebServer extends EventEmitter {
|
|
|
1177
1224
|
// come back to a loader whose file we deleted.
|
|
1178
1225
|
if (killMux) {
|
|
1179
1226
|
void removeAgentSessionPreamble(sessionId);
|
|
1227
|
+
// The per-session custom-model config dir carries the endpoint's API key (pi and
|
|
1228
|
+
// omp embed it literally); it must not outlive the session it was written for.
|
|
1229
|
+
removeConfigDir(customModelConfigDir(sessionId));
|
|
1180
1230
|
}
|
|
1181
1231
|
await session.stop(killMux);
|
|
1182
1232
|
this.sessions.delete(sessionId);
|
|
@@ -1465,10 +1515,12 @@ export class WebServer extends EventEmitter {
|
|
|
1465
1515
|
sessionId,
|
|
1466
1516
|
filePath,
|
|
1467
1517
|
sessionWorkingDir: session.workingDir,
|
|
1518
|
+
remote: session.remote,
|
|
1468
1519
|
})
|
|
1469
1520
|
: await registerExternalAttachment(sessionId, filePath, {
|
|
1470
1521
|
sessionWorkingDir: session.workingDir,
|
|
1471
1522
|
forceWorkspaceConfinement: true,
|
|
1523
|
+
remote: session.remote,
|
|
1472
1524
|
});
|
|
1473
1525
|
const record = attachmentRegistry.get(sessionId, event.attachmentId);
|
|
1474
1526
|
if (record) {
|
|
@@ -2449,6 +2501,7 @@ export class WebServer extends EventEmitter {
|
|
|
2449
2501
|
// Note: a legacy CLAUDE_CODE_EFFORT_LEVEL entry is auto-migrated to `effort`
|
|
2450
2502
|
// by the Session constructor (env var would hard-lock /effort switching).
|
|
2451
2503
|
const savedEnvOverrides = savedState?.__envOverrides;
|
|
2504
|
+
const savedCustomModel = savedState?.__customModel;
|
|
2452
2505
|
// Prefer the private (externalPath-bearing) history; fall back to the
|
|
2453
2506
|
// sanitized public copy for sessions persisted before that split.
|
|
2454
2507
|
const savedAttachmentHistory = savedState?.__attachmentHistory ??
|
|
@@ -2509,6 +2562,15 @@ export class WebServer extends EventEmitter {
|
|
|
2509
2562
|
// when both tabs are on screen.
|
|
2510
2563
|
parentSessionId: savedState?.parentSessionId,
|
|
2511
2564
|
});
|
|
2565
|
+
// Custom-model selection survives the restart. The tmux session still carries
|
|
2566
|
+
// the injected `setenv`s (that is what kept the pane on the endpoint across the
|
|
2567
|
+
// restart), but `_envOverrides` is rebuilt from a persist that deliberately
|
|
2568
|
+
// excludes them, so re-derive the values from the endpoint store and re-write
|
|
2569
|
+
// the isolated config dir; an endpoint that has since been deleted still gets
|
|
2570
|
+
// the bookkeeping restored, which is what a later clear needs to unset.
|
|
2571
|
+
if (savedCustomModel) {
|
|
2572
|
+
session.setCustomModel(savedCustomModel, await this._rebuildCustomModelEnv(session, savedCustomModel));
|
|
2573
|
+
}
|
|
2512
2574
|
// Update session name if it was a "Restored:" placeholder or doesn't match saved name
|
|
2513
2575
|
if (savedState?.name && muxSession.name !== savedState.name) {
|
|
2514
2576
|
this.mux.updateSessionName(muxSession.sessionId, savedState.name);
|