fix(shared): stop ancestor discovery at worktree root
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,13 +1,29 @@
|
||||
import { existsSync } from "node:fs"
|
||||
import { execFileSync } from "node:child_process"
|
||||
import { existsSync, realpathSync } from "node:fs"
|
||||
import { dirname, join, resolve } from "node:path"
|
||||
|
||||
function normalizePath(path: string): string {
|
||||
const resolvedPath = resolve(path)
|
||||
if (!existsSync(resolvedPath)) {
|
||||
return resolvedPath
|
||||
}
|
||||
|
||||
try {
|
||||
return realpathSync(resolvedPath)
|
||||
} catch {
|
||||
return resolvedPath
|
||||
}
|
||||
}
|
||||
|
||||
function findAncestorDirectories(
|
||||
startDirectory: string,
|
||||
targetPaths: ReadonlyArray<ReadonlyArray<string>>,
|
||||
stopDirectory?: string,
|
||||
): string[] {
|
||||
const directories: string[] = []
|
||||
const seen = new Set<string>()
|
||||
let currentDirectory = resolve(startDirectory)
|
||||
let currentDirectory = normalizePath(startDirectory)
|
||||
const resolvedStopDirectory = stopDirectory ? normalizePath(stopDirectory) : undefined
|
||||
|
||||
while (true) {
|
||||
for (const targetPath of targetPaths) {
|
||||
@@ -20,33 +36,66 @@ function findAncestorDirectories(
|
||||
directories.push(candidateDirectory)
|
||||
}
|
||||
|
||||
if (resolvedStopDirectory === currentDirectory) {
|
||||
return directories
|
||||
}
|
||||
|
||||
const parentDirectory = dirname(currentDirectory)
|
||||
if (parentDirectory === currentDirectory) {
|
||||
return directories
|
||||
}
|
||||
|
||||
currentDirectory = parentDirectory
|
||||
currentDirectory = normalizePath(parentDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
export function findProjectClaudeSkillDirs(startDirectory: string): string[] {
|
||||
return findAncestorDirectories(startDirectory, [[".claude", "skills"]])
|
||||
function detectWorktreePath(directory: string): string | undefined {
|
||||
try {
|
||||
return execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
||||
cwd: directory,
|
||||
encoding: "utf-8",
|
||||
timeout: 5000,
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
}).trim()
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
export function findProjectAgentsSkillDirs(startDirectory: string): string[] {
|
||||
return findAncestorDirectories(startDirectory, [[".agents", "skills"]])
|
||||
export function findProjectClaudeSkillDirs(startDirectory: string, stopDirectory?: string): string[] {
|
||||
return findAncestorDirectories(
|
||||
startDirectory,
|
||||
[[".claude", "skills"]],
|
||||
stopDirectory ?? detectWorktreePath(startDirectory),
|
||||
)
|
||||
}
|
||||
|
||||
export function findProjectOpencodeSkillDirs(startDirectory: string): string[] {
|
||||
return findAncestorDirectories(startDirectory, [
|
||||
[".opencode", "skills"],
|
||||
[".opencode", "skill"],
|
||||
])
|
||||
export function findProjectAgentsSkillDirs(startDirectory: string, stopDirectory?: string): string[] {
|
||||
return findAncestorDirectories(
|
||||
startDirectory,
|
||||
[[".agents", "skills"]],
|
||||
stopDirectory ?? detectWorktreePath(startDirectory),
|
||||
)
|
||||
}
|
||||
|
||||
export function findProjectOpencodeCommandDirs(startDirectory: string): string[] {
|
||||
return findAncestorDirectories(startDirectory, [
|
||||
[".opencode", "commands"],
|
||||
[".opencode", "command"],
|
||||
])
|
||||
export function findProjectOpencodeSkillDirs(startDirectory: string, stopDirectory?: string): string[] {
|
||||
return findAncestorDirectories(
|
||||
startDirectory,
|
||||
[
|
||||
[".opencode", "skills"],
|
||||
[".opencode", "skill"],
|
||||
],
|
||||
stopDirectory ?? detectWorktreePath(startDirectory),
|
||||
)
|
||||
}
|
||||
|
||||
export function findProjectOpencodeCommandDirs(startDirectory: string, stopDirectory?: string): string[] {
|
||||
return findAncestorDirectories(
|
||||
startDirectory,
|
||||
[
|
||||
[".opencode", "commands"],
|
||||
[".opencode", "command"],
|
||||
],
|
||||
stopDirectory ?? detectWorktreePath(startDirectory),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user