From 0aa8934fb377c218a729fc478e2a6e209e9c7cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=82CHES?= Date: Mon, 16 Mar 2026 20:29:09 -0600 Subject: [PATCH] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/resource-loader.ts | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/resource-loader.ts b/src/resource-loader.ts index 55325b45b..ed32d7ab0 100644 --- a/src/resource-loader.ts +++ b/src/resource-loader.ts @@ -1,6 +1,6 @@ import { DefaultResourceLoader } from '@gsd/pi-coding-agent' import { homedir } from 'node:os' -import { chmodSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs' +import { chmodSync, cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs' import { dirname, join, relative, resolve } from 'node:path' import { fileURLToPath } from 'node:url' import { compareSemver } from './update-check.js' @@ -139,16 +139,32 @@ export function getNewerManagedResourceVersion(agentDir: string, currentVersion: * Files copied from the Nix store inherit read-only modes (0444/0555). * Calling this before cpSync prevents overwrite failures on subsequent upgrades, * and calling it after ensures the next run can overwrite the copies too. + * + * Preserves existing permission bits (including executability) and only adds + * owner-write (and for directories, owner-exec) without widening group/other + * permissions. */ function makeTreeWritable(dirPath: string): void { if (!existsSync(dirPath)) return - chmodSync(dirPath, 0o755) - for (const entry of readdirSync(dirPath, { withFileTypes: true })) { - const entryPath = join(dirPath, entry.name) - if (entry.isDirectory()) { + + const stats = statSync(dirPath) + const isDir = stats.isDirectory() + const currentMode = stats.mode & 0o777 + + // Ensure owner-write; for directories also ensure owner-exec so they remain traversable. + let newMode = currentMode | 0o200 + if (isDir) { + newMode |= 0o100 + } + + if (newMode !== currentMode) { + chmodSync(dirPath, newMode) + } + + if (isDir) { + for (const entry of readdirSync(dirPath, { withFileTypes: true })) { + const entryPath = join(dirPath, entry.name) makeTreeWritable(entryPath) - } else { - chmodSync(entryPath, 0o644) } } }