@@ -6,6 +6,7 @@ import { defaultTemplateConfig } from "@effect-template/lib/core/template-defaul
66import { parseGithubRepoUrl , parseGitlabRepoUrl } from "@effect-template/lib/core/repo"
77import { CommandFailedError } from "@effect-template/lib/shell/errors"
88import { authCodexLogin as runCodexLogin } from "@effect-template/lib/usecases/auth-codex"
9+ import { authGrokLogout as runGrokLogout } from "@effect-template/lib/usecases/auth-grok-logout"
910import { authGitlabLogin as runGitlabLogin , authGitlabLogout as runGitlabLogout , listGitlabTokens } from "@effect-template/lib/usecases/auth-gitlab"
1011import { authGithubLogin as runGithubLogin , authGithubLogout as runGithubLogout } from "@effect-template/lib/usecases/auth-github"
1112import { readEnvText } from "@effect-template/lib/usecases/env-file"
@@ -25,6 +26,7 @@ import {
2526 resolveGithubCloneAuthToken
2627} from "@effect-template/lib/usecases/github-token-preflight"
2728import { validateGithubToken , type GithubTokenValidationResult } from "@effect-template/lib/usecases/github-token-validation"
29+ import { resolveGrokAccountPath , resolveGrokAuthMethod } from "@effect-template/lib/usecases/auth-grok-helpers"
2830import { normalizeAccountLabel } from "@effect-template/lib/usecases/auth-helpers"
2931import { resolvePathFromCwd } from "@effect-template/lib/usecases/path-helpers"
3032import { Effect , Logger , Match } from "effect"
@@ -34,6 +36,8 @@ import type {
3436 CodexAuthLoginRequest ,
3537 CodexAuthLogoutRequest ,
3638 CodexAuthStatus ,
39+ GrokAuthLogoutRequest ,
40+ GrokAuthStatus ,
3741 GitlabAuthLoginRequest ,
3842 GitlabAuthLogoutRequest ,
3943 GitlabAuthStatus ,
@@ -57,6 +61,7 @@ export const gitlabAuthRequiredMessage = [
5761] . join ( "\n" )
5862export const githubAuthEnvGlobalPath = defaultTemplateConfig . envGlobalPath
5963export const codexAuthPath = defaultTemplateConfig . codexAuthPath
64+ export const grokAuthPath = defaultTemplateConfig . grokAuthPath
6065
6166const githubTokenKey = "GITHUB_TOKEN"
6267const githubTokenPrefix = "GITHUB_TOKEN__"
@@ -70,6 +75,7 @@ type GithubTokenEntry = {
7075type JsonRecord = Readonly < Record < string , unknown > >
7176type CodexRuntime = FileSystem . FileSystem | Path . Path | CommandExecutor . CommandExecutor
7277type CodexCommandError = CommandFailedError | PlatformError
78+ type GrokCommandError = CommandFailedError | PlatformError
7379
7480const labelFromKey = ( key : string ) : string =>
7581 key . startsWith ( githubTokenPrefix ) ? key . slice ( githubTokenPrefix . length ) : "default"
@@ -138,6 +144,16 @@ const toCodexApiError = (error: CodexCommandError): ApiBadRequestError | ApiInte
138144 cause : error
139145 } )
140146
147+ const toGrokApiError = ( error : GrokCommandError ) : ApiBadRequestError | ApiInternalError =>
148+ error . _tag === "CommandFailedError"
149+ ? new ApiBadRequestError ( {
150+ message : `${ error . command } failed (exit ${ error . exitCode } ).`
151+ } )
152+ : new ApiInternalError ( {
153+ message : String ( error ) ,
154+ cause : error
155+ } )
156+
141157const runWithCapturedLogs = < R > (
142158 effect : Effect . Effect < void , CodexCommandError , R > ,
143159 fallbackOutput : string
@@ -406,6 +422,32 @@ const codexAuthStatus = (
406422 account
407423} )
408424
425+ const grokAuthStatus = (
426+ label : string ,
427+ authPath : string ,
428+ method : GrokAuthStatus [ "method" ]
429+ ) : GrokAuthStatus => ( {
430+ label,
431+ message : method === "none"
432+ ? `Grok not connected (${ label } ).`
433+ : `Grok connected (${ label } , ${ method } ).` ,
434+ connected : method !== "none" ,
435+ authPath,
436+ method
437+ } )
438+
439+ export const readGrokAuthStatus = (
440+ label ?: string | null | undefined
441+ ) : Effect . Effect < GrokAuthStatus , PlatformError , FileSystem . FileSystem | Path . Path > =>
442+ Effect . gen ( function * ( _ ) {
443+ const fs = yield * _ ( FileSystem . FileSystem )
444+ const path = yield * _ ( Path . Path )
445+ const rootPath = resolvePathFromCwd ( path , process . cwd ( ) , grokAuthPath )
446+ const { accountLabel, accountPath } = resolveGrokAccountPath ( path , rootPath , label ?? null )
447+ const method = yield * _ ( resolveGrokAuthMethod ( fs , accountPath ) )
448+ return grokAuthStatus ( accountLabel , accountPath , method )
449+ } )
450+
409451export const readCodexAuthStatus = (
410452 label ?: string | null | undefined
411453) : Effect . Effect < CodexAuthStatus , PlatformError , FileSystem . FileSystem | Path . Path > =>
@@ -489,6 +531,25 @@ export const logoutCodexAuth = (
489531 return yield * _ ( readCodexAuthStatus ( request . label ) )
490532 } )
491533
534+ export const logoutGrokAuth = (
535+ request : GrokAuthLogoutRequest
536+ ) : Effect . Effect <
537+ GrokAuthStatus ,
538+ PlatformError | ApiBadRequestError | ApiInternalError ,
539+ FileSystem . FileSystem | Path . Path | CommandExecutor . CommandExecutor
540+ > =>
541+ Effect . gen ( function * ( _ ) {
542+ yield * _ (
543+ runGrokLogout ( {
544+ _tag : "AuthGrokLogout" ,
545+ label : request . label ?? null ,
546+ grokAuthPath
547+ } ) . pipe ( Effect . mapError ( toGrokApiError ) )
548+ )
549+
550+ return yield * _ ( readGrokAuthStatus ( request . label ) )
551+ } )
552+
492553export const ensureGithubAuthForCreate = ( config : {
493554 readonly repoUrl : string
494555 readonly gitTokenLabel ?: string | undefined
0 commit comments