Skip to content

Commit 9c7657b

Browse files
Fix script path truncation by centralizing relative path computation
The old code computed relative paths by doing string arithmetic with dropFirst(extensionsPathString.count + 1), but extensionsPathString came from URL.appendingPathComponent("./commands") which preserved the literal "./" — making it 2 chars longer than the actual resolved file paths from FileManager. Every script path was silently truncated (system/ → stem/, apps/ → ps/, etc.) for all 851 scripts. Replace both callsites with a new URL.relativePath(from:) helper that standardizes both sides before computing the relative path, eliminating the mismatch entirely. extensionsPathString is no longer needed and is removed. Also regenerates commands/extensions.json and commands/README.md with correct paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b78006c commit 9c7657b

5 files changed

Lines changed: 20181 additions & 20171 deletions

File tree

Tools/Toolkit/Sources/ToolkitLibrary/Core/Stores/DataManager.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ public actor DataManager {
2222
data.metadata.isEmpty
2323
}
2424

25-
nonisolated var extensionsPathString: String {
26-
extensionsPath.path
27-
}
28-
2925
public init(extensionsPath path: String, extensionsFilename: String = "") throws {
3026
let resolvedPath = URL.resolvingPath(path)
3127

Tools/Toolkit/Sources/ToolkitLibrary/Core/Toolkit/Toolkit+ReadContent.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ extension Toolkit {
7878
guard let content = readContentFile(from: file), !content.isEmpty else {
7979
continue
8080
}
81-
let pathCount = dataManager.extensionsPathString.count + 1
82-
readmePath = String(file.path.dropFirst(pathCount))
81+
readmePath = file.relativePath(from: dataManager.extensionsPath)
8382
} else if var scriptCommand = await readScriptCommand(from: file) {
8483
await dataManager.increaseTotal()
8584
await dataManager.addLanguage(scriptCommand.language)
@@ -147,9 +146,7 @@ extension Toolkit {
147146
var dictionary = readKeyValues(of: content)
148147
dictionary[filenameKey] = filename
149148

150-
let pathCount = dataManager.extensionsPathString.count + 1
151-
let parentDir = fileURL.deletingLastPathComponent().path
152-
let scriptPath = String(parentDir.dropFirst(pathCount))
149+
let scriptPath = fileURL.deletingLastPathComponent().relativePath(from: dataManager.extensionsPath)
153150
dictionary["path"] = "\(scriptPath)/"
154151

155152
if !dataManager.ignoreGitInformation {

Tools/Toolkit/Sources/ToolkitLibrary/Extensions/URL/URL+FileSystem.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ extension URL {
3535
)
3636
}
3737

38+
/// Returns the path of `self` relative to `base`, with both sides standardized
39+
/// so that `./`-prefixed or symlinked inputs produce the same result.
40+
func relativePath(from base: URL) -> String {
41+
let basePath = base.standardized.path
42+
let selfPath = standardized.path
43+
guard selfPath.hasPrefix(basePath) else { return selfPath }
44+
let stripped = selfPath.dropFirst(basePath.count)
45+
return String(stripped.hasPrefix("/") ? stripped.dropFirst() : stripped)
46+
}
47+
3848
/// Resolves a path string to an absolute URL.
3949
/// Handles absolute paths, tilde-prefixed paths, and relative-to-cwd paths.
4050
static func resolvingPath(_ path: String) -> URL {

0 commit comments

Comments
 (0)