Avoid truncated output filename collisions

ober

2d4413a5a8703aedc9cde66c2c25ac9f2de0b934

diff --git a/src/jcode/core/agent.ss b/src/jcode/core/agent.ss
index a766eb0..e28e744 100644
--- a/src/jcode/core/agent.ss
+++ b/src/jcode/core/agent.ss
@@ -284,6 +284,23 @@ Be concise. Prefer edit over write for modifying existing files.
       *local-max-tool-bytes*
       *max-tool-bytes*)))
 
+(def (write-truncated-output text)
+  "Write TEXT to a unique file under truncated-dir and return its path.
+   Tool calls can finish in parallel, so second-level timestamps are not
+   unique enough."
+  (let ((dir (truncated-dir))
+        (stamp (time-second (current-time))))
+    (let loop ((attempt 0))
+      (let ((file (path-join dir
+                    (format "tool-~a-~a.txt" stamp (random 1000000000)))))
+        (guard (e [#t
+                   (if (< attempt 100)
+                     (loop (+ attempt 1))
+                     (error 'write-truncated-output
+                            "failed to write truncated tool output"))])
+          (with-output-to-file file (lambda () (display text)))
+          file)))))
+
 (def (truncate-tool-output text)
   "Cap tool output at *max-tool-lines* / *max-tool-bytes*. If truncated,
    save the full output to ~/.jcode/truncated/ and return a preview + hint."
@@ -301,12 +318,10 @@ Be concise. Prefer edit over write for modifying existing files.
                 (>= bytes byte-limit))
           ;; Save full output, return preview + hint
           (let* ((preview (string-join (reverse acc) "\n"))
-                 (file (path-join (truncated-dir)
-                         (format "tool-~a.txt" (time-second (current-time)))))
+                 (file (write-truncated-output text))
                  (removed (if (> total-bytes byte-limit)
                             (format "~a bytes" (- total-bytes (string-length preview)))
                             (format "~a lines" (- total-lines count)))))
-            (with-output-to-file file (lambda () (display text)))
             (string-append preview
               (format "\n\n...~a truncated...\n\nFull output saved to: ~a\nUse grep to search or read with specific line ranges."
                 removed file)))