diff --git a/lib/pi-provider.js b/lib/pi-provider.js index 210291d..c4efd81 100644 --- a/lib/pi-provider.js +++ b/lib/pi-provider.js @@ -14,7 +14,18 @@ let operationId = 0; function resolvePiModelsConfigFile(env = process.env) { const configured = String(env.PI_MODELS_CONFIG || '').trim(); - return configured ? path.resolve(configured) : path.join(os.homedir(), '.pi', 'agent', 'models.json'); + if (configured) return path.resolve(configured); + + const candidates = []; + if (process.getuid && process.getuid() === 0) { + candidates.push('/home/sts/.pi/agent/models.json'); + } + candidates.push(path.join(os.homedir(), '.pi', 'agent', 'models.json')); + candidates.push('/root/.pi/agent/models.json'); + + return candidates.find((candidate) => { + try { return fs.existsSync(path.dirname(candidate)) || fs.existsSync(candidate); } catch (_) { return false; } + }) || candidates[0]; } function normalizeBaseUrl(baseUrl) { @@ -75,16 +86,41 @@ function readConfig(configFile) { function writeConfigAtomic(configFile, config) { const dir = path.dirname(configFile); + const owner = resolveOwnerForPath(dir); fs.mkdirSync(dir, { recursive: true }); + chownIfPossible(dir, owner); const tempFile = path.join(dir, `.${path.basename(configFile)}.${process.pid}.${Date.now()}.tmp`); try { fs.writeFileSync(tempFile, `${JSON.stringify(config, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 }); fs.renameSync(tempFile, configFile); + chownIfPossible(configFile, owner); } finally { try { fs.unlinkSync(tempFile); } catch (_) {} } } +function resolveOwnerForPath(targetPath) { + let current = targetPath; + while (current && current !== path.dirname(current)) { + try { + const stat = fs.statSync(current); + return { uid: stat.uid, gid: stat.gid }; + } catch (_) { + current = path.dirname(current); + } + } + return null; +} + +function chownIfPossible(targetPath, owner) { + if (!owner || !(process.getuid && process.getuid() === 0)) return; + try { + fs.chownSync(targetPath, owner.uid, owner.gid); + } catch (error) { + log.warn('pi-provider', `chown failed for ${targetPath}: ${error.message}`); + } +} + function sameModels(left, right) { const ids = (models) => (models || []).map((model) => model.id).sort(); return JSON.stringify(ids(left)) === JSON.stringify(ids(right));