From 39aa7db8414e5d0cece69210290248cf16d48ac1 Mon Sep 17 00:00:00 2001 From: skulidropek <66840575+skulidropek@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:12:50 +0000 Subject: [PATCH 1/2] fix(usecases): skip tmp dirs in config search --- packages/lib/src/usecases/docker-git-config-search.ts | 7 ++++++- .../lib/tests/usecases/docker-git-config-search.test.ts | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/lib/src/usecases/docker-git-config-search.ts b/packages/lib/src/usecases/docker-git-config-search.ts index 4deb91e6..95f6af84 100644 --- a/packages/lib/src/usecases/docker-git-config-search.ts +++ b/packages/lib/src/usecases/docker-git-config-search.ts @@ -11,7 +11,12 @@ type DockerGitConfigSearchState = { const isDockerGitConfig = (entry: string): boolean => entry.endsWith("docker-git.json") const shouldSkipDir = (entry: string): boolean => - entry === ".git" || entry === ".orch" || entry === ".docker-git" || entry === ".cache" || entry === "node_modules" + entry === ".git" || + entry === ".orch" || + entry === ".docker-git" || + entry === ".cache" || + entry === "node_modules" || + entry === "tmp" const isNotFoundStatError = (error: PlatformError): boolean => error._tag === "SystemError" && error.reason === "NotFound" diff --git a/packages/lib/tests/usecases/docker-git-config-search.test.ts b/packages/lib/tests/usecases/docker-git-config-search.test.ts index b3d06f36..d4c2b490 100644 --- a/packages/lib/tests/usecases/docker-git-config-search.test.ts +++ b/packages/lib/tests/usecases/docker-git-config-search.test.ts @@ -44,6 +44,7 @@ describe("findDockerGitConfigPaths", () => { const ignoredOrch = path.join(root, "org/repo-a/.orch/docker-git.json") const ignoredRootCache = path.join(root, ".cache/packages/pnpm/store/v10/index/docker-git.json") const ignoredDockerGit = path.join(root, ".docker-git/.cache/git-mirrors/docker-git.json") + const ignoredTmp = path.join(root, "org/tmp/repo-c/docker-git.json") yield* _(writeFileWithParents(fs, path, includedMain)) yield* _(writeFileWithParents(fs, path, includedNested)) @@ -51,6 +52,7 @@ describe("findDockerGitConfigPaths", () => { yield* _(writeFileWithParents(fs, path, ignoredOrch)) yield* _(writeFileWithParents(fs, path, ignoredRootCache)) yield* _(writeFileWithParents(fs, path, ignoredDockerGit)) + yield* _(writeFileWithParents(fs, path, ignoredTmp)) const found = yield* _(findDockerGitConfigPaths(fs, path, root)) expect([...found].sort()).toEqual([includedMain, includedNested].sort()) From 880fb9f130d7812f992c55b9afdfbf8699e127c4 Mon Sep 17 00:00:00 2001 From: skulidropek <66840575+skulidropek@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:22:38 +0000 Subject: [PATCH 2/2] fix(core): skip tmp dirs in recursive scans --- .githooks/pre-commit | 7 +++---- .../app/tests/hooks/pre-commit-ai-dirs.test.ts | 5 +++++ packages/lib/src/usecases/auth-copy.ts | 5 +++++ packages/lib/src/usecases/scrap-session-import.ts | 3 ++- packages/lib/tests/usecases/auth-sync.test.ts | 14 ++++++++++++++ scripts/repair-knowledge-history.js | 2 +- scripts/session-backup-gist.js | 3 ++- scripts/session-backup-repo.js | 3 ++- scripts/setup-pre-commit-hook.js | 7 +++---- scripts/split-knowledge-large-files.js | 3 ++- 10 files changed, 39 insertions(+), 13 deletions(-) diff --git a/.githooks/pre-commit b/.githooks/pre-commit index fc4d63a2..64babb4d 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -9,10 +9,9 @@ node scripts/split-knowledge-large-files.js while IFS= read -r -d '' knowledge_dir; do git add -A -- "$knowledge_dir" done < <( - find . -type d \ - \( -name ".knowledge" -o -name ".knowlenge" \) \ - -not -path "*/.git/*" \ - -print0 + find . \ + \( -name ".git" -o -name "tmp" \) -type d -prune -o \ + \( -type d \( -name ".knowledge" -o -name ".knowlenge" \) -print0 \) ) # CHANGE: auto-stage AI agent config directories (.gemini, .claude, .codex) diff --git a/packages/app/tests/hooks/pre-commit-ai-dirs.test.ts b/packages/app/tests/hooks/pre-commit-ai-dirs.test.ts index d99d7936..a91d27a3 100644 --- a/packages/app/tests/hooks/pre-commit-ai-dirs.test.ts +++ b/packages/app/tests/hooks/pre-commit-ai-dirs.test.ts @@ -97,6 +97,9 @@ const AI_DIR_STAGING_SNIPPET = `for ai_dir in .gemini .claude .codex; do git add -A -- "$ai_dir" fi done` +const KNOWLEDGE_TMP_PRUNE_SNIPPET = `find . \\ + \\( -name ".git" -o -name "tmp" \\) -type d -prune -o \\ + \\( -type d \\( -name ".knowledge" -o -name ".knowlenge" \\) -print0 \\)` // Tests that require an isolated temp git repo describe("pre-commit hook (isolated repo)", () => { @@ -182,6 +185,7 @@ describe("pre-commit hook (isolated repo)", () => { expect(hookContent).toContain(".claude") expect(hookContent).toContain(".codex") expect(hookContent).toContain(AI_DIR_STAGING_SNIPPET) + expect(hookContent).toContain(KNOWLEDGE_TMP_PRUNE_SNIPPET) }) // INVARIANT: core.hooksPath = ".githooks" after setup @@ -227,6 +231,7 @@ describe("committed hook files", () => { const content = fs.readFileSync(path.resolve(repoRoot, ".githooks/pre-commit"), "utf8") expect(content).toContain(AI_DIR_STAGING_SNIPPET) + expect(content).toContain(KNOWLEDGE_TMP_PRUNE_SNIPPET) expect(content.startsWith("#!/usr/bin/env bash\n")).toBe(true) expect(content).toContain("set -euo pipefail") }) diff --git a/packages/lib/src/usecases/auth-copy.ts b/packages/lib/src/usecases/auth-copy.ts index 543514ed..2e484de7 100644 --- a/packages/lib/src/usecases/auth-copy.ts +++ b/packages/lib/src/usecases/auth-copy.ts @@ -3,6 +3,8 @@ import type * as FileSystem from "@effect/platform/FileSystem" import type * as Path from "@effect/platform/Path" import { Effect } from "effect" +const shouldSkipCopiedDir = (entry: string): boolean => entry === "tmp" + const copyDirRecursive = ( fs: FileSystem.FileSystem, path: Path.Path, @@ -19,6 +21,9 @@ const copyDirRecursive = ( for (const entry of entries) { const sourceEntry = path.join(sourcePath, entry) const targetEntry = path.join(targetPath, entry) + if (shouldSkipCopiedDir(entry)) { + continue + } const entryInfo = yield* _(fs.stat(sourceEntry)) if (entryInfo.type === "Directory") { yield* _(copyDirRecursive(fs, path, sourceEntry, targetEntry)) diff --git a/packages/lib/src/usecases/scrap-session-import.ts b/packages/lib/src/usecases/scrap-session-import.ts index 16a91e92..78bad01d 100644 --- a/packages/lib/src/usecases/scrap-session-import.ts +++ b/packages/lib/src/usecases/scrap-session-import.ts @@ -159,7 +159,8 @@ const prepareRepoForImport = ( `git -c safe.directory="$SAFE" reset --hard ${shellEscape(ctx.manifest.repo.head)}`, "git -c safe.directory=\"$SAFE\" clean -fd", // Remove common heavy caches that are easy to rebuild with internet access. - "find . -name node_modules -type d -prune -exec rm -rf '{}' + 2>/dev/null || true" + String + .raw`find . \( -name tmp -o -name .git \) -type d -prune -o -name node_modules -type d -prune -exec rm -rf '{}' + 2>/dev/null || true` ].join("\n") return runDockerExec( diff --git a/packages/lib/tests/usecases/auth-sync.test.ts b/packages/lib/tests/usecases/auth-sync.test.ts index 5f938193..49273fed 100644 --- a/packages/lib/tests/usecases/auth-sync.test.ts +++ b/packages/lib/tests/usecases/auth-sync.test.ts @@ -161,10 +161,13 @@ describe("syncGithubAuthKeys", () => { const path = yield* _(Path.Path) const legacyClaudeDefault = path.join(root, ".orch", "auth", "claude", "default") const legacyTokenPath = path.join(legacyClaudeDefault, ".oauth-token") + const ignoredTmpTokenPath = path.join(root, ".orch", "auth", "claude", "tmp", ".oauth-token") const expectedToken = "legacy-claude-token\n" yield* _(fs.makeDirectory(legacyClaudeDefault, { recursive: true })) yield* _(fs.writeFileString(legacyTokenPath, expectedToken)) + yield* _(fs.makeDirectory(path.dirname(ignoredTmpTokenPath), { recursive: true })) + yield* _(fs.writeFileString(ignoredTmpTokenPath, "ignored-claude-token\n")) yield* _( migrateLegacyOrchLayout(root, { @@ -186,7 +189,18 @@ describe("syncGithubAuthKeys", () => { ".oauth-token" ) const migratedToken = yield* _(fs.readFileString(migratedTokenPath)) + const migratedTmpTokenPath = path.join( + root, + ".docker-git", + ".orch", + "auth", + "claude", + "tmp", + ".oauth-token" + ) + const hasMigratedTmpToken = yield* _(fs.exists(migratedTmpTokenPath)) expect(migratedToken).toBe(expectedToken) + expect(hasMigratedTmpToken).toBe(false) }) ).pipe(Effect.provide(NodeContext.layer))) diff --git a/scripts/repair-knowledge-history.js b/scripts/repair-knowledge-history.js index 91659f16..07777f06 100755 --- a/scripts/repair-knowledge-history.js +++ b/scripts/repair-knowledge-history.js @@ -54,7 +54,7 @@ if (!Number.isFinite(count) || count <= 0) { // Run splitter + secret redaction after each commit is replayed, then amend if needed. const execCmd = [ `node scripts/split-knowledge-large-files.js`, - `while IFS= read -r -d '' knowledge_dir; do git add -A -- "$knowledge_dir"; done < <(find . -type d \\( -name ".knowledge" -o -name ".knowlenge" \\) -not -path "*/.git/*" -print0)`, + `while IFS= read -r -d '' knowledge_dir; do git add -A -- "$knowledge_dir"; done < <(find . \\( -name ".git" -o -name "tmp" \\) -type d -prune -o \\( -type d \\( -name ".knowledge" -o -name ".knowlenge" \\) -print0 \\))`, `bash scripts/pre-commit-secret-guard.sh`, `if ! git diff --cached --quiet; then git commit --amend --no-edit --no-verify; fi`, ].join(" && "); diff --git a/scripts/session-backup-gist.js b/scripts/session-backup-gist.js index 738d9a39..89c13f14 100644 --- a/scripts/session-backup-gist.js +++ b/scripts/session-backup-gist.js @@ -41,6 +41,7 @@ const { } = require("./session-backup-repo.js"); const SESSION_DIR_NAMES = [".codex", ".claude", ".qwen", ".gemini"]; +const SESSION_WALK_IGNORE_DIR_NAMES = new Set([".git", "node_modules", "tmp"]); const isPathWithinParent = (targetPath, parentPath) => { const relative = path.relative(parentPath, targetPath); @@ -366,7 +367,7 @@ const collectSessionFiles = (dirPath, baseName, verbose) => { const relPath = relativePath ? `${relativePath}/${entry.name}` : entry.name; if (entry.isDirectory()) { - if (entry.name === "node_modules" || entry.name === ".git") { + if (SESSION_WALK_IGNORE_DIR_NAMES.has(entry.name)) { continue; } walk(fullPath, relPath); diff --git a/scripts/session-backup-repo.js b/scripts/session-backup-repo.js index 6806a647..7f7c12ba 100644 --- a/scripts/session-backup-repo.js +++ b/scripts/session-backup-repo.js @@ -15,6 +15,7 @@ const GH_GIT_CREDENTIAL_HELPER = "!gh auth git-credential"; const CHUNK_MANIFEST_SUFFIX = ".chunks.json"; const DOCKER_GIT_CONFIG_FILE = "docker-git.json"; const GITHUB_ENV_KEYS = ["GITHUB_TOKEN", "GH_TOKEN"]; +const PROJECT_WALK_IGNORE_DIR_NAMES = new Set([".git", "node_modules", ".cache", "tmp"]); const parseEnvText = (text) => { const entries = []; @@ -90,7 +91,7 @@ const findDockerGitProjectForTarget = (projectsRoot, targetDir, log) => { if (!entry.isDirectory()) { continue; } - if (entry.name === ".git" || entry.name === "node_modules" || entry.name === ".cache") { + if (PROJECT_WALK_IGNORE_DIR_NAMES.has(entry.name)) { continue; } stack.push(path.join(currentDir, entry.name)); diff --git a/scripts/setup-pre-commit-hook.js b/scripts/setup-pre-commit-hook.js index 2211852d..4b1e348c 100644 --- a/scripts/setup-pre-commit-hook.js +++ b/scripts/setup-pre-commit-hook.js @@ -29,10 +29,9 @@ node scripts/split-knowledge-large-files.js while IFS= read -r -d '' knowledge_dir; do git add -A -- "$knowledge_dir" done < <( - find . -type d \\ - \\( -name ".knowledge" -o -name ".knowlenge" \\) \\ - -not -path "*/.git/*" \\ - -print0 + find . \\ + \\( -name ".git" -o -name "tmp" \\) -type d -prune -o \\ + \\( -type d \\( -name ".knowledge" -o -name ".knowlenge" \\) -print0 \\) ) # CHANGE: auto-stage AI agent config directories (.gemini, .claude, .codex) diff --git a/scripts/split-knowledge-large-files.js b/scripts/split-knowledge-large-files.js index 6778a795..b225e0f9 100755 --- a/scripts/split-knowledge-large-files.js +++ b/scripts/split-knowledge-large-files.js @@ -5,7 +5,7 @@ const path = require("node:path"); const MAX_BYTES = 99 * 1000 * 1000; const KNOWLEDGE_DIR_NAMES = new Set([".knowledge", ".knowlenge"]); -const WALK_IGNORE_DIR_NAMES = new Set([".git", "node_modules"]); +const WALK_IGNORE_DIR_NAMES = new Set([".git", "node_modules", "tmp"]); const MANIFEST_SUFFIX = ".chunks.json"; const CHUNK_BYTES = 1024 * 1024; @@ -85,6 +85,7 @@ const walk = (dir) => { for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory()) { + if (WALK_IGNORE_DIR_NAMES.has(entry.name)) continue; walk(fullPath); continue; }