diff --git a/CHANGELOG.md b/CHANGELOG.md index cd3616a7d..b46df026e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Accept unescaped square brackets in workspace file URI paths. #594 - Fix inflated costs for OpenAI-compatible providers (e.g. Synthetic); count usage once per request before completion and retain received usage on stream errors. - Tool prompts: push, git config, shell search/read and sub-agents run on explicit request; rule headings are tool-scoped. - Recover Anthropic streaming responses interrupted by transient TLS `bad_record_mac` failures. diff --git a/src/eca/shared.clj b/src/eca/shared.clj index 35d7e31c8..302b40de0 100644 --- a/src/eca/shared.clj +++ b/src/eca/shared.clj @@ -203,9 +203,19 @@ (string/blank? path) base :else (str base "/" path)))) +(defn ^:private escape-raw-file-uri-path-brackets [uri] + (let [[_ prefix path] (re-matches #"(?is)(file:(?://[^/]*)?)(/.*)" uri) + escape-brackets #(-> % + (string/replace "[" "%5B") + (string/replace "]" "%5D"))] + (if path + (str prefix (escape-brackets path)) + (escape-brackets uri)))) + (defn uri->filename [uri] (let [^URI uri (-> uri (string/replace " " "%20") + escape-raw-file-uri-path-brackets (URI.))] (-> (Paths/get uri) .toString ;; WINDOWS drive letters diff --git a/test/eca/shared_test.clj b/test/eca/shared_test.clj index d6286eb1b..a5c34573b 100644 --- a/test/eca/shared_test.clj +++ b/test/eca/shared_test.clj @@ -19,7 +19,12 @@ (when h/windows? (shared/uri->filename "file:///c:/c.clj"))))) (testing "Spaces" (is (= (h/file-path "/Users/foo/Library/Some Document/comappleCloudDocs") - (shared/uri->filename (h/file-uri "file:///Users/foo/Library/Some Document/comappleCloudDocs")))))) + (shared/uri->filename (h/file-uri "file:///Users/foo/Library/Some Document/comappleCloudDocs"))))) + (testing "Raw square brackets" + (is (= (h/file-path "/path/[workspace") + (shared/uri->filename (h/file-uri "file:///path/[workspace")))) + (is (= (h/file-path "/path/workspace]") + (shared/uri->filename (h/file-uri "file:///path/workspace]")))))) (deftest assoc-some-test (testing "single association"