From ab7bea628ffcd878347a154da9509199f48004dd Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 22 Jun 2026 08:45:22 +0200 Subject: [PATCH] WIP --- backend/src/app/binfile/common.clj | 2 +- backend/src/app/binfile/v3.clj | 147 ++++---- .../src/app/main/ui/dashboard/import.cljs | 11 +- frontend/src/app/worker/import.cljs | 20 +- package.json | 6 +- pnpm-lock.yaml | 334 +++++++++--------- 6 files changed, 254 insertions(+), 266 deletions(-) diff --git a/backend/src/app/binfile/common.clj b/backend/src/app/binfile/common.clj index 402dc30750..76fafece3b 100644 --- a/backend/src/app/binfile/common.clj +++ b/backend/src/app/binfile/common.clj @@ -922,4 +922,4 @@ "Return all shared files in `team-id` whose slugified name equals `slug`." [cfg team-id slug] (->> (get-shared-files-for-team cfg team-id) - (filterv #(= slug (slugify-name (:name %)))))) + (filter #(= slug (slugify-name (:name %)))))) diff --git a/backend/src/app/binfile/v3.clj b/backend/src/app/binfile/v3.clj index c36ed30263..942a37db53 100644 --- a/backend/src/app/binfile/v3.clj +++ b/backend/src/app/binfile/v3.clj @@ -380,6 +380,9 @@ (defn- export-files [{:keys [::bfc/ids ::bfc/include-libraries ::output] :as cfg}] + + (prn "=====" "export-files" include-libraries ids) + (let [original-ids ids ids (into ids (when include-libraries (bfc/get-libraries cfg ids))) rels (if include-libraries @@ -912,51 +915,58 @@ (vswap! bfc/*state* update :index assoc id (:id sobject))))))) -(defn- resolve-external-libraries +(defn- resolve-external-libraries-references "For each external library in the manifest, look for matching shared files in the team by slugified name. Returns a map of old-lib-id -> [{:id uuid :name string}] for libraries with matches." [{:keys [::manifest ::bfc/team-id] :as cfg}] - (let [external-libs (:external-libraries manifest)] - (when (and team-id (seq external-libs)) - (reduce (fn [result {:keys [id slug]}] - (let [candidates (bfc/find-shared-files-by-slug cfg team-id slug)] - (if (seq candidates) - (assoc result id candidates) - result))) - {} - external-libs)))) + (assert (uuid? team-id) "team-id should be provided") + (reduce (fn [result {:keys [id slug] :as lib}] + (if-let [candidates (-> (bfc/find-shared-files-by-slug cfg team-id slug) + (vec) + (not-empty))] + (assoc result id (assoc lib :candidates candidates)) + result)) + {} + (:external-libraries manifest))) (defn- auto-link-libraries "Auto-link imported files to libraries that have exactly one candidate - match. Returns a vector of {:id old-lib-id :name string :new-id uuid} + match. Returns a vector of {:id old-lib-id :name string :linked-to uuid} for each auto-linked library." [{:keys [::db/conn ::manifest ::bfc/timestamp ::bfc/profile-id] :as cfg} resolution file-ids] - (let [external-libs (:external-libraries manifest)] - (reduce (fn [linked {:keys [id name used-by] :as ext-lib}] - (let [candidates (get resolution id)] - (if (= 1 (count candidates)) - (let [new-lib-id (:id (first candidates)) - perms (bfc/get-file-permissions conn profile-id new-lib-id)] - ;; Only auto-link when the importer has edit permission - ;; on the matched library, matching the manual link RPC. - (if (:can-edit perms) - (let [;; Link only files that actually used this library - relevant-file-ids (if (seq used-by) - (let [used-set (set (map bfc/lookup-index used-by))] - (filterv used-set file-ids)) - file-ids)] - (doseq [fid relevant-file-ids] - (let [rel-params {:file-id fid - :library-file-id new-lib-id}] - (db/insert! conn :file-library-rel rel-params - ::db/on-conflict-do-nothing? true) - (bfc/upsert-file-library-sync! conn (assoc rel-params :synced-at timestamp)))) - (conj linked {:id id :name name :new-id new-lib-id})) - linked)) - linked))) - [] - external-libs))) + (reduce-kv (fn [result id {:keys [name used-by candidates]}] + (if (= 1 (count candidates)) + (let [candidate (first candidates) + lib-id (get candidate :id) + perms (bfc/get-file-permissions conn profile-id lib-id)] + + ;; Only auto-link when the importer has edit permission + ;; on the matched library, matching the manual link RPC. + (if (:can-edit perms) + ;; Link only files that actually used this library + (let [used-by (into #{} (map bfc/lookup-index) used-by) + file-ids (-> (filter #(contains? used-by %) file-ids) + (not-empty))] + + (doseq [file-id file-ids] + (when (contains? used-by file-id) + (let [rel-params {:file-id file-id + :library-file-id lib-id}] + (db/insert! conn :file-library-rel rel-params + {::db/on-conflict-do-nothing? true}) + (bfc/upsert-file-library-sync! conn (assoc rel-params :synced-at timestamp))))) + + (if file-ids + (update result id (fn [lib] + (-> lib + (assoc :linked-to lib-id) + (dissoc :candidates)))) + (dissoc result id))) + result)) + result)) + resolution + resolution)) (defn- import-files* [{:keys [::manifest] :as cfg}] @@ -966,40 +976,28 @@ (import-storage-objects cfg) - (let [files (get manifest :files) - result (reduce (fn [result file] - (let [name' (get file :name) - file (assoc file :name name')] - (conj result (import-file cfg file)))) - [] - files)] + (let [files (get manifest :files) + file-ids (reduce (fn [result file] + (let [name' (get file :name) + file (assoc file :name name')] + (conj result (import-file cfg file)))) + [] + files)] (import-file-relations cfg) ;; Resolve external libraries by slug and auto-link single matches - (let [resolution (resolve-external-libraries cfg) - auto-linked (when (seq resolution) - (auto-link-libraries cfg resolution result)) + (let [resolution + (resolve-external-libraries-references cfg) - ;; Collect multi-match candidates for frontend resolution - candidates (when (seq resolution) - (into {} - (filter (fn [[_ candidates]] (> (count candidates) 1))) - resolution)) + resolution + (auto-link-libraries cfg resolution file-ids)] - ;; Build external-libraries lookup from manifest for the frontend - external-libs-info (when (seq resolution) - (->> (:external-libraries manifest) - (filter #(contains? candidates (:id %))) - (mapv (fn [{:keys [id name slug]}] - {:id id :name name :slug slug}))))] + (app.common.pprint/pprint resolution) (bfm/apply-pending-migrations! cfg) - - {:file-ids result - :auto-linked (or auto-linked []) - :library-candidates (or candidates {}) - :external-libs (or external-libs-info [])}))) + {:file-ids file-ids + :resolution resolution}))) (defn- import-file-and-overwrite* [{:keys [::manifest ::bfc/file-id] :as cfg}] @@ -1027,10 +1025,8 @@ (bfc/invalidate-thumbnails cfg file-id) (bfm/apply-pending-migrations! cfg) - {:file-ids [file-id] - :auto-linked [] - :library-candidates {} - :external-libs []}))) + {:file-ids [file-id] + :resolution {}}))) (defn- import-files [{:keys [::bfc/timestamp ::bfc/input] :or {timestamp (ct/now)} :as cfg}] @@ -1068,20 +1064,9 @@ (events/tap :progress {:section :manifest}) (binding [bfc/*state* (volatile! {:media [] :index {}})] - (let [result (if (::bfc/file-id cfg) - (db/tx-run! cfg import-file-and-overwrite*) - (db/tx-run! cfg import-files*))] - - ;; Emit library-candidates event for frontend resolution of - ;; multi-match cases (if any) - (when (seq (:library-candidates result)) - (events/tap :library-candidates - {:file-ids (:file-ids result) - :auto-linked (:auto-linked result) - :library-candidates (:library-candidates result) - :external-libs (:external-libs result)})) - - result)))) + (if (::bfc/file-id cfg) + (db/tx-run! cfg import-file-and-overwrite*) + (db/tx-run! cfg import-files*))))) ;; --- PUBLIC API @@ -1110,6 +1095,8 @@ tp (ct/tpoint) ab (volatile! false) cs (volatile! nil)] + + (prn "AAAAAAAAAAAA") (try (l/info :hint "start exportation" :export-id (str id)) (binding [bfc/*state* (volatile! (bfc/initial-state))] diff --git a/frontend/src/app/main/ui/dashboard/import.cljs b/frontend/src/app/main/ui/dashboard/import.cljs index a079a8a2b9..c54b678459 100644 --- a/frontend/src/app/main/ui/dashboard/import.cljs +++ b/frontend/src/app/main/ui/dashboard/import.cljs @@ -188,9 +188,11 @@ (rx/filter (comp uuid? :file-id)) (rx/subs! (fn [message] + (prn "AAA" message) ;; Capture library-resolution data if present (same for all ;; entries from the same zip, so first one wins) - (when-let [resolution (:library-resolution message)] + (when-let [resolution (-> (:libraries-resolution message) + (not-empty))] (when (nil? @library-resolution*) (reset! library-resolution* resolution))) (swap! state update-entry-status message)))))) @@ -198,14 +200,14 @@ (mf/defc import-entry* {::mf/memo true ::mf/private true} - [{:keys [entries entry edition can-be-deleted importing? on-edit on-change on-delete]}] + [{:keys [entries entry edition can-be-deleted is-progress on-edit on-change on-delete]}] (let [status (:status entry) ;; FIXME: rename to format format (:type entry) loading? (or (= :analyze status) (= :import-progress status) - (and importing? (= :import-ready status))) + (and is-progress (= :import-ready status))) analyze-error? (= :analyze-error status) import-success? (= :import-success status) import-error? (= :import-error status) @@ -623,6 +625,7 @@ :else (tr "dashboard.import.import-error.unknown-error"))])]))] + [:div (tr "dashboard.import.import-error.message2")]] (when-not (= :library-resolution status) @@ -631,7 +634,7 @@ :key (dm/str (:uri entry) "/" (:file-id entry)) :entry entry :entries entries - :importing? (= :import-progress status) + :is-progress (= :import-progress status) :on-edit on-edit :on-change on-entry-change :on-delete on-entry-delete diff --git a/frontend/src/app/worker/import.cljs b/frontend/src/app/worker/import.cljs index 0edcefa474..098b8a8536 100644 --- a/frontend/src/app/worker/import.cljs +++ b/frontend/src/app/worker/import.cljs @@ -218,20 +218,18 @@ :section (:section payload) :name (:name payload)) - (= type "library-candidates") - (vreset! library-resolution* payload) - :else (log/dbg :hint "import-binfile: end"))))) (rx/filter sse/end-of-stream?) - (rx/mapcat (fn [_] - (let [resolution @library-resolution*] - (->> (rx/from entries) - (rx/map (fn [entry] - (cond-> {:status :finish - :file-id (:file-id entry)} - (some? resolution) - (assoc :library-resolution resolution)))))))) + (rx/mapcat (fn [message] + (let [{:keys [file-ids resolution]} (sse/get-payload message)] + (rx/concat + (->> (rx/from entries) + (rx/map (fn [entry] + {:status :finish + :file-id (:file-id entry)}))) + (rx/of {:status :libraries-resolution + :data resolution}))))) (rx/catch (fn [cause] (log/error :hint "import-binfile: unexpected error on importing" diff --git a/package.json b/package.json index a1171fe177..61773719aa 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "fmt": "./scripts/fmt" }, "devDependencies": { - "@types/node": "^25.9.2", - "esbuild": "^0.28.0", + "@types/node": "^25.9.3", + "esbuild": "^0.28.1", "mdts": "^0.20.3", "nrepl-client": "^0.3.0", - "opencode-ai": "^1.17.0" + "opencode-ai": "^1.17.7" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b42a208a2a..68b1f07f7b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: devDependencies: '@types/node': - specifier: ^25.9.2 - version: 25.9.2 + specifier: ^25.9.3 + version: 25.9.3 esbuild: - specifier: ^0.28.0 - version: 0.28.0 + specifier: ^0.28.1 + version: 0.28.1 mdts: specifier: ^0.20.3 version: 0.20.3 @@ -21,163 +21,163 @@ importers: specifier: ^0.3.0 version: 0.3.0 opencode-ai: - specifier: ^1.17.0 - version: 1.17.0 + specifier: ^1.17.7 + version: 1.17.7 packages: - '@esbuild/aix-ppc64@0.28.0': - resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.28.0': - resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.28.0': - resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.28.0': - resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.28.0': - resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.28.0': - resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.28.0': - resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.28.0': - resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.28.0': - resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.28.0': - resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.28.0': - resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.28.0': - resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.28.0': - resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.28.0': - resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.28.0': - resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.28.0': - resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.28.0': - resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.28.0': - resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.28.0': - resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.28.0': - resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.28.0': - resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.28.0': - resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.28.0': - resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.28.0': - resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.28.0': - resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.28.0': - resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -194,8 +194,8 @@ packages: '@simple-git/argv-parser@1.1.1': resolution: {integrity: sha512-Q9lBcfQ+VQCpQqGJFHe5yooOS5hGdLFFbJ5R+R5aDsnkPCahtn1hSkMcORX65J2Z5lxSkD0lQorMsncuBQxYUw==} - '@types/node@25.9.2': - resolution: {integrity: sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==} + '@types/node@25.9.3': + resolution: {integrity: sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==} accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} @@ -333,8 +333,8 @@ packages: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} - esbuild@0.28.0: - resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} engines: {node: '>=18'} hasBin: true @@ -545,72 +545,72 @@ packages: resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} engines: {node: '>=20'} - opencode-ai@1.17.0: - resolution: {integrity: sha512-YDRKBJ469vAK9Vtx5EMbRSo/BU+iL+Lit0sbGtorjC4bU6tb76pKTIhD11tnseRYx6MLv4XrypPDyZedEIk02A==} + opencode-ai@1.17.7: + resolution: {integrity: sha512-5oMjuqlVL78JhvXshwp2NCXCI+CHr24wWi7/5aI0CZoHnI44qTqssWOBUW59dPTpRGSOQmXTDTOOsPVYW38JPg==} cpu: [arm64, x64] os: [darwin, linux, win32] hasBin: true - opencode-darwin-arm64@1.17.0: - resolution: {integrity: sha512-heL151oyckrFxpu8Bdf9BTYdXb4OTCXwTZ8NI+O1iGakzeRLkNnoVER76uS6DO6Aoj/De8xUOub3o0yCn0Kuwg==} + opencode-darwin-arm64@1.17.7: + resolution: {integrity: sha512-/uoZpJvnxY1jtRXAASQTIn0goya61M1RJhX0Zx2RwO+sdnrfvYYX6p7iL82Rl+Sp+TAS8y2NBvN+p/OLAnxsqg==} cpu: [arm64] os: [darwin] - opencode-darwin-x64-baseline@1.17.0: - resolution: {integrity: sha512-rwWQDyioFd4p2WrVbenBPYy3u01R8FyMrbOjgj1003CXRuY5W3UmsgoIlFwJUA09EGHiu0rvU4dwA0WaLhsfsA==} + opencode-darwin-x64-baseline@1.17.7: + resolution: {integrity: sha512-nvaY4qQgS9ZSkCvw9+DOrQQeycbW8/AEcD/Q0suleMuUgFIqfrsVa4cdsmYrUh3BH+y2NRaVgMSIfU9gPqXAKA==} cpu: [x64] os: [darwin] - opencode-darwin-x64@1.17.0: - resolution: {integrity: sha512-8ebo4FZI1LhGXW7Yihm8J2J550ulLa50RkznRJrufod63ki6D6g/VrH5PkvAXNwpIQ7wZU1QnHUmgRb6OSF5ww==} + opencode-darwin-x64@1.17.7: + resolution: {integrity: sha512-v60XhJae1eKn/Kjhy2PLOY+ss7peSox8ILZFz7fwBzRgz4q61gIo1vM9WzXQ6Vt+5Oj8etYbPl3xmt1XDLZtEA==} cpu: [x64] os: [darwin] - opencode-linux-arm64-musl@1.17.0: - resolution: {integrity: sha512-MsgHfzE6+feVsrUMBvPoCcE5QF8EMcufkSMgbdJCnyRXS/v6cuoaRPNz5sIMknpfPnGaCUnHYLiyOtjeEe0NNA==} + opencode-linux-arm64-musl@1.17.7: + resolution: {integrity: sha512-bIySXi+XNLHL5m8lS1ljL5XZzQ0iMdf/X6KKaqHbDZQ3E0Qu7ERIHZjohx8S7htvCdPztuzeSr2udS0emumf6g==} cpu: [arm64] os: [linux] libc: [musl] - opencode-linux-arm64@1.17.0: - resolution: {integrity: sha512-T21kUGraOA7EBLwOg+SELrc6vAK8l3Vj5JXrOtm9+OQEUIL8yU4yyJlgxLSTh2RnGBhsOGxPwLm2L1o0nmy6ow==} + opencode-linux-arm64@1.17.7: + resolution: {integrity: sha512-HTH5Z5V7xiAD+/nYn9wQYwM/LDokBZu8Ig+npwJrhGWzZGM+lChbv2+griYyRoaNEZ+zRsCvwyv96TTfb6nWDQ==} cpu: [arm64] os: [linux] - opencode-linux-x64-baseline-musl@1.17.0: - resolution: {integrity: sha512-rW9DU2oiMWFDQtM1O8I96cjQu7bpKkv+Nmh0VyK8dUjPx2vsTl4eNBVQmLSCevkSCd81rP8uu8pmZ3cr2xxO+A==} + opencode-linux-x64-baseline-musl@1.17.7: + resolution: {integrity: sha512-kTuZpRxMOzKt+ztp6yb+cSN8L69UYWN1x7Na4egX2d26IU0xK+RlXE9HjHzF/EjsmSBMc3DR8MvKUVldQ2XdbA==} cpu: [x64] os: [linux] libc: [musl] - opencode-linux-x64-baseline@1.17.0: - resolution: {integrity: sha512-f1kDGqOGUQxrgWkNmZSVAVzD0xAxTfkXRIukHNw7r3IblgY0+PZB5XEq8KDMskzdJRwdYqv2cPyjv+D6pThkcQ==} + opencode-linux-x64-baseline@1.17.7: + resolution: {integrity: sha512-fj62eWDQSygxS3Q5S3Gm4VYOsHrlTnje46bXoWc9IXfFNwFHAyL+izKzpU1SePCpCCEdsjy//nCKOnqN4PPK5g==} cpu: [x64] os: [linux] - opencode-linux-x64-musl@1.17.0: - resolution: {integrity: sha512-upbH4j5PDwL+7mFRUYclK708kJ0zq1snnb+r2rtHxWSbNTfLd8ZJnUS+rXuPpymWHWdvwB8STl/66lP63dt/cQ==} + opencode-linux-x64-musl@1.17.7: + resolution: {integrity: sha512-iKUBKzVD1ybMmAy3KW6cjfst18+glp3Fgtd7POGEAaQO7cWzwSmOnFHN3uCAi/wYrfrvYd4zXxHsFP0yMJRUmA==} cpu: [x64] os: [linux] libc: [musl] - opencode-linux-x64@1.17.0: - resolution: {integrity: sha512-WIH0gewBkD3gt7K3R12/1KqV4nLIEVuzTJc1zBnPcGPOnR9HEid5qxGwgbM0DyfQC9pkhCszHT2Xx71TEScEGg==} + opencode-linux-x64@1.17.7: + resolution: {integrity: sha512-UIxkdA/8281EHbHYVr5PSD+eVoMdlyfkmXiZp3u9duttsMHdf1F6lw0XjYmDRBCPp8zQM1D1RLCABuRA/kUX+Q==} cpu: [x64] os: [linux] - opencode-windows-arm64@1.17.0: - resolution: {integrity: sha512-iAvHYUS0GRJ+Utr1d4X4KwxmVi0nTM08ZhPkJtF1yzg38oTtHmxdDnkzTd2IIc/79XOfnRMzq47ejwnz9yWp7g==} + opencode-windows-arm64@1.17.7: + resolution: {integrity: sha512-BVlfloqHrjPhpDvbm3u1vQuEn063lbT3lcT7HBLmHpvwJd6FJutjPpm5/3xYxSusmXRGL7bmMZ3v1KPOeY0tBQ==} cpu: [arm64] os: [win32] - opencode-windows-x64-baseline@1.17.0: - resolution: {integrity: sha512-A+jlLAvIiLUb8Z0mPy9orTPpJQplOGAiTbNM/If5cUvEvBnifwkXOg4YCYEcUwC0hEfbyV9uJRLTyvtTOR8z5g==} + opencode-windows-x64-baseline@1.17.7: + resolution: {integrity: sha512-Gui/cezrLsLEZb1rUwNoKGXIiuZA0FsaGN3L/qR3/Qpce3e+hhqfqLHQXqlh0PFU1dSRKVRF8ukwWVx+2G5CPQ==} cpu: [x64] os: [win32] - opencode-windows-x64@1.17.0: - resolution: {integrity: sha512-ayaNoZnxcF18LVO1zO7hscGpMZGrWaUDMpe2XHmLOz7x6yKECo3HuK0IwhXRBtsaq+KZ68pWYUjp54pgEWcduw==} + opencode-windows-x64@1.17.7: + resolution: {integrity: sha512-MAykQj6ouoZ2rMt+q8ujBTnc4sD86WfLnPom28CTD+KgmI1s2D2qka7J6DjpK6A3j8PpkC0bEBIqVBciVgY6EA==} cpu: [x64] os: [win32] @@ -778,82 +778,82 @@ packages: snapshots: - '@esbuild/aix-ppc64@0.28.0': + '@esbuild/aix-ppc64@0.28.1': optional: true - '@esbuild/android-arm64@0.28.0': + '@esbuild/android-arm64@0.28.1': optional: true - '@esbuild/android-arm@0.28.0': + '@esbuild/android-arm@0.28.1': optional: true - '@esbuild/android-x64@0.28.0': + '@esbuild/android-x64@0.28.1': optional: true - '@esbuild/darwin-arm64@0.28.0': + '@esbuild/darwin-arm64@0.28.1': optional: true - '@esbuild/darwin-x64@0.28.0': + '@esbuild/darwin-x64@0.28.1': optional: true - '@esbuild/freebsd-arm64@0.28.0': + '@esbuild/freebsd-arm64@0.28.1': optional: true - '@esbuild/freebsd-x64@0.28.0': + '@esbuild/freebsd-x64@0.28.1': optional: true - '@esbuild/linux-arm64@0.28.0': + '@esbuild/linux-arm64@0.28.1': optional: true - '@esbuild/linux-arm@0.28.0': + '@esbuild/linux-arm@0.28.1': optional: true - '@esbuild/linux-ia32@0.28.0': + '@esbuild/linux-ia32@0.28.1': optional: true - '@esbuild/linux-loong64@0.28.0': + '@esbuild/linux-loong64@0.28.1': optional: true - '@esbuild/linux-mips64el@0.28.0': + '@esbuild/linux-mips64el@0.28.1': optional: true - '@esbuild/linux-ppc64@0.28.0': + '@esbuild/linux-ppc64@0.28.1': optional: true - '@esbuild/linux-riscv64@0.28.0': + '@esbuild/linux-riscv64@0.28.1': optional: true - '@esbuild/linux-s390x@0.28.0': + '@esbuild/linux-s390x@0.28.1': optional: true - '@esbuild/linux-x64@0.28.0': + '@esbuild/linux-x64@0.28.1': optional: true - '@esbuild/netbsd-arm64@0.28.0': + '@esbuild/netbsd-arm64@0.28.1': optional: true - '@esbuild/netbsd-x64@0.28.0': + '@esbuild/netbsd-x64@0.28.1': optional: true - '@esbuild/openbsd-arm64@0.28.0': + '@esbuild/openbsd-arm64@0.28.1': optional: true - '@esbuild/openbsd-x64@0.28.0': + '@esbuild/openbsd-x64@0.28.1': optional: true - '@esbuild/openharmony-arm64@0.28.0': + '@esbuild/openharmony-arm64@0.28.1': optional: true - '@esbuild/sunos-x64@0.28.0': + '@esbuild/sunos-x64@0.28.1': optional: true - '@esbuild/win32-arm64@0.28.0': + '@esbuild/win32-arm64@0.28.1': optional: true - '@esbuild/win32-ia32@0.28.0': + '@esbuild/win32-ia32@0.28.1': optional: true - '@esbuild/win32-x64@0.28.0': + '@esbuild/win32-x64@0.28.1': optional: true '@kwsites/file-exists@1.1.1': @@ -870,7 +870,7 @@ snapshots: dependencies: '@simple-git/args-pathspec': 1.0.3 - '@types/node@25.9.2': + '@types/node@25.9.3': dependencies: undici-types: 7.24.6 @@ -986,34 +986,34 @@ snapshots: dependencies: es-errors: 1.3.0 - esbuild@0.28.0: + esbuild@0.28.1: optionalDependencies: - '@esbuild/aix-ppc64': 0.28.0 - '@esbuild/android-arm': 0.28.0 - '@esbuild/android-arm64': 0.28.0 - '@esbuild/android-x64': 0.28.0 - '@esbuild/darwin-arm64': 0.28.0 - '@esbuild/darwin-x64': 0.28.0 - '@esbuild/freebsd-arm64': 0.28.0 - '@esbuild/freebsd-x64': 0.28.0 - '@esbuild/linux-arm': 0.28.0 - '@esbuild/linux-arm64': 0.28.0 - '@esbuild/linux-ia32': 0.28.0 - '@esbuild/linux-loong64': 0.28.0 - '@esbuild/linux-mips64el': 0.28.0 - '@esbuild/linux-ppc64': 0.28.0 - '@esbuild/linux-riscv64': 0.28.0 - '@esbuild/linux-s390x': 0.28.0 - '@esbuild/linux-x64': 0.28.0 - '@esbuild/netbsd-arm64': 0.28.0 - '@esbuild/netbsd-x64': 0.28.0 - '@esbuild/openbsd-arm64': 0.28.0 - '@esbuild/openbsd-x64': 0.28.0 - '@esbuild/openharmony-arm64': 0.28.0 - '@esbuild/sunos-x64': 0.28.0 - '@esbuild/win32-arm64': 0.28.0 - '@esbuild/win32-ia32': 0.28.0 - '@esbuild/win32-x64': 0.28.0 + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 escape-html@1.0.3: {} @@ -1263,55 +1263,55 @@ snapshots: powershell-utils: 0.1.0 wsl-utils: 0.3.1 - opencode-ai@1.17.0: + opencode-ai@1.17.7: optionalDependencies: - opencode-darwin-arm64: 1.17.0 - opencode-darwin-x64: 1.17.0 - opencode-darwin-x64-baseline: 1.17.0 - opencode-linux-arm64: 1.17.0 - opencode-linux-arm64-musl: 1.17.0 - opencode-linux-x64: 1.17.0 - opencode-linux-x64-baseline: 1.17.0 - opencode-linux-x64-baseline-musl: 1.17.0 - opencode-linux-x64-musl: 1.17.0 - opencode-windows-arm64: 1.17.0 - opencode-windows-x64: 1.17.0 - opencode-windows-x64-baseline: 1.17.0 + opencode-darwin-arm64: 1.17.7 + opencode-darwin-x64: 1.17.7 + opencode-darwin-x64-baseline: 1.17.7 + opencode-linux-arm64: 1.17.7 + opencode-linux-arm64-musl: 1.17.7 + opencode-linux-x64: 1.17.7 + opencode-linux-x64-baseline: 1.17.7 + opencode-linux-x64-baseline-musl: 1.17.7 + opencode-linux-x64-musl: 1.17.7 + opencode-windows-arm64: 1.17.7 + opencode-windows-x64: 1.17.7 + opencode-windows-x64-baseline: 1.17.7 - opencode-darwin-arm64@1.17.0: + opencode-darwin-arm64@1.17.7: optional: true - opencode-darwin-x64-baseline@1.17.0: + opencode-darwin-x64-baseline@1.17.7: optional: true - opencode-darwin-x64@1.17.0: + opencode-darwin-x64@1.17.7: optional: true - opencode-linux-arm64-musl@1.17.0: + opencode-linux-arm64-musl@1.17.7: optional: true - opencode-linux-arm64@1.17.0: + opencode-linux-arm64@1.17.7: optional: true - opencode-linux-x64-baseline-musl@1.17.0: + opencode-linux-x64-baseline-musl@1.17.7: optional: true - opencode-linux-x64-baseline@1.17.0: + opencode-linux-x64-baseline@1.17.7: optional: true - opencode-linux-x64-musl@1.17.0: + opencode-linux-x64-musl@1.17.7: optional: true - opencode-linux-x64@1.17.0: + opencode-linux-x64@1.17.7: optional: true - opencode-windows-arm64@1.17.0: + opencode-windows-arm64@1.17.7: optional: true - opencode-windows-x64-baseline@1.17.0: + opencode-windows-x64-baseline@1.17.7: optional: true - opencode-windows-x64@1.17.0: + opencode-windows-x64@1.17.7: optional: true parseurl@1.3.3: {}