secrets-import: add "grok" entry + import-from-grok! (add-grok phase 5)

ober

9a51e93c07d5f9fbcb6669ed4190d5025b67f159

diff --git a/src/jcode/core/secrets-import.ss b/src/jcode/core/secrets-import.ss
index df037bf..274bee2 100644
--- a/src/jcode/core/secrets-import.ss
+++ b/src/jcode/core/secrets-import.ss
@@ -20,12 +20,14 @@
         import-from-claude-code!
         import-from-aider!
         import-from-env!
+        import-from-grok!
         import-prompt-missing!)
 
 (import :std/text/json
         :std/misc/string
         :std/os/path
         :jcode/core/secrets
+        :jcode/core/grok-auth
         :jcode/core/log
         :jerboa/core
         :jerboa/runtime)
@@ -40,6 +42,10 @@
     ("openrouter" . "OPENROUTER_API_KEY")
     ("deepseek"   . "DEEPSEEK_API_KEY")
     ("xai"        . "XAI_API_KEY")
+    ;; "grok" is the Grok CLI session-token provider. Its preferred env var is
+    ;; GROK_CODE_XAI_API_KEY so import-from-env! does not collide with xai's
+    ;; XAI_API_KEY; runtime lookup in config.ss accepts both.
+    ("grok"       . "GROK_CODE_XAI_API_KEY")
     ("groq"       . "GROQ_API_KEY")
     ("mistral"    . "MISTRAL_API_KEY")
     ("together"   . "TOGETHER_API_KEY")
@@ -168,6 +174,37 @@
          (log-info logger "aider-import" `((count . ,added) (path . ,path)))
          added)))))
 
+;;; ---- ~/.grok session token ----
+
+(def (import-from-grok!)
+  ;; Best-effort import of the Grok CLI bearer token from ~/.grok/auth.json
+  ;; into the encrypted store under "grok". Only the current `key` is
+  ;; written — refresh_token / email / user_id / principal_id stay in
+  ;; ~/.grok and are never logged. Returns the count imported (0 or 1).
+  ;;
+  ;; Surface a clear "session token" disclaimer so the user knows this is
+  ;; NOT a durable API key: Grok tokens expire (default ~6h) and the CLI
+  ;; hot-reloads auth.json on `grok login`. Runtime ~/.grok lookup remains
+  ;; the primary path (config-get-provider-key); explicit `keys import grok`
+  ;; is for users who prefer a single source of truth.
+  (let ((tok (grok-auth-token)))
+    (cond
+      ((not tok)
+       (display "  No usable token in ~/.grok/auth.json (run `grok login`)."
+                (current-error-port))
+       (newline (current-error-port))
+       0)
+      (else
+       (secret-store-set! "grok" tok)
+       (display "  Imported Grok CLI session token into the encrypted store."
+                (current-error-port))
+       (newline (current-error-port))
+       (display "  Note: Grok tokens expire — re-run `grok login` and `jcode keys import grok` when 401s appear."
+                (current-error-port))
+       (newline (current-error-port))
+       (log-info logger "grok-import" '((count . 1)))
+       1))))
+
 ;;; ---- env vars ----
 
 (def (import-from-env!)
diff --git a/test/run.ss b/test/run.ss
index 2499e9b..6ad14a4 100644
--- a/test/run.ss
+++ b/test/run.ss
@@ -6,6 +6,7 @@
         (jcode core message)
         (jcode core grok-auth)
         (jcode core config)
+        (jcode core secrets-import)
         (jcode provider provider)
         (jcode tool registry)
         (jcode tool file)
@@ -1767,6 +1768,21 @@
   (grok-list-models (make-provider "grok" "" "grok-build" "https://x/v1"))
   (lambda (ms) (assoc "grok-build" ms)))
 
+;; ── secrets-import: grok known-providers entry ────────────────────
+;; *known-providers* (secrets-import) is the single-env-var-per-provider
+;; mapping used by import-from-env! / aider import / interactive prompts.
+;; For "grok" we pick GROK_CODE_XAI_API_KEY so it does not duplicate xai's
+;; XAI_API_KEY entry; runtime config-get-provider-key accepts BOTH names.
+
+(section "=== secrets-import: grok ===")
+
+(check! "*known-providers* maps grok → GROK_CODE_XAI_API_KEY"
+        (cdr (assoc "grok" *known-providers*)) "GROK_CODE_XAI_API_KEY")
+(check! "*known-providers* still maps xai → XAI_API_KEY"
+        (cdr (assoc "xai" *known-providers*)) "XAI_API_KEY")
+(check-pred! "*known-providers* still contains anthropic"
+             *known-providers* (lambda (l) (assoc "anthropic" l)))
+
 ;; ── Results ───────────────────────────────────────────────────────
 
 (printf "~n~a passed, ~a failed~n" pass-count fail-count)