fix pi cwd resolution and super admin home dir for all pi endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,9 +5,8 @@ import { sessionManager } from './session-manager';
|
||||
import * as storage from './storage';
|
||||
import * as piBridge from './pi-bridge';
|
||||
import { sendClaudeCodeStreaming } from '@@/channels/send-claude-code';
|
||||
import { join, resolve } from 'path';
|
||||
import { homedir } from 'os';
|
||||
import { getHomeDir } from '../../../servers/data-path';
|
||||
import { join } from 'path';
|
||||
import { getHomeDirForRole } from '../../../servers/data-path';
|
||||
import { getUserSettings } from 'officerdb';
|
||||
import { logger } from './logger';
|
||||
|
||||
@@ -36,25 +35,16 @@ type WSData = {
|
||||
|
||||
const IDLE_TIMEOUT_MS = 60 * 60 * 1000; // 1 hour
|
||||
|
||||
const resolveSandboxedCwd = (email: string, cwdRoot?: string, cwd?: string) => {
|
||||
const root = !cwdRoot || cwdRoot === 'home' ? getHomeDir(email) : getHomeDir(email);
|
||||
const resolveCwd = (email: string, role: string, cwd?: string) => {
|
||||
const root = getHomeDirForRole(email, role);
|
||||
if (!cwd || cwd === '~') return root;
|
||||
if (cwd.startsWith('~/')) return join(root, cwd.slice(2));
|
||||
if (cwd.startsWith('/')) return join(root, cwd.slice(1));
|
||||
return root;
|
||||
};
|
||||
|
||||
const resolveHostCwd = (cwdRoot?: string, cwd?: string) => {
|
||||
if (cwdRoot === 'officer.dev') return resolve(process.cwd(), '..');
|
||||
const root = homedir();
|
||||
if (!cwd || cwd === '~') return root;
|
||||
if (cwd.startsWith('/')) return cwd;
|
||||
if (cwd.startsWith('~/')) return join(root, cwd.slice(2));
|
||||
return join(root, cwd);
|
||||
};
|
||||
|
||||
export const resolveBaseCwd = (email: string, cwdRoot?: string, cwd?: string) => {
|
||||
return resolveHostCwd(cwdRoot, cwd);
|
||||
export const resolveBaseCwd = (email: string, role: string, cwd?: string) => {
|
||||
return resolveCwd(email, role, cwd);
|
||||
};
|
||||
|
||||
const wsToSessionMap = new WeakMap<any, string>();
|
||||
@@ -289,10 +279,8 @@ async function handleChat(
|
||||
return handleClaudeCodeChat(ws, sessionId, model, msg);
|
||||
}
|
||||
|
||||
const homeDir = getHomeDir(email);
|
||||
const cwd = ws.data.sandboxed
|
||||
? resolveSandboxedCwd(email, msg.cwdRoot, msg.cwd)
|
||||
: resolveHostCwd(msg.cwdRoot, msg.cwd);
|
||||
const homeDir = getHomeDirForRole(email, ws.data.role);
|
||||
const cwd = resolveCwd(email, ws.data.role, msg.cwd);
|
||||
const groupSlug = msg.groupSlug || null;
|
||||
const session = sessionManager.getOrCreate(sessionId, email, cwd, model, groupSlug, msg.context, msg.contextId);
|
||||
session.userId = userId;
|
||||
@@ -312,15 +300,15 @@ async function handleChat(
|
||||
const onEvent = createEventHandler(sessionId, model, cwd, homeDir);
|
||||
|
||||
// If session has history, save to disk and pass --session for context replay
|
||||
let spawnOptions: { sessionFile?: string; username?: string } | undefined;
|
||||
let spawnOptions: { sessionFile?: string; username?: string; role?: string } | undefined;
|
||||
if (session.messages.length > 0) {
|
||||
await storage.saveSession(homeDir, sessionId, session.meta, session.messages);
|
||||
const hostPath = await storage.getSessionFilePath(homeDir, sessionId);
|
||||
if (hostPath) {
|
||||
spawnOptions = { sessionFile: hostPath, username };
|
||||
spawnOptions = { sessionFile: hostPath, username, role: ws.data.role };
|
||||
}
|
||||
}
|
||||
if (!spawnOptions) spawnOptions = { username };
|
||||
if (!spawnOptions) spawnOptions = { username, role: ws.data.role };
|
||||
|
||||
session.piProcess = await piBridge.spawnPi(cwd, model, userId, email, onEvent, spawnOptions);
|
||||
|
||||
@@ -389,11 +377,9 @@ async function handleClaudeCodeChat(
|
||||
},
|
||||
): Promise<void> {
|
||||
const { email, username, userId } = ws.data;
|
||||
const homeDir = getHomeDir(email);
|
||||
const homeDir = getHomeDirForRole(email, ws.data.role);
|
||||
|
||||
const cwd = ws.data.sandboxed
|
||||
? resolveSandboxedCwd(email, msg.cwdRoot, msg.cwd)
|
||||
: resolveHostCwd(msg.cwdRoot, msg.cwd);
|
||||
const cwd = resolveCwd(email, ws.data.role, msg.cwd);
|
||||
|
||||
const groupSlug = msg.groupSlug || null;
|
||||
|
||||
@@ -468,7 +454,7 @@ async function handleResume(
|
||||
let session = sessionManager.getSession(sessionId);
|
||||
|
||||
if (!session) {
|
||||
const homeDir = getHomeDir(email);
|
||||
const homeDir = getHomeDirForRole(email, ws.data.role);
|
||||
|
||||
try {
|
||||
const { meta, messages } = await storage.loadSession(homeDir, sessionId);
|
||||
@@ -500,19 +486,19 @@ async function handleResume(
|
||||
// Spawn fresh Pi process if needed
|
||||
if (!session.piProcess) {
|
||||
try {
|
||||
const homeDir = getHomeDir(email);
|
||||
const homeDir = getHomeDirForRole(email, ws.data.role);
|
||||
const onEvent = createEventHandler(sessionId, session.model, session.cwd, homeDir);
|
||||
|
||||
// If session has history, save to disk and pass --session for context replay
|
||||
let spawnOptions: { sessionFile?: string; username?: string } | undefined;
|
||||
let spawnOptions: { sessionFile?: string; username?: string; role?: string } | undefined;
|
||||
if (session.messages.length > 0) {
|
||||
await storage.saveSession(homeDir, sessionId, session.meta, session.messages);
|
||||
const hostPath = await storage.getSessionFilePath(homeDir, sessionId);
|
||||
if (hostPath) {
|
||||
spawnOptions = { sessionFile: hostPath, username: ws.data.username };
|
||||
spawnOptions = { sessionFile: hostPath, username: ws.data.username, role: ws.data.role };
|
||||
}
|
||||
}
|
||||
if (!spawnOptions) spawnOptions = { username: ws.data.username };
|
||||
if (!spawnOptions) spawnOptions = { username: ws.data.username, role: ws.data.role };
|
||||
|
||||
session.piProcess = await piBridge.spawnPi(
|
||||
session.cwd,
|
||||
|
||||
Reference in New Issue
Block a user