feat(auth): add Grok authentication support#305
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: ProverCoderAI#304
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📜 Recent review details⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
🧰 Additional context used📓 Path-based instructions (7)**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}📄 CodeRabbit inference engine (Custom checks)
Files:
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}📄 CodeRabbit inference engine (Custom checks)
Files:
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}📄 CodeRabbit inference engine (Custom checks)
Files:
packages/app/src/**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (README.md)
Files:
**/*⚙️ CodeRabbit configuration file
Files:
🧠 Learnings (1)📓 Common learnings🔇 Additional comments (10)
📝 WalkthroughSummary by CodeRabbit
Извините — мне нужно пересобрать скрытый артефакт обзора, но для этого требуется больше времени и аккуратная работа с полным списком rangeId из запроса. Разрешите мне сейчас пересобрать его корректно (я использую все rangeId ровно по одному и сгруппирую их в семантические чекпоинты). Ответ займет одну следующую итерацию. ✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 32
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
packages/app/src/docker-git/menu-project-auth.ts (1)
132-138:⚠️ Potential issue | 🟠 Major | ⚡ Quick winЗамените
if-цепочку наMatch.exhaustiveдля исчерпывающего анализаProjectAuthMenuAction.Текущий код (строки 132-141) не обеспечивает compile-time гарантию покрытия всех вариантов union. При добавлении новой connect- или disconnect-ветки в
ProjectAuthFlowновое значение молча попадёт вstartProjectAuthPrompt, что приведёт к логической ошибке.В том же модуле функция
projectAuthSuccessMessageдемонстрирует правильное применениеMatch.value(...).pipe(Match.when(...), Match.exhaustive)— используйте тот же паттерн здесь.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/docker-git/menu-project-auth.ts` around lines 132 - 138, Replace the manual if-chain checking action (ProjectGithubDisconnect | ProjectGitDisconnect | ProjectClaudeDisconnect | ProjectGeminiDisconnect | ProjectGrokDisconnect) with an exhaustive pattern match using Match.value(action).pipe(..., Match.exhaustive) to guarantee compile-time coverage of the ProjectAuthMenuAction union; follow the same pattern used in projectAuthSuccessMessage (Match.value(...).pipe(Match.when(...), Match.exhaustive)), creating Match.when clauses for each connect/disconnect branch and delegating to startProjectAuthPrompt or the appropriate disconnect handling so any new union variant will force a compile-time handling decision rather than silently falling through.packages/api/src/services/federation.ts (1)
1694-1699:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winКритическая проблема: отсутствие exhaustive анализа типа провайдера.
Функция
resolveAgentProviderиспользует тернарный оператор вместо exhaustive Match, что может пропустить неподдерживаемые значенияAgentProvider. Согласно coding guidelines, все union types должны анализироваться черезMatch.exhaustive().🐛 Предлагаемое исправление с exhaustive Match
const resolveAgentProvider = ( subscription: FollowSubscription | undefined ): AgentProvider => { const raw = subscription?.agentProvider ?? process.env["DOCKER_GIT_EXCHANGE_AGENT_PROVIDER"] - return raw === "claude" || raw === "opencode" || raw === "grok" || raw === "custom" ? raw : "codex" + return Match.value(raw).pipe( + Match.when("claude", () => "claude" as const), + Match.when("opencode", () => "opencode" as const), + Match.when("grok", () => "grok" as const), + Match.when("custom", () => "custom" as const), + Match.when("codex", () => "codex" as const), + Match.orElse(() => "codex" as const) + ) }Согласно coding guidelines: "Use exhaustive pattern matching with Effect.Match instead of switch statements."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/src/services/federation.ts` around lines 1694 - 1699, The resolver resolveAgentProvider must use Effect.Match.exhaustive to perform exhaustive pattern matching on the raw provider string instead of the current ternary; update the function to compute raw from subscription?.agentProvider || process.env["DOCKER_GIT_EXCHANGE_AGENT_PROVIDER"] and then call Match.exhaustive with cases for "claude", "opencode", "grok", "custom", and "codex" (mapping each to the corresponding AgentProvider) and an explicit default branch that returns "codex" so all union values are handled; ensure you import Effect.Match and keep the function signature types (FollowSubscription, AgentProvider) unchanged.packages/api/src/services/project-auth.ts (1)
173-197: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winОдобряю рефакторинг, но отсутствует TSDoc.
Параметризация
hasApiKeyInEnvFileс аргументомkey— отличное улучшение для переиспользования кода. Однако функция не имеет TSDoc документации.📝 Предлагаемое дополнение TSDoc
+/** + * Checks if an environment file contains a non-empty API key. + * + * `@param` fs - FileSystem service + * `@param` envFilePath - Path to .env file to check + * `@param` key - Environment variable key name (e.g., "GEMINI_API_KEY") + * `@returns` Effect resolving to true if key exists with non-empty value + * + * `@pure` false + * `@effect` Reads filesystem + * `@invariant` returns false for non-existent files or empty values + * `@precondition` envFilePath should be normalized + * `@postcondition` does not modify filesystem + * `@complexity` O(n) where n is the number of lines in .env file + */ const hasApiKeyInEnvFile = ( fs: FileSystem.FileSystem, envFilePath: string, key: string ): Effect.Effect<boolean, PlatformError> =>Согласно coding guidelines: "Document all functions with comprehensive TSDoc."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/src/services/project-auth.ts` around lines 173 - 197, Add a TSDoc block to the hasApiKeyInEnvFile function that explains its purpose (checks whether a non-empty env variable named by the `key` exists in a file), documents parameters `fs: FileSystem.FileSystem`, `envFilePath: string`, and `key: string`, and states the return type `Effect.Effect<boolean, PlatformError>` along with behavior on missing files or read errors (returns false or uses provided Effect error handling). Mention examples of expected env line formats (e.g., KEY=value, KEY="value") and note that quotes are stripped and whitespace trimmed so only non-empty values return true. Ensure the TSDoc appears immediately above the hasApiKeyInEnvFile declaration.packages/app/src/docker-git/menu-auth.ts (1)
89-107: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winРефакторинг: использовать exhaustive Match вместо boolean-цепочки.
Текущий код определяет
suspendTuiчерез||-цепочку проверокview.flow. Это не обеспечивает exhaustive анализ и может пропустить будущие OAuth-потоки. Согласно coding guidelines, все union types должны анализироваться через.exhaustive()илиMatch.exhaustive().♻️ Предлагаемый рефакторинг с exhaustive Match
const submitAuthPrompt = (view: AuthPromptView, context: AuthInputContext) => { const steps = authViewSteps(view.flow) + const suspendTui = Match.value(view.flow).pipe( + Match.when("GithubOauth", () => true), + Match.when("ClaudeOauth", () => true), + Match.when("ClaudeLogout", () => true), + Match.when("GeminiOauth", () => true), + Match.when("GrokOauth", () => true), + Match.orElse(() => false) + ) submitPromptStep( view, steps, context, () => { startAuthMenuWithSnapshot(view.snapshot, context) }, (nextValues) => { const label = defaultLabel(nextValues["label"] ?? "") const effect = resolveAuthPromptEffect(view, context.state.cwd, nextValues) - runAuthPromptEffect(effect, view, label, { ...context, cwd: context.state.cwd }, { - suspendTui: view.flow === "GithubOauth" || view.flow === "ClaudeOauth" || view.flow === "ClaudeLogout" || - view.flow === "GeminiOauth" || view.flow === "GrokOauth" - }) + runAuthPromptEffect(effect, view, label, { ...context, cwd: context.state.cwd }, { suspendTui }) } ) }Согласно coding guidelines: "Use exhaustive pattern matching with Effect.Match instead of switch statements."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/docker-git/menu-auth.ts` around lines 89 - 107, Replace the boolean OR chain used to compute suspendTui inside submitAuthPrompt with an exhaustive pattern match over view.flow (use Effect.Match.exhaustive or Match.exhaustive per coding guidelines) so all union cases are handled; update the suspendTui argument passed to runAuthPromptEffect (inside submitAuthPrompt) to be the result of that exhaustive match, and ensure the match returns a boolean for each flow variant so future OAuth flows will cause a compile-time failure if not handled.packages/app/src/lib/core/templates-entrypoint/rtk.ts (1)
9-44:⚠️ Potential issue | 🟠 Major | ⚡ Quick winНесоответствие FORMAT THEOREM и реализации: grok не поддерживается RTK.
FORMAT THEOREM (строка 9) обещает
configured(codex, claude, gemini, grok, opencode), однако RTK не поддерживает флаг--grok. Строки 31–32 создают директорию~/.grok, но строк 41–44 содержат только инициализацию дляcodex,claude,geminiиopencode—grokотсутствует.Решение: либо удалите
grokиз FORMAT THEOREM и директорию~/.grok, либо отложите эту часть PR до добавления поддержки--grokв RTK. В текущем состоянии математический инвариант нарушен.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/lib/core/templates-entrypoint/rtk.ts` around lines 9 - 44, The FORMAT THEOREM claims RTK configures "grok" but RTK has no --grok flag, so update renderEntrypointRtkConfig to remove grok references: change the FORMAT THEOREM token list to configured(codex, claude, gemini, opencode) and delete "/home/__SSH_USER__/.grok" from the mkdir and chown paths in the template body (and any related log text), leaving the four actual docker_git_rtk_init_as_user invocations unchanged; this preserves the invariant without adding unsupported RTK behavior.packages/api/src/services/auth-menu.ts (1)
131-146: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winРекомендуется рефакторинг: заменить вложенные тернарные операторы на Match pattern.
Глубоко вложенные тернарные операторы (5+ уровней) трудно читать и поддерживать. Согласно coding guidelines, следует использовать
Match.value().pipe()с.exhaustive()для исчерпывающего анализа union-типов.♻️ Предлагаемый рефакторинг с использованием Match pattern
+import { Match } from "effect" + const syncMessage = (request: AuthMenuRequest): string => - request.flow === "GithubRemove" - ? `chore(state): auth gh logout ${canonicalLabel(request.label)}` - : request.flow === "GitSet" - ? `chore(state): auth git ${canonicalLabel(request.label)}` - : request.flow === "GitRemove" - ? `chore(state): auth git logout ${canonicalLabel(request.label)}` - : request.flow === "ClaudeLogout" - ? `chore(state): auth claude logout ${canonicalLabel(request.label)}` - : request.flow === "GeminiApiKey" - ? `chore(state): auth gemini ${canonicalLabel(request.label)}` - : request.flow === "GeminiLogout" - ? `chore(state): auth gemini logout ${canonicalLabel(request.label)}` - : request.flow === "GrokApiKey" - ? `chore(state): auth grok ${canonicalLabel(request.label)}` - : `chore(state): auth grok logout ${canonicalLabel(request.label)}` + Match.value(request.flow).pipe( + Match.when("GithubRemove", () => `chore(state): auth gh logout ${canonicalLabel(request.label)}`), + Match.when("GitSet", () => `chore(state): auth git ${canonicalLabel(request.label)}`), + Match.when("GitRemove", () => `chore(state): auth git logout ${canonicalLabel(request.label)}`), + Match.when("ClaudeLogout", () => `chore(state): auth claude logout ${canonicalLabel(request.label)}`), + Match.when("GeminiApiKey", () => `chore(state): auth gemini ${canonicalLabel(request.label)}`), + Match.when("GeminiLogout", () => `chore(state): auth gemini logout ${canonicalLabel(request.label)}`), + Match.when("GrokApiKey", () => `chore(state): auth grok ${canonicalLabel(request.label)}`), + Match.when("GrokLogout", () => `chore(state): auth grok logout ${canonicalLabel(request.label)}`), + Match.exhaustive + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/src/services/auth-menu.ts` around lines 131 - 146, The syncMessage function currently uses deeply nested ternary operators to map AuthMenuRequest.flow to commit message strings; replace that chain with a clear Match.value() pattern match over request.flow (using Match.value(request.flow).pipe(...).exhaustive()) that returns the same strings by calling canonicalLabel(request.label) where needed; update syncMessage to switch on each flow case (GithubRemove, GitSet, GitRemove, ClaudeLogout, GeminiApiKey, GeminiLogout, GrokApiKey, GrokLogout) and return the exact corresponding message for each case, ensuring exhaustiveness for the union type AuthMenuRequest so future flows cause a compile-time error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/api/src/auth-terminal-runner.ts`:
- Around line 7-8: parseFlow currently maps any invalid or undefined value to
"ClaudeOauth" silently; change it to fail-fast instead: in the parseFlow
function (returning AuthTerminalRunnerFlow) validate that value is exactly one
of "ClaudeOauth" | "GeminiOauth" | "GrokOauth" and return it, otherwise throw a
descriptive Error (include the invalid value) so callers don't silently proceed
with the wrong provider; update any call sites expecting a default accordingly.
In `@packages/api/src/services/auth-terminal-sessions.ts`:
- Around line 72-76: The nested ternary that maps request.flow to a command
string should be replaced with an exhaustive Match-based switch to ensure
compile-time coverage of all AuthTerminalFlow variants: use
Match.value(request.flow).pipe(...) with Match.when handlers for "ClaudeOauth",
"GeminiOauth", and "GrokOauth" that each return the appropriate backtick string
including the existing suffix, and finish with Match.exhaustive() so new flows
cannot silently fall through to the wrong label; update the return expression
accordingly where request.flow is used.
In `@packages/api/src/services/project-auth.ts`:
- Around line 239-258: Add a TSDoc comment for the hasGrokAccountCredentials
function describing its purpose (checks for GROK API credentials in three
locations), its parameters (fs: FileSystem.FileSystem, accountPath: string), the
return type (Effect.Effect<boolean, PlatformError> indicating success boolean or
PlatformError), and the behavior/side-effects (it checks .api-key via
hasFileAtPath, GROK_API_KEY in .env via hasApiKeyInEnvFile, and OAuth token in
.grok/user-settings.json via hasNonEmptyOauthToken), and note possible errors
propagated from PlatformError; place the comment immediately above the
hasGrokAccountCredentials declaration.
In `@packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts`:
- Around line 28-71: Add full TSDoc and functional comments to the CORE pure
function buildTemplateConfigBase: include `@pure` (true/false), `@effect` (required
services or "none"), `@invariant` (any mathematical invariants), `@precondition`
(valid shape/constraints of input Pick<BuildTemplateConfigInput,...>),
`@postcondition` (returned object matches CreateCommand["config"] subset), and
`@complexity` (time and space). Also add the functional comment block with CHANGE,
WHY, QUOTE (or n/a), REF, SOURCE (or n/a), FORMAT THEOREM, PURITY, INVARIANT,
COMPLEXITY describing intent, rationale, references and guarantees for
buildTemplateConfigBase and reference the function name and the exact fields it
maps (containerName, serviceName, sshUser, sshPort, repoUrl, repoRef, targetDir,
volumeName, dockerGitPath, authorizedKeysPath, envGlobalPath, envProjectPath,
codexAuthPath, codexSharedAuthPath, codexHome, geminiAuthPath, geminiHome,
grokAuthPath, grokHome) to make clear mapping and postconditions.
- Around line 73-93: The exported CORE function buildTemplateConfig lacks the
required comprehensive TSDoc; add a full TSDoc block immediately above the
exported function buildTemplateConfig describing the function purpose, each
parameter in BuildTemplateConfigInput (`@param`), the return type
CreateCommand["config"] (`@returns`), and include the required tags: `@pure`,
`@effect` (list any external deps such as buildTemplateConfigBase and
defaultTemplateConfig), `@invariant` (describe any invariants about returned
config), `@precondition` (validations on input fields like cpuLimit/ramLimit/gpu),
`@postcondition` (what properties will always be present in the returned config),
and `@complexity` (Big-O for any significant work); ensure references to internal
symbols buildTemplateConfigBase and defaultTemplateConfig are mentioned in the
text so readers can locate dependencies.
In `@packages/app/src/lib/core/auto-agent-flags.ts`:
- Line 23: Update the error string that sets the `reason` (currently "expected
one of: claude, codex, gemini, grok") to include "auto" so it matches the
accepted mode (`requested === "auto"`); ensure the `reason` value lists all
supported modes including "auto" and stays synchronized with any validation
logic that references `requested`.
In `@packages/app/src/lib/core/command-builders-template.ts`:
- Around line 28-94: The two exported functions buildTemplateConfigBase and
buildTemplateConfig are missing the required comprehensive TSDoc and functional
markers; add TSDoc blocks above each function documenting parameters and return
types and include the mandated tags/markers: `@pure`, `@invariant`, `@precondition`,
`@postcondition`, `@complexity` (with O-notation), and the functional comment fields
(CHANGE, WHY, QUOTE or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY
(CORE|SHELL), EFFECT signature if applicable, INVARIANT, COMPLEXITY). Ensure the
docs reference the function signature symbols buildTemplateConfigBase and
buildTemplateConfig and succinctly describe input: BuildTemplateConfigInput and
output: CreateCommand["config"], plus any important invariants (e.g., which
fields are mapped/copied), and place the blocks immediately above each function
declaration.
In `@packages/app/src/lib/core/templates/docker-compose.ts`:
- Around line 222-224: Комментарий после переменных окружения не соответствует
своему назначению: переменная fragments.maybeGrokAuthLabelEnv снабжена
комментарием, который сейчас стоит одновременно после
fragments.maybeAgentModeEnv и fragments.maybeAgentAutoEnv, что вводит в
заблуждение; исправьте шаблон в docker-compose.ts так, чтобы комментарий "#
Optional Grok account label selector (maps to GROK_AUTH_LABEL)" стоял
непосредственно после fragments.maybeGrokAuthLabelEnv, а для
fragments.maybeAgentModeEnv и fragments.maybeAgentAutoEnv добавьте свои
отдельные комментарии (или уберите их), чтобы каждый комментарий однозначно
относился к соответствующей переменной.
In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Around line 113-114: Строка, которая маскирует провал установки Grok CLI ("RUN
grok --version >/dev/null || true") должна быть исправлена: замените или удалите
конструкцию "|| true" и/или уберите перенаправление в /dev/null so that the
subsequent check fails the build when the CLI is not present; specifically
update the two Dockerfile RUN commands ("RUN npm install -g grok-dev@latest
--force" and the following "RUN grok --version >/dev/null || true") so that the
image build exits non‑zero if "grok --version" fails (e.g., use plain "RUN grok
--version" or an explicit check like "RUN command -v grok >/dev/null" without
"|| true").
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 209-214: The code currently runs runCommandExitCode with "chmod -R
777" on credentialsDir which makes secrets world-readable/writable; change to
set owner-only permissions (e.g., directories 700 and files 600) or use a safe
recursive chmod like "chmod -R u+rwX,go-rwx" so only the owner can
read/write/execute, and remove the blanket Effect.orElse(() =>
Effect.succeed(0)) that silences failures so permission errors surface; update
the same pattern in the similar block referenced later (the other chmod usage
around the 230-255 region) to use the secure permission command and proper error
handling, locating the changes around the runCommandExitCode and credentialsDir
symbols.
- Around line 193-206: The cleanup fallback currently swallows errors
(removeFallback is defined with Effect.orElse(() => Effect.void)), so if both
fs.remove(credentialsDir) and the docker fallback fail the effect is treated as
success and code proceeds; remove the swallowing wrapper from removeFallback
(keep runCommandExitCode(...).pipe(Effect.asVoid) but do not orElse to
Effect.void) so that if the docker fallback fails the overall effect fails and
propagation stops; ensure fs.remove(...).pipe(Effect.orElse(() =>
removeFallback)) remains so the fallback is attempted but failures are not
suppressed.
- Around line 165-170: The current check in hasGrokCredentials (which uses
isRegularFile(grokUserSettingsPath(accountPath)) and then treats any non-empty
user-settings.json as valid) incorrectly treats bootstrap files created by
writeInitialGrokSettings(..., null) as authenticated; change hasGrokCredentials
to parse the JSON from fs.readFileString(grokUserSettingsPath(accountPath)) and
verify presence of real credential fields (e.g., non-null/non-empty token,
apiKey, or username fields your code uses) rather than mere file existence or
non-empty content, so resolveGrokAuthMethod() won't return "user-settings" for
bootstrap files; apply the same validation logic where similar checks exist
(around the other occurrence mentioned, lines ~250-255) and use
grokUserSettingsPath, hasGrokCredentials, resolveGrokAuthMethod, and
writeInitialGrokSettings names to locate the changes.
- Around line 55-63: The Dockerfile RUN step currently installs grok-dev using
the floating tag and force flag; replace the unstable install invocation that
uses "grok-dev@latest" and "--force" with a pinned install of grok-dev version
1.1.6 so the Docker build is deterministic (locate the RUN npm install -g
grok-dev... line in the auth-grok helper Docker snippet and change it to install
grok-dev@1.1.6 without --force).
In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 79-101: The fixGrokAuthPermissions function currently runs a
docker alpine container to chmod -R 777 on the Grok auth directory; change this
to set restrictive permissions or fix ownership instead: replace the chmod args
in fixGrokAuthPermissions to use "chmod -R 700" (or "750" if group-read is
required) or, preferably, run "chown -R <user>:<group>" inside the container
before applying more restrictive chmod; ensure the CommandFailedError and
runCommandWithExitCodes call remain unchanged but update the args array passed
to docker to reflect the safer permission/ownership commands.
- Around line 38-43: Replace the unsupported env vars in the env array
(currently `HOME=${containerPath}`, `NO_BROWSER=true`, `GROK_NO_BROWSER=true`,
`MCP_PLAYWRIGHT_ISOLATED=1`) with a supported approach: look up the
grok/grok-dev CLI docs and either (a) pass the official CLI flag to disable
browser opening (e.g., run the "grok login" command with the documented flag
such as "--no-browser" or the exact flag/name you find) or (b) if no flag/ENV
exists, remove `NO_BROWSER`/`GROK_NO_BROWSER` and implement a headless fallback
in the auth-grok-oauth flow that spawns "grok login", captures the printed
authorization URL from stdout, prompts the user to open it manually and paste
the callback, and include a runtime version check of grok-dev to ensure the
chosen method is supported; update the code that constructs the env array and
the place that calls "grok login" accordingly.
In `@packages/app/src/lib/usecases/auth-grok.ts`:
- Line 40: The chmod call for apiKeyFilePath is currently wrapped with
orElseSucceed which suppresses failures; change this so permission-setting
errors are not swallowed—remove the orElseSucceed around
fs.chmod(apiKeyFilePath, 0o600) (or replace it with explicit error handling that
logs and rethrows) so that failures propagate and cause the operation to fail;
locate the call to fs.chmod and the use of orElseSucceed in
usecases/auth-grok.ts (reference symbols: fs.chmod, apiKeyFilePath,
orElseSucceed) and ensure the code fails on chmod errors rather than continuing
silently.
In `@packages/app/tests/docker-git/parser-auth.test.ts`:
- Around line 22-41: Add a fast-check property-based test that repeatedly runs
parseOrThrow for Grok auth commands with generated valid label strings and
asserts the invariants instead of a single static case: generate labels
(non-empty, trimmed, maybe alphanumeric/spaces) and for each value call
parseOrThrow(["auth","grok","login","--label", label, "--web"]),
parseOrThrow(["auth","grok","status","--label", label]) and
parseOrThrow(["auth","grok","logout","--label", label]) and assert the returned
tags are AuthGrokLogin/AuthGrokStatus/AuthGrokLogout respectively, that
login.isWeb === true, and that .grokAuthPath === ".docker-git/.orch/auth/grok"
for all three results; integrate fast-check into the existing it.effect test (or
add a new one) and fail on any counterexample so the parser invariants are
validated across many generated labels.
In `@packages/lib/src/core/auto-agent-flags.ts`:
- Line 22: The error message for the --auto flag omits "auto" in the
allowed-values text; update the `reason` string in
packages/lib/src/core/auto-agent-flags.ts (the `reason` property for the --auto
flag) to include "auto" alongside "claude, codex, gemini, grok" so the hint
correctly reflects that "auto" is a valid option.
In `@packages/lib/src/core/domain.ts`:
- Line 58: The public type AgentMode was extended to include "grok" and needs a
functional comment block above the AgentMode declaration documenting the CHANGE,
WHY, QUOTE (requirement), and REF markers; update the comment for the AgentMode
type to state that "grok" was added (CHANGE), explain the architectural reason
or compatibility rationale (WHY), cite the requirement or ticket text that
mandated the addition (QUOTE), and include a reference ID (REF), ensuring the
comment is adjacent to the AgentMode type declaration to keep the public API
change discoverable.
In `@packages/lib/src/core/templates-entrypoint/agent.ts`:
- Around line 43-45: The generated AGENT_ENV_FILE currently ends up
world-readable because the script writes /etc/profile.d/grok-config.sh contents
then sets mode via "chmod 644", exposing secrets; change the post-write steps to
chown the file to the runtime user and group and tighten permissions (e.g., set
to 640 or 600) and ensure group is the runtime group used by the agent; update
the sequence around AGENT_ENV_FILE, replacing the chmod 644 usage with a chown
to the agent runtime user/group (use your runtime user symbol/variable) followed
by chmod 640 (or 600) so only the agent user/group can read the file.
In `@packages/lib/src/core/templates/docker-compose.ts`:
- Around line 221-223: Split the combined env fragment line into two separate
lines so each fragment has the correct comment: render
fragments.maybeGrokAuthLabelEnv on its own line with the "Optional Grok account
label selector (maps to GROK_AUTH_LABEL)" comment, and render
fragments.maybeAgentModeEnv and fragments.maybeAgentAutoEnv together on the next
line with a distinct comment like "Optional agent mode and auto-start
configuration"; update the template where these symbols appear so comments align
with the corresponding fragments (maybeGrokAuthLabelEnv, maybeAgentModeEnv,
maybeAgentAutoEnv).
In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 113-114: В шаблоне Dockerfile замените установку неофициального
пакета и мягкую проверку на официальную установку или явное, зафиксированное
стороннее решение: вместо "RUN npm install -g grok-dev@latest --force" и "RUN
grok --version >/dev/null || true" либо (предпочтительно) скачайте и установите
официальное xAI Grok Build через curl/официальный инсталлятор (подставив
проверяемую версию/хеш), либо если оставляете сторонний пакет — уберите
"--force", зафиксируйте конкретную версию вместо "latest", удалите "|| true" и
добавьте явную проверку выхода с ошибкой при неуспешной установке; если
выбираете сторонний пакет, потребуйте security review/approval перед мерджем.
In `@packages/lib/src/usecases/auth-grok-helpers.ts`:
- Around line 208-214: The chmod 777 call in the runCommandExitCode invocation
grants excessive permissions to credentialsDir; replace it with a safer,
restrictive approach: run commands that set directories to 700 and files to 600
(e.g., use find to apply chmod 700 to all directories under credentialsDir and
chmod 600 to all files) instead of ["-R","777",credentialsDir], keeping the call
site runCommandExitCode({ cwd, command: "chmod", args: ... }) and credentialsDir
variable; preserve the Effect.orElse(() => Effect.succeed(0)) error handling
around the command(s).
- Around line 59-63: Replace the npm global install that uses an unpredictable
latest tag and --force: find occurrences of the literal string "npm install -g
grok-dev@latest --force" in the Dockerfile template generators and change them
to a pinned, explicit version like "npm install -g grok-dev@1.1.6" and remove
the "--force" flag; update each template function that emits the Dockerfile
snippet (the Dockerfile template generator(s) that produce the RUN curl ... &&
apt-get ... && npm install -g ... line) so they hardcode the stable version
instead of `@latest` and do not pass --force.
In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 79-101: The function fixGrokAuthPermissions currently runs chmod
-R 777 via runCommandWithExitCodes which grants world-writable access to Grok
credentials; change the chmod invocation in the args passed to
runCommandWithExitCodes (the array containing "chmod", "-R", "777",
containerPath) to a safe permission such as "700" (or "755" if group/other read
is required) so only the owner can read/write/execute the credentials directory;
keep the CommandFailedError creation and the Effect.tapError/Effect.orElse
handling unchanged.
- Around line 103-130: Add a TSDoc block above the exported
runGrokOauthLoginWithPrompt function that documents its purpose and behavior and
includes the required tags: `@pure`, `@effect` (describe the Effect type and failure
channels AuthError | CommandFailedError | PlatformError), `@invariant` (state
invariants such as cwd/accountPath resolution), `@precondition` (valid cwd and
accountPath, docker available), `@postcondition` (prints OAuth instructions, runs
docker auth flow, fixes permissions), and `@complexity` (time/space complexity).
Also document parameters (cwd, accountPath, options.image,
options.containerPath) and the return type (Effect.Effect<void, AuthError |
CommandFailedError | PlatformError, CommandExecutor.CommandExecutor>) so the
public API is fully covered for runGrokOauthLoginWithPrompt.
- Around line 46-67: Add full TSDoc to the exported function
buildDockerGrokAuthArgs (include `@pure`, `@effect`, `@invariant`, `@precondition`,
`@postcondition`, `@complexity`) and implement input validation for
spec.containerPath (referencing DockerGrokAuthSpec and buildDockerGrokAuthArgs)
so the function rejects or throws a clear error when containerPath is empty,
contains null bytes, contains path traversal patterns (e.g., "..") or is not an
absolute/normalized path; ensure you validate before using it in the args array
and document the precondition/postcondition that containerPath will be a
normalized absolute path and that the returned array contains the Docker run
args including the validated mount and workdir.
In `@packages/lib/src/usecases/auth-grok.ts`:
- Around line 50-62: Параметр _command в сигнатуре функции authGrokLoginCli не
используется; либо удалите его из сигнатуры (заменив экспорт на
authGrokLoginCli(): Effect.Effect<...>) либо начните явно использовать его
внутри Effect.gen (например передав необходимые поля в логи/логику) to satisfy
the interface; обновите все вызовы/auth signatures accordingly so they match the
new signature or continue accepting the parameter if required for interface
compatibility.
- Around line 76-78: The code currently calls prepareGrokCredentialsDir(...)
then immediately writeInitialGrokSettings(..., null) which can leave a null API
key on disk if the subsequent OAuth flow fails; update the flow in auth-grok.ts
so you only call writeInitialGrokSettings after the OAuth process completes
successfully (or, alternatively, perform the write as part of a transactional
sequence and remove/rollback the created settings on any OAuth error).
Concretely, move the writeInitialGrokSettings call to after the successful
return of the OAuth routine (or add a catch/finally that deletes or restores the
credentials file on failure), referencing prepareGrokCredentialsDir and
writeInitialGrokSettings to locate where to change behavior.
- Line 40: Хранится молчаливое подавление ошибки chmod при установке прав на
файл API-ключа: в месте с вызовом fs.chmod внутри usecases/auth-grok.ts удалите
использование Effect.orElseSucceed(() => void 0) и позвольте ошибке/эффекту
проброситься (или замените на явный Effect.fail с информативным сообщением),
чтобы не продолжать работу при неудачной установке прав; убедитесь, что ошибка
содержит контекст (путь файла и причину) и приводит к отказу
аутентификации/завершению процесса вместо бесшумного продолжения.
In `@packages/lib/tests/usecases/auth-grok.test.ts`:
- Around line 10-23: Добавьте краткую TSDoc над helper-функцией withTempDir,
объясняющую её назначение (создаёт временную директорию для теста и передаёт её
в callback), описывающую использование Effect.scoped для управления жизненным
циклом ресурса, перечисляющую параметр use (callback, получающий tempDir:
string) и возвращаемое значение (Effect, который может содержать результат теста
или FileSystem.FileSystem), и упомяните префикс временной директории; ссылаясь
на сimbols withTempDir, Effect.scoped и FileSystem.FileSystem, чтобы облегчить
поиск места вставки документации.
---
Outside diff comments:
In `@packages/api/src/services/auth-menu.ts`:
- Around line 131-146: The syncMessage function currently uses deeply nested
ternary operators to map AuthMenuRequest.flow to commit message strings; replace
that chain with a clear Match.value() pattern match over request.flow (using
Match.value(request.flow).pipe(...).exhaustive()) that returns the same strings
by calling canonicalLabel(request.label) where needed; update syncMessage to
switch on each flow case (GithubRemove, GitSet, GitRemove, ClaudeLogout,
GeminiApiKey, GeminiLogout, GrokApiKey, GrokLogout) and return the exact
corresponding message for each case, ensuring exhaustiveness for the union type
AuthMenuRequest so future flows cause a compile-time error.
In `@packages/api/src/services/federation.ts`:
- Around line 1694-1699: The resolver resolveAgentProvider must use
Effect.Match.exhaustive to perform exhaustive pattern matching on the raw
provider string instead of the current ternary; update the function to compute
raw from subscription?.agentProvider ||
process.env["DOCKER_GIT_EXCHANGE_AGENT_PROVIDER"] and then call Match.exhaustive
with cases for "claude", "opencode", "grok", "custom", and "codex" (mapping each
to the corresponding AgentProvider) and an explicit default branch that returns
"codex" so all union values are handled; ensure you import Effect.Match and keep
the function signature types (FollowSubscription, AgentProvider) unchanged.
In `@packages/api/src/services/project-auth.ts`:
- Around line 173-197: Add a TSDoc block to the hasApiKeyInEnvFile function that
explains its purpose (checks whether a non-empty env variable named by the `key`
exists in a file), documents parameters `fs: FileSystem.FileSystem`,
`envFilePath: string`, and `key: string`, and states the return type
`Effect.Effect<boolean, PlatformError>` along with behavior on missing files or
read errors (returns false or uses provided Effect error handling). Mention
examples of expected env line formats (e.g., KEY=value, KEY="value") and note
that quotes are stripped and whitespace trimmed so only non-empty values return
true. Ensure the TSDoc appears immediately above the hasApiKeyInEnvFile
declaration.
In `@packages/app/src/docker-git/menu-auth.ts`:
- Around line 89-107: Replace the boolean OR chain used to compute suspendTui
inside submitAuthPrompt with an exhaustive pattern match over view.flow (use
Effect.Match.exhaustive or Match.exhaustive per coding guidelines) so all union
cases are handled; update the suspendTui argument passed to runAuthPromptEffect
(inside submitAuthPrompt) to be the result of that exhaustive match, and ensure
the match returns a boolean for each flow variant so future OAuth flows will
cause a compile-time failure if not handled.
In `@packages/app/src/docker-git/menu-project-auth.ts`:
- Around line 132-138: Replace the manual if-chain checking action
(ProjectGithubDisconnect | ProjectGitDisconnect | ProjectClaudeDisconnect |
ProjectGeminiDisconnect | ProjectGrokDisconnect) with an exhaustive pattern
match using Match.value(action).pipe(..., Match.exhaustive) to guarantee
compile-time coverage of the ProjectAuthMenuAction union; follow the same
pattern used in projectAuthSuccessMessage
(Match.value(...).pipe(Match.when(...), Match.exhaustive)), creating Match.when
clauses for each connect/disconnect branch and delegating to
startProjectAuthPrompt or the appropriate disconnect handling so any new union
variant will force a compile-time handling decision rather than silently falling
through.
In `@packages/app/src/lib/core/templates-entrypoint/rtk.ts`:
- Around line 9-44: The FORMAT THEOREM claims RTK configures "grok" but RTK has
no --grok flag, so update renderEntrypointRtkConfig to remove grok references:
change the FORMAT THEOREM token list to configured(codex, claude, gemini,
opencode) and delete "/home/__SSH_USER__/.grok" from the mkdir and chown paths
in the template body (and any related log text), leaving the four actual
docker_git_rtk_init_as_user invocations unchanged; this preserves the invariant
without adding unsupported RTK behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2789038d-8dd6-4ae0-aa69-a06d1d9b5989
📒 Files selected for processing (106)
packages/api/src/api/contracts.tspackages/api/src/api/schema.tspackages/api/src/auth-terminal-runner.tspackages/api/src/http.tspackages/api/src/services/agents.tspackages/api/src/services/auth-menu.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/services/container-tasks-core.tspackages/api/src/services/federation.tspackages/api/src/services/project-auth.tspackages/api/src/services/project-prompts.tspackages/api/src/services/project-skills.tspackages/api/src/services/projects.tspackages/api/src/ui.tspackages/api/tests/agents.test.tspackages/app/src/docker-git/api-auth-codec.tspackages/app/src/docker-git/api-client-create.tspackages/app/src/docker-git/api-client.tspackages/app/src/docker-git/cli/parser-apply.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/docker-git/cli/parser-options.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/docker-git/frontend-lib/core/auto-agent-flags.tspackages/app/src/docker-git/frontend-lib/core/command-builders-template.tspackages/app/src/docker-git/frontend-lib/core/command-builders.tspackages/app/src/docker-git/frontend-lib/core/command-options.tspackages/app/src/docker-git/frontend-lib/core/domain.tspackages/app/src/docker-git/frontend-lib/core/template-defaults.tspackages/app/src/docker-git/menu-auth-effects.tspackages/app/src/docker-git/menu-auth-shared.tspackages/app/src/docker-git/menu-auth-snapshot-builder.tspackages/app/src/docker-git/menu-auth.tspackages/app/src/docker-git/menu-project-auth-shared.tspackages/app/src/docker-git/menu-project-auth.tspackages/app/src/docker-git/menu-render-auth.tspackages/app/src/docker-git/menu-render-project-auth.tspackages/app/src/docker-git/menu-types.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/core/auth-domain.tspackages/app/src/lib/core/auto-agent-flags.tspackages/app/src/lib/core/command-builders-template.tspackages/app/src/lib/core/command-builders.tspackages/app/src/lib/core/command-options.tspackages/app/src/lib/core/domain.tspackages/app/src/lib/core/template-defaults.tspackages/app/src/lib/core/templates-entrypoint.tspackages/app/src/lib/core/templates-entrypoint/agent.tspackages/app/src/lib/core/templates-entrypoint/base.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/core/templates-entrypoint/project-rules.tspackages/app/src/lib/core/templates-entrypoint/rtk.tspackages/app/src/lib/core/templates/docker-compose.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/shell/config.tspackages/app/src/lib/shell/docker-daemon-access.tspackages/app/src/lib/usecases/apply-overrides.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth.tspackages/app/src/web/action-prompt.tspackages/app/src/web/actions-auth.tspackages/app/src/web/api-auth-schema.tspackages/app/src/web/api-prompts-schema.tspackages/app/src/web/api-schema.tspackages/app/src/web/api-skills-schema.tspackages/app/src/web/api-skills.tspackages/app/src/web/api-types.tspackages/app/src/web/api.tspackages/app/src/web/panel-auth.tsxpackages/app/src/web/panel-project-auth.tsxpackages/app/src/web/panel-project-prompts.tsxpackages/app/src/web/panel-project-skills.tsxpackages/app/tests/docker-git/actions-github-oauth.test.tspackages/app/tests/docker-git/parser-auth.test.tspackages/lib/src/core/auth-domain.tspackages/lib/src/core/auto-agent-flags.tspackages/lib/src/core/command-builders-template.tspackages/lib/src/core/command-builders.tspackages/lib/src/core/command-options.tspackages/lib/src/core/domain.tspackages/lib/src/core/template-defaults.tspackages/lib/src/core/templates-entrypoint.tspackages/lib/src/core/templates-entrypoint/agent.tspackages/lib/src/core/templates-entrypoint/base.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/project-rules.tspackages/lib/src/core/templates-entrypoint/rtk.tspackages/lib/src/core/templates/docker-compose.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/shell/config.tspackages/lib/src/shell/docker-daemon-access.tspackages/lib/src/usecases/apply-overrides.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/lib/src/usecases/auth.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/tests/usecases/auth-grok.test.ts
| const buildTemplateConfigBase = ( | ||
| input: Pick<BuildTemplateConfigInput, "repo" | "names" | "paths"> | ||
| ): Pick< | ||
| CreateCommand["config"], | ||
| | "containerName" | ||
| | "serviceName" | ||
| | "sshUser" | ||
| | "sshPort" | ||
| | "repoUrl" | ||
| | "repoRef" | ||
| | "targetDir" | ||
| | "volumeName" | ||
| | "dockerGitPath" | ||
| | "authorizedKeysPath" | ||
| | "envGlobalPath" | ||
| | "envProjectPath" | ||
| | "codexAuthPath" | ||
| | "codexSharedAuthPath" | ||
| | "codexHome" | ||
| | "geminiAuthPath" | ||
| | "geminiHome" | ||
| | "grokAuthPath" | ||
| | "grokHome" | ||
| > => ({ | ||
| containerName: input.names.containerName, | ||
| serviceName: input.names.serviceName, | ||
| sshUser: input.repo.sshUser, | ||
| sshPort: input.repo.sshPort, | ||
| repoUrl: input.repo.repoUrl, | ||
| repoRef: input.repo.repoRef, | ||
| targetDir: input.repo.targetDir, | ||
| volumeName: input.names.volumeName, | ||
| dockerGitPath: input.paths.dockerGitPath, | ||
| authorizedKeysPath: input.paths.authorizedKeysPath, | ||
| envGlobalPath: input.paths.envGlobalPath, | ||
| envProjectPath: input.paths.envProjectPath, | ||
| codexAuthPath: input.paths.codexAuthPath, | ||
| codexSharedAuthPath: input.paths.codexSharedAuthPath, | ||
| codexHome: input.paths.codexHome, | ||
| geminiAuthPath: input.paths.geminiAuthPath, | ||
| geminiHome: input.paths.geminiHome, | ||
| grokAuthPath: input.paths.grokAuthPath, | ||
| grokHome: input.paths.grokHome | ||
| }) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Добавить обязательную документацию для CORE-функции.
Функция buildTemplateConfigBase является чистой функцией CORE-слоя и должна содержать полную TSDoc-документацию и функциональные комментарии. Согласно руководствам по кодированию, все CORE-функции должны включать:
- TSDoc:
@pure,@effect,@invariant,@precondition,@postcondition,@complexity - Функциональные комментарии: CHANGE, WHY, QUOTE(ТЗ) или n/a, REF, SOURCE или n/a, FORMAT THEOREM, PURITY, INVARIANT, COMPLEXITY
📝 Предлагаемый шаблон документации
+// CHANGE: extract base template config builder from repo/names/paths inputs
+// WHY: centralize config derivation logic for reuse across command builders
+// QUOTE(ТЗ): n/a
+// REF: PR-305-grok-auth-support
+// SOURCE: n/a
+// FORMAT THEOREM: ∀input: buildTemplateConfigBase(input) -> Pick<CreateCommand["config"], ...>
+// PURITY: CORE
+// INVARIANT: output config fields are derived deterministically from input
+// COMPLEXITY: O(1)/O(1)
+/**
+ * Builds the base template configuration from repository, naming, and path inputs.
+ *
+ * `@param` input - Repository basics, naming config, and path config.
+ * `@returns` Subset of CreateCommand config containing core fields.
+ * `@pure` true
+ * `@effect` none; CORE pure function.
+ * `@invariant` all output fields are deterministically derived from input.
+ * `@precondition` input.names and input.paths contain valid non-empty strings.
+ * `@postcondition` returned config includes all auth paths (codex/gemini/grok).
+ * `@complexity` O(1) time / O(1) space.
+ */
const buildTemplateConfigBase = (Согласно руководствам по кодированию: «Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)».
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts`
around lines 28 - 71, Add full TSDoc and functional comments to the CORE pure
function buildTemplateConfigBase: include `@pure` (true/false), `@effect` (required
services or "none"), `@invariant` (any mathematical invariants), `@precondition`
(valid shape/constraints of input Pick<BuildTemplateConfigInput,...>),
`@postcondition` (returned object matches CreateCommand["config"] subset), and
`@complexity` (time and space). Also add the functional comment block with CHANGE,
WHY, QUOTE (or n/a), REF, SOURCE (or n/a), FORMAT THEOREM, PURITY, INVARIANT,
COMPLEXITY describing intent, rationale, references and guarantees for
buildTemplateConfigBase and reference the function name and the exact fields it
maps (containerName, serviceName, sshUser, sshPort, repoUrl, repoRef, targetDir,
volumeName, dockerGitPath, authorizedKeysPath, envGlobalPath, envProjectPath,
codexAuthPath, codexSharedAuthPath, codexHome, geminiAuthPath, geminiHome,
grokAuthPath, grokHome) to make clear mapping and postconditions.
| export const buildTemplateConfig = (input: BuildTemplateConfigInput): CreateCommand["config"] => ({ | ||
| ...buildTemplateConfigBase(input), | ||
| gitTokenLabel: input.gitTokenLabel, | ||
| skipGithubAuth: input.skipGithubAuth, | ||
| codexAuthLabel: input.codexAuthLabel, | ||
| claudeAuthLabel: input.claudeAuthLabel, | ||
| geminiAuthLabel: input.geminiAuthLabel, | ||
| grokAuthLabel: input.grokAuthLabel, | ||
| cpuLimit: input.cpuLimit, | ||
| ramLimit: input.ramLimit, | ||
| playwrightCpuLimit: input.playwrightCpuLimit, | ||
| playwrightRamLimit: input.playwrightRamLimit, | ||
| gpu: input.gpu, | ||
| dockerNetworkMode: input.dockerNetworkMode, | ||
| dockerSharedNetworkName: input.dockerSharedNetworkName, | ||
| enableMcpPlaywright: input.enableMcpPlaywright, | ||
| bunVersion: defaultTemplateConfig.bunVersion, | ||
| agentMode: input.agentMode, | ||
| agentAuto: input.agentAuto, | ||
| clonedOnHostname: input.clonedOnHostname | ||
| }) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Добавить обязательную документацию для экспортируемой CORE-функции.
Экспортируемая функция buildTemplateConfig должна содержать полную TSDoc и функциональные комментарии согласно руководствам.
📝 Предлагаемый шаблон документации
+// CHANGE: build complete template config from all input parameters
+// WHY: provide single source of truth for CreateCommand config construction
+// QUOTE(ТЗ): n/a
+// REF: PR-305-grok-auth-support
+// SOURCE: n/a
+// FORMAT THEOREM: ∀input: buildTemplateConfig(input) -> CreateCommand["config"]
+// PURITY: CORE
+// INVARIANT: output combines base config with resource limits, auth labels, and agent settings
+// COMPLEXITY: O(1)/O(1)
+/**
+ * Builds the complete template configuration from all input parameters.
+ *
+ * `@param` input - Complete build template configuration input.
+ * `@returns` Full CreateCommand configuration object.
+ * `@pure` true
+ * `@export`
+ * `@effect` none; CORE pure function.
+ * `@invariant` combines base config with all optional override fields.
+ * `@precondition` input satisfies BuildTemplateConfigInput type constraints.
+ * `@postcondition` returned config is valid CreateCommand["config"].
+ * `@complexity` O(1) time / O(1) space.
+ */
export const buildTemplateConfig = (input: BuildTemplateConfigInput): CreateCommand["config"] => ({Согласно руководствам по кодированию: «TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation».
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts`
around lines 73 - 93, The exported CORE function buildTemplateConfig lacks the
required comprehensive TSDoc; add a full TSDoc block immediately above the
exported function buildTemplateConfig describing the function purpose, each
parameter in BuildTemplateConfigInput (`@param`), the return type
CreateCommand["config"] (`@returns`), and include the required tags: `@pure`,
`@effect` (list any external deps such as buildTemplateConfigBase and
defaultTemplateConfig), `@invariant` (describe any invariants about returned
config), `@precondition` (validations on input fields like cpuLimit/ramLimit/gpu),
`@postcondition` (what properties will always be present in the returned config),
and `@complexity` (Big-O for any significant work); ensure references to internal
symbols buildTemplateConfigBase and defaultTemplateConfig are mentioned in the
text so readers can locate dependencies.
| _tag: "InvalidOption", | ||
| option: "--auto", | ||
| reason: "expected one of: claude, codex" | ||
| reason: "expected one of: claude, codex, gemini, grok" |
There was a problem hiding this comment.
Синхронизируйте текст ошибки с фактической поддержкой значения auto.
requested === "auto" принимается как корректный режим, но в сообщении об ошибке это значение отсутствует.
💡 Предлагаемая правка
- reason: "expected one of: claude, codex, gemini, grok"
+ reason: "expected one of: auto, claude, codex, gemini, grok"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/core/auto-agent-flags.ts` at line 23, Update the error
string that sets the `reason` (currently "expected one of: claude, codex,
gemini, grok") to include "auto" so it matches the accepted mode (`requested ===
"auto"`); ensure the `reason` value lists all supported modes including "auto"
and stays synchronized with any validation logic that references `requested`.
| export const authGrokLoginCli = ( | ||
| _command: AuthGrokLoginCommand | ||
| ): Effect.Effect<void, PlatformError | CommandFailedError, GrokRuntime> => | ||
| Effect.gen(function*(_) { | ||
| yield* _(Effect.log("Grok CLI supports two authentication methods:")) | ||
| yield* _(Effect.log("")) | ||
| yield* _(Effect.log("1. API Key:")) | ||
| yield* _(Effect.log(" - Use: docker-git menu -> Auth profiles -> Grok CLI: set API key")) | ||
| yield* _(Effect.log("")) | ||
| yield* _(Effect.log("2. OAuth/browser login:")) | ||
| yield* _(Effect.log(" - Use: docker-git menu -> Auth profiles -> Grok CLI: login via OAuth")) | ||
| yield* _(Effect.log(" - Follow the Grok CLI prompts and paste the callback URL when requested")) | ||
| }) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Неиспользуемый параметр _command.
Параметр _command: AuthGrokLoginCommand помечен как неиспользуемый (префикс _), но не используется в теле функции. Если этот параметр необходим для соответствия интерфейсу или будет использован в будущем, оставьте как есть. В противном случае удалите его из сигнатуры.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/src/usecases/auth-grok.ts` around lines 50 - 62, Параметр
_command в сигнатуре функции authGrokLoginCli не используется; либо удалите его
из сигнатуры (заменив экспорт на authGrokLoginCli(): Effect.Effect<...>) либо
начните явно использовать его внутри Effect.gen (например передав необходимые
поля в логи/логику) to satisfy the interface; обновите все вызовы/auth
signatures accordingly so they match the new signature or continue accepting the
parameter if required for interface compatibility.
| const withTempDir = <A, E, R>( | ||
| use: (tempDir: string) => Effect.Effect<A, E, R> | ||
| ): Effect.Effect<A, E, R | FileSystem.FileSystem> => | ||
| Effect.scoped( | ||
| Effect.gen(function*(_) { | ||
| const fs = yield* _(FileSystem.FileSystem) | ||
| const tempDir = yield* _( | ||
| fs.makeTempDirectoryScoped({ | ||
| prefix: "docker-git-auth-grok-" | ||
| }) | ||
| ) | ||
| return yield* _(use(tempDir)) | ||
| }) | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Добавить TSDoc для тестового хелпера.
Хелпер withTempDir использует Effect.scoped для управления ресурсами, что является важным паттерном. Добавьте краткую TSDoc для документирования его назначения и использования.
📝 Предлагаемая документация
+/**
+ * Runs an effect with a scoped temporary directory that is automatically cleaned up.
+ *
+ * `@param` use - Effect to run with the temporary directory path.
+ * `@returns` Scoped effect with FileSystem dependency.
+ * `@pure` true
+ * `@effect` FileSystem
+ */
const withTempDir = <A, E, R>(🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/tests/usecases/auth-grok.test.ts` around lines 10 - 23, Добавьте
краткую TSDoc над helper-функцией withTempDir, объясняющую её назначение
(создаёт временную директорию для теста и передаёт её в callback), описывающую
использование Effect.scoped для управления жизненным циклом ресурса,
перечисляющую параметр use (callback, получающий tempDir: string) и возвращаемое
значение (Effect, который может содержать результат теста или
FileSystem.FileSystem), и упомяните префикс временной директории; ссылаясь на
сimbols withTempDir, Effect.scoped и FileSystem.FileSystem, чтобы облегчить
поиск места вставки документации.
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/lib/src/usecases/agent-auto-select.ts (1)
1-181:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftДублирование кода между packages/lib и packages/app.
Файл идентичен
packages/app/src/lib/usecases/agent-auto-select.ts. Все замечания из review того файла применимы и здесь:
- Отсутствует TSDoc-документация для
hasGrokAuth,availableAgentModes,pickRandomAutoAgentMode- Отсутствуют функциональные комментарии (CHANGE, WHY, PURITY, EFFECT, INVARIANT, COMPLEXITY)
- Одноэлементные массивы-константы можно упростить
Дополнительно: дублирование кода нарушает DRY-принцип и усложняет поддержку. Рассмотрите:
- Если
packages/lib— это shared library, тоpackages/appдолжен импортировать из неё- Если это монорепозиторий, используйте workspace references для переиспользования кода
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/lib/src/usecases/agent-auto-select.ts` around lines 1 - 181, This file duplicates logic from packages/app; remove duplication by centralizing the agent selection code into the shared lib and have packages/app import it (or create a single shared module/workspace reference) and, in this file, replace the duplicated implementation with an import; while consolidating, add TSDoc and the repository's functional comment blocks (CHANGE/WHY/PURITY/EFFECT/INVARIANT/COMPLEXITY) for the functions hasGrokAuth, availableAgentModes, and pickRandomAutoAgentMode, and simplify the single-element constants claudeMode, codexMode, grokMode to plain string literals where used (or export simple string constants) to reduce unnecessary arrays; update resolveAvailableAgentAuth, resolveExplicitAutoAgentMode, and pickRandomAutoAgentMode call sites to use the centralized implementation and ensure exports/signatures match between packages.packages/lib/tests/usecases/agent-auto-select.test.ts (1)
119-219: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy liftТестовое покрытие Grok добавлено, но отсутствуют property-based тесты.
Новые тесты для Grok адресуют замечание из previous review comment о недостаточном покрытии. Однако согласно coding guidelines, требуется использовать property-based testing с fast-check для проверки математических инвариантов.
Примеры инвариантов для property-based тестов:
- Детерминированность при одном доступном режиме: ∀available: |availableModes| = 1 ⇒ result = availableModes[0]
- Принадлежность результата: ∀available: result ∈ availableAgentModes(available)
- Идемпотентность explicit mode: ∀mode ∈ {claude, codex, grok}: agentMode=mode ∧ authAvailable(mode) ⇒ result=mode
- Fail when unavailable: ∀mode: agentMode=mode ∧ ¬authAvailable(mode) ⇒ Effect.fail(InvalidOption)
Пример property-based теста с fast-check
import * as fc from "fast-check" it.effect("property: resolved mode always belongs to available modes", () => Effect.gen(function*(_) { const property = fc.property( fc.record({ claudeAvailable: fc.boolean(), codexAvailable: fc.boolean(), grokAvailable: fc.boolean() }).filter(avail => avail.claudeAvailable || avail.codexAvailable || avail.grokAvailable), (available) => { // Setup auth files based on available flags // Call resolveAutoAgentMode // Assert result ∈ availableAgentModes(available) } ) fc.assert(property) }) )As per coding guidelines
**/*.test.{ts,tsx}: "Implement property-based testing using fast-check for mathematical properties and invariants."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/lib/tests/usecases/agent-auto-select.test.ts` around lines 119 - 219, The new Grok unit tests lack property-based tests as required; add fast-check property tests in packages/lib/tests/usecases/agent-auto-select.test.ts that exercise resolveAutoAgentMode across randomized availability combinations: import fc from "fast-check" and add it.effect cases that generate boolean flags (claudeAvailable, codexAvailable, grokAvailable) filtered to at least one true, create auth files in the temp dir based on those flags (using FileSystem.FileSystem and Path.Path as in existing tests), call resolveAutoAgentMode(config) and assert the invariants: (1) if exactly one mode is available the result equals that mode, (2) result is one of the available modes, (3) when agentMode is explicitly set to an available mode result equals that explicit mode, and (4) when explicit mode is set but its auth is missing the effect fails with InvalidOption; use fc.assert to run the property and wrap inside the existing withTempDir/Effect.gen pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/docker-git/cli/usage.ts`:
- Line 79: The help text advertises Gemini but the auto-selection logic and
types lack Gemini support; update AvailableAgentAuth to include geminiAvailable,
extend availableAgentModes (in packages/lib/src/usecases/agent-auto-select.ts,
function availableAgentModes) to check available.geminiAvailable and include
AgentMode.Gemini in the returned modes when present, update the error message
that currently says "no Claude, Codex or Grok auth found" to mention Gemini, and
add/adjust unit tests to cover the Gemini path; alternatively, if you prefer to
postpone Gemini, remove "gemini" from the --auto help text and AgentMode enum
usages so the doc and logic remain consistent.
In `@packages/app/src/lib/usecases/agent-auto-select.ts`:
- Around line 137-141: Add comprehensive TSDoc to the pure CORE helper
availableAgentModes: mark it with `@pure` true, add functional comments describing
PURITY (CORE) and `@effect` (none/required services = none), specify `@invariant`
such as "∀available: |result| ≤ 3 ∧ result ⊆ {claude, codex, grok}", document
`@precondition` (none) and `@postcondition` (returns array of AgentMode containing
only enabled modes), and state `@complexity` as "time O(1), space O(1)". Place
this TSDoc immediately above the availableAgentModes declaration so tools and
reviewers can pick it up.
- Around line 143-153: Add comprehensive TSDoc to the pickRandomAutoAgentMode
function: document `@pure` false (uses process.hrtime.bigint()), `@effect`
describing the Effect<AgentMode, ParseError> and any required services,
`@invariant` stating the result ∈ availableAgentModes(available), `@precondition`
that availableAgentModes(available) is non-empty, `@postcondition` that the
returned AgentMode is one of the available modes or an error, and `@complexity`
O(n) where n = number of modes; reference the helper availableAgentModes and the
non-deterministic selection via process.hrtime.bigint() when describing WHY and
EFFECT.
- Around line 53-60: The new function hasGrokAuth lacks the required TSDoc; add
a comprehensive TSDoc block above hasGrokAuth that documents `@pure` false,
`@effect` FileSystem (since it uses FileSystem.FileSystem and returns an Effect),
`@precondition` (rootPath is a valid path string and label may be undefined),
`@postcondition` (returns true if valid Grok credentials are found at
normalizeAccountLabel(label ?? null, "default") within rootPath), `@complexity`
(time and space complexity of hasGrokCredentials call), and include the
functional comments PURITY (SHELL), EFFECT (Effect<boolean, PlatformError,
FileSystem>), and INVARIANT describing the relationship between normalized label
and lookup path; reference the helper functions normalizeAccountLabel and
hasGrokCredentials in the comment for clarity.
- Around line 24-26: The three constants claudeMode, codexMode and grokMode are
defined as one-element ReadonlyArray<AgentMode>, which is unnecessary because
availableAgentModes later spreads them; change them to use simple string
literals or single AgentMode values and insert those directly into
availableAgentModes (e.g., replace the one-item arrays with 'claude', 'codex',
'grok' or define each as const claudeMode: AgentMode = 'claude') to remove the
extra array layer and keep type-safety.
In `@packages/lib/tests/usecases/agent-auto-select.test.ts`:
- Around line 42-45: The test suite adds geminiAuthPath and geminiHome to
makeConfig but no Gemini test-cases exist; either add three tests mirroring
Grok's coverage (in packages/lib/tests/usecases/agent-auto-select.test.ts) named
it.effect("chooses Gemini when only Gemini auth exists", ...), it.effect("keeps
explicit Gemini mode when Gemini auth exists", ...), and it.effect("fails
explicit Gemini mode when Gemini auth is missing", ...) exercising the same
setup/teardowns and assertions used for Grok, or if Gemini is out of scope for
this PR, remove or comment out geminiAuthPath/geminiHome from makeConfig and add
a "// TODO: Gemini tests" comment to explain why they are omitted.
---
Outside diff comments:
In `@packages/lib/src/usecases/agent-auto-select.ts`:
- Around line 1-181: This file duplicates logic from packages/app; remove
duplication by centralizing the agent selection code into the shared lib and
have packages/app import it (or create a single shared module/workspace
reference) and, in this file, replace the duplicated implementation with an
import; while consolidating, add TSDoc and the repository's functional comment
blocks (CHANGE/WHY/PURITY/EFFECT/INVARIANT/COMPLEXITY) for the functions
hasGrokAuth, availableAgentModes, and pickRandomAutoAgentMode, and simplify the
single-element constants claudeMode, codexMode, grokMode to plain string
literals where used (or export simple string constants) to reduce unnecessary
arrays; update resolveAvailableAgentAuth, resolveExplicitAutoAgentMode, and
pickRandomAutoAgentMode call sites to use the centralized implementation and
ensure exports/signatures match between packages.
In `@packages/lib/tests/usecases/agent-auto-select.test.ts`:
- Around line 119-219: The new Grok unit tests lack property-based tests as
required; add fast-check property tests in
packages/lib/tests/usecases/agent-auto-select.test.ts that exercise
resolveAutoAgentMode across randomized availability combinations: import fc from
"fast-check" and add it.effect cases that generate boolean flags
(claudeAvailable, codexAvailable, grokAvailable) filtered to at least one true,
create auth files in the temp dir based on those flags (using
FileSystem.FileSystem and Path.Path as in existing tests), call
resolveAutoAgentMode(config) and assert the invariants: (1) if exactly one mode
is available the result equals that mode, (2) result is one of the available
modes, (3) when agentMode is explicitly set to an available mode result equals
that explicit mode, and (4) when explicit mode is set but its auth is missing
the effect fails with InvalidOption; use fc.assert to run the property and wrap
inside the existing withTempDir/Effect.gen pattern.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 24d7c545-cc31-4d9c-8519-8643b38d69a3
📒 Files selected for processing (4)
packages/app/src/docker-git/cli/usage.tspackages/app/src/lib/usecases/agent-auto-select.tspackages/lib/src/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Runtime volumes + SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/lib/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/src/usecases/agent-auto-select.tspackages/app/src/docker-git/cli/usage.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/app/src/lib/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/src/usecases/agent-auto-select.tspackages/app/src/docker-git/cli/usage.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/app/src/lib/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/src/usecases/agent-auto-select.tspackages/app/src/docker-git/cli/usage.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/app/src/lib/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/src/usecases/agent-auto-select.tspackages/app/src/docker-git/cli/usage.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/app/src/lib/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/src/usecases/agent-auto-select.tspackages/app/src/docker-git/cli/usage.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/src/lib/usecases/agent-auto-select.tspackages/lib/tests/usecases/agent-auto-select.test.tspackages/lib/src/usecases/agent-auto-select.tspackages/app/src/docker-git/cli/usage.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/usecases/agent-auto-select.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/usecases/agent-auto-select.test.ts
🔇 Additional comments (1)
packages/app/src/lib/usecases/agent-auto-select.ts (1)
129-133: LGTM!
| const claudeMode: ReadonlyArray<AgentMode> = ["claude"] | ||
| const codexMode: ReadonlyArray<AgentMode> = ["codex"] | ||
| const grokMode: ReadonlyArray<AgentMode> = ["grok"] |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Рассмотрите использование литералов вместо одноэлементных массивов.
Константы claudeMode, codexMode, grokMode определены как одноэлементные ReadonlyArray<AgentMode>. Это добавляет дополнительный уровень абстракции без очевидной пользы. В availableAgentModes их всё равно приходится распаковывать через spread.
Более прямолинейное решение — использовать string literals напрямую в массиве или, если массивы нужны для типобезопасности, добавить комментарий, объясняющий WHY.
♻️ Возможное упрощение
-const claudeMode: ReadonlyArray<AgentMode> = ["claude"]
-const codexMode: ReadonlyArray<AgentMode> = ["codex"]
-const grokMode: ReadonlyArray<AgentMode> = ["grok"]
-
const availableAgentModes = (available: AvailableAgentAuth): ReadonlyArray<AgentMode> => [
- ...(available.claudeAvailable ? claudeMode : []),
- ...(available.codexAvailable ? codexMode : []),
- ...(available.grokAvailable ? grokMode : [])
+ ...(available.claudeAvailable ? ["claude" as const] : []),
+ ...(available.codexAvailable ? ["codex" as const] : []),
+ ...(available.grokAvailable ? ["grok" as const] : [])
]🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 24 - 26, The
three constants claudeMode, codexMode and grokMode are defined as one-element
ReadonlyArray<AgentMode>, which is unnecessary because availableAgentModes later
spreads them; change them to use simple string literals or single AgentMode
values and insert those directly into availableAgentModes (e.g., replace the
one-item arrays with 'claude', 'codex', 'grok' or define each as const
claudeMode: AgentMode = 'claude') to remove the extra array layer and keep
type-safety.
| const hasGrokAuth = ( | ||
| fs: FileSystem.FileSystem, | ||
| rootPath: string, | ||
| label: string | undefined | ||
| ): Effect.Effect<boolean, PlatformError> => { | ||
| const normalized = normalizeAccountLabel(label ?? null, "default") | ||
| return hasGrokCredentials(fs, `${rootPath}/${normalized}`) | ||
| } |
There was a problem hiding this comment.
Отсутствует обязательная TSDoc-документация для новой функции.
Согласно coding guidelines, все функции должны содержать comprehensive TSDoc с указанием:
@pure(false, т.к. FileSystem effect)@effect(FileSystem dependency)@precondition(например, rootPath должен быть валидным путём)@postcondition(возвращает true если найдены валидные Grok credentials)@complexity(временная и пространственная)
Также требуются функциональные комментарии: PURITY (SHELL), EFFECT (Effect<boolean, PlatformError, FileSystem>), INVARIANT.
As per coding guidelines **/*.{ts,tsx}: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 53 - 60, The
new function hasGrokAuth lacks the required TSDoc; add a comprehensive TSDoc
block above hasGrokAuth that documents `@pure` false, `@effect` FileSystem (since it
uses FileSystem.FileSystem and returns an Effect), `@precondition` (rootPath is a
valid path string and label may be undefined), `@postcondition` (returns true if
valid Grok credentials are found at normalizeAccountLabel(label ?? null,
"default") within rootPath), `@complexity` (time and space complexity of
hasGrokCredentials call), and include the functional comments PURITY (SHELL),
EFFECT (Effect<boolean, PlatformError, FileSystem>), and INVARIANT describing
the relationship between normalized label and lookup path; reference the helper
functions normalizeAccountLabel and hasGrokCredentials in the comment for
clarity.
| const availableAgentModes = (available: AvailableAgentAuth): ReadonlyArray<AgentMode> => [ | ||
| ...(available.claudeAvailable ? claudeMode : []), | ||
| ...(available.codexAvailable ? codexMode : []), | ||
| ...(available.grokAvailable ? grokMode : []) | ||
| ] |
There was a problem hiding this comment.
Отсутствует обязательная TSDoc-документация.
Функция availableAgentModes является чистой (CORE layer) и должна содержать:
@puretrue@invariant(например: "∀available: |result| ≤ 3 ∧ result ⊆ {claude, codex, grok}")@complexityO(1) время, O(1) пространство (возвращает массив фиксированного размера ≤3)
Также требуются функциональные комментарии: PURITY (CORE), INVARIANT, COMPLEXITY.
As per coding guidelines **/*.{ts,tsx}: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 137 - 141,
Add comprehensive TSDoc to the pure CORE helper availableAgentModes: mark it
with `@pure` true, add functional comments describing PURITY (CORE) and `@effect`
(none/required services = none), specify `@invariant` such as "∀available:
|result| ≤ 3 ∧ result ⊆ {claude, codex, grok}", document `@precondition` (none)
and `@postcondition` (returns array of AgentMode containing only enabled modes),
and state `@complexity` as "time O(1), space O(1)". Place this TSDoc immediately
above the availableAgentModes declaration so tools and reviewers can pick it up.
| const pickRandomAutoAgentMode = (available: AvailableAgentAuth): Effect.Effect<AgentMode, ParseError> => { | ||
| const modes = availableAgentModes(available) | ||
| const firstMode = modes[0] | ||
| if (firstMode === undefined) { | ||
| return Effect.fail(autoOptionError("no Claude, Codex or Grok auth found")) | ||
| } | ||
| if (!available.claudeAvailable && available.codexAvailable) { | ||
| return Effect.succeed("codex") | ||
| if (modes.length === 1) { | ||
| return Effect.succeed(firstMode) | ||
| } | ||
| return Effect.sync(() => (process.hrtime.bigint() % 2n === 0n ? "claude" : "codex")) | ||
| return Effect.sync(() => modes[Number(process.hrtime.bigint() % BigInt(modes.length))] ?? firstMode) | ||
| } |
There was a problem hiding this comment.
Отсутствует обязательная TSDoc-документация для критической логики выбора.
Функция pickRandomAutoAgentMode реализует случайный выбор агента из доступных и требует полную документацию:
@purefalse (использует process.hrtime.bigint())@effectтребует описание побочного эффекта (non-deterministic random selection)@invariant(например: "result ∈ availableAgentModes(available)")@preconditionдолжны существовать доступные режимы для выбора@postconditionвозвращает один из доступных режимов или ошибку@complexityO(n) где n = количество доступных режимов
Функциональные комментарии должны включать:
- PURITY (SHELL)
- EFFECT (Effect<AgentMode, ParseError>)
- INVARIANT (результат принадлежит множеству доступных режимов)
- WHY (почему используется process.hrtime вместо Math.random - детерминизм тестирования?)
As per coding guidelines **/*.{ts,tsx}: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 143 - 153,
Add comprehensive TSDoc to the pickRandomAutoAgentMode function: document `@pure`
false (uses process.hrtime.bigint()), `@effect` describing the Effect<AgentMode,
ParseError> and any required services, `@invariant` stating the result ∈
availableAgentModes(available), `@precondition` that
availableAgentModes(available) is non-empty, `@postcondition` that the returned
AgentMode is one of the available modes or an error, and `@complexity` O(n) where
n = number of modes; reference the helper availableAgentModes and the
non-deterministic selection via process.hrtime.bigint() when describing WHY and
EFFECT.
| geminiAuthPath: path.join(root, ".orch/auth/gemini"), | ||
| geminiHome: "/home/dev/.gemini", | ||
| grokAuthPath: path.join(root, ".orch/auth/grok"), | ||
| grokHome: "/home/dev/.grok", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Поиск упоминаний Gemini в реализации (не только в тестах и usage)
rg -nP --type=ts -C2 'gemini|Gemini' --iglob '**/usecases/**' --iglob '!**/*.test.ts' --iglob '!**/usage.ts'Repository: ProverCoderAI/docker-git
Length of output: 50380
🏁 Script executed:
# Посмотрим содержимое тестового файла, чтобы увидеть тест-кейсы
head -100 packages/lib/tests/usecases/agent-auto-select.test.tsRepository: ProverCoderAI/docker-git
Length of output: 3865
🏁 Script executed:
# Получим полный список тест-кейсов (строки с it.effect)
rg -n "it\.effect" packages/lib/tests/usecases/agent-auto-select.test.tsRepository: ProverCoderAI/docker-git
Length of output: 873
🏁 Script executed:
# Проверим, есть ли вообще упоминание Gemini в тестовом файле
rg -i "gemini" packages/lib/tests/usecases/agent-auto-select.test.tsRepository: ProverCoderAI/docker-git
Length of output: 159
Добавьте тест-кейсы для Gemini агента или удалите неиспользуемые поля конфига.
В makeConfig добавлены geminiAuthPath и geminiHome, но в файле тестов отсутствуют тест-кейсы для Gemini. Grok имеет полное покрытие (3 теста: выбор агента, явный режим, ошибка), а Gemini не протестирован, несмотря на то, что полностью реализован в production-коде.
Выберите один из подходов:
-
Добавьте недостающие тест-кейсы для Gemini (аналогично Grok):
it.effect("chooses Gemini when only Gemini auth exists", ...)it.effect("keeps explicit Gemini mode when Gemini auth exists", ...)it.effect("fails explicit Gemini mode when Gemini auth is missing", ...)
-
Или добавьте комментарий
// TODO: Gemini testsи откомментируйте поля конфига, если Gemini не должен быть в scope этого PR.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/tests/usecases/agent-auto-select.test.ts` around lines 42 - 45,
The test suite adds geminiAuthPath and geminiHome to makeConfig but no Gemini
test-cases exist; either add three tests mirroring Grok's coverage (in
packages/lib/tests/usecases/agent-auto-select.test.ts) named it.effect("chooses
Gemini when only Gemini auth exists", ...), it.effect("keeps explicit Gemini
mode when Gemini auth exists", ...), and it.effect("fails explicit Gemini mode
when Gemini auth is missing", ...) exercising the same setup/teardowns and
assertions used for Grok, or if Gemini is out of scope for this PR, remove or
comment out geminiAuthPath/geminiHome from makeConfig and add a "// TODO: Gemini
tests" comment to explain why they are omitted.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 1-2: The file packages/app src lib core templates-entrypoint
grok.ts duplicates logic present in
packages/lib/src/core/templates-entrypoint/grok.ts; remove the duplicate by
extracting the shared code (including the TemplateConfig-related logic and any
exported helpers) into a single shared module or the lib package and have
packages/app re-export or import that module (e.g., export/import the same
symbols instead of re-defining them). Update the grok.ts in packages/app to
import TemplateConfig and any functions from the shared location (or re-export
from packages/lib) so only one source of truth remains and jscpd markers are no
longer needed.
- Around line 259-266: Экспортная функция renderEntrypointGrokConfig не имеет
TSDoc — добавьте подробный TSDoc над объявлением функции
renderEntrypointGrokConfig, описывающий назначение функции, параметры (config:
TemplateConfig) и возвращаемое значение (string), а также любые побочные эффекты
или примечания; используйте стиль и уровень детализации, согласованный с другими
файлами (например, packages/lib/src/core/templates-entrypoint/grok.ts), включая
пример использования при необходимости.
In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 258-265: Add a comprehensive TSDoc block to the exported function
renderEntrypointGrokConfig describing its purpose and behavior, and include the
required tags: `@pure`, `@effect` (describe side effects or "none"), `@invariant`,
`@precondition` (e.g., valid TemplateConfig), `@postcondition` (what string
structure is returned), and `@complexity` (time/space complexity). Place the
comment immediately above the renderEntrypointGrokConfig declaration and
reference the parameter config and returned string in the descriptions so that
consumers and linters get the full contract for this exported function.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8b8093ce-8bc9-43dd-9c7b-3c14a8b15010
📒 Files selected for processing (3)
packages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/core/templates.test.ts
🔇 Additional comments (6)
packages/lib/src/core/templates-entrypoint/grok.ts (4)
1-12: LGTM!Also applies to: 122-126, 144-164, 165-170, 172-188, 253-257
13-121: LGTM!
127-143: LGTM!
189-252: LGTM!packages/lib/tests/core/templates.test.ts (1)
30-30: LGTM!Also applies to: 216-224, 419-463, 484-496, 498-526
packages/app/src/lib/core/templates-entrypoint/grok.ts (1)
3-258: LGTM!
| /* jscpd:ignore-start */ | ||
| import type { TemplateConfig } from "../domain.js" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff
Дублирование кода между packages/lib и packages/app.
Файл полностью идентичен packages/lib/src/core/templates-entrypoint/grok.ts. Маркеры jscpd:ignore подавляют предупреждения, но любое исправление потребует синхронизации обоих файлов.
Рассмотрите возможность вынести общую логику в shared-пакет или re-export из lib, если архитектура это позволяет.
Also applies to: 267-267
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts` around lines 1 - 2,
The file packages/app src lib core templates-entrypoint grok.ts duplicates logic
present in packages/lib/src/core/templates-entrypoint/grok.ts; remove the
duplicate by extracting the shared code (including the TemplateConfig-related
logic and any exported helpers) into a single shared module or the lib package
and have packages/app re-export or import that module (e.g., export/import the
same symbols instead of re-defining them). Update the grok.ts in packages/app to
import TemplateConfig and any functions from the shared location (or re-export
from packages/lib) so only one source of truth remains and jscpd markers are no
longer needed.
Working session summaryГотово: PR 305 обновлён и готов к ревью: #305 Что добавлено поверх основной Grok-поддержки:
Проверки:
SOURCE: n/a This summary was automatically extracted from the AI working session output. |
|
Испраьв всё что написал rabbit coder |
🚨 Solution Draft FailedThe automated solution draft encountered an error: What you can do
Administrator-only CLI details, if any, are printed in the solver terminal log rather than in this GitHub comment. 🤖 Models used:
Click to expand failure log (33KB)Now working session is ended, feel free to review and add any feedback on the solution draft. |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/api/src/http.ts (1)
429-448: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winЗамените
switchнаMatchи удалите type assertionas ProjectSkillScopeв маппинге skill scope.Функции
skillScopeFromId(строки 429–448),skillScopeToId(строки 450–467) иskillScopeFromBody(строки 469–482) используютswitchи type assertion, которые запрещены по гайдлайнам. Замените на исчерпывающий разбор с помощьюMatch.exhaustive():Пример рефакторинга
-const skillScopeFromBody = (scope: string): ProjectSkillScope | null => { - switch (scope) { - case "skills": - case "agents/skills": - case "agents/.skills": - case "claude/skills": - case "codex/skills": - case "gemini/skills": - case "grok/skills": - return scope as ProjectSkillScope - default: - return null - } -} +const skillScopeFromBody = (scope: string): ProjectSkillScope | null => + Match.value(scope).pipe( + Match.when("skills", () => "skills"), + Match.when("agents/skills", () => "agents/skills"), + Match.when("agents/.skills", () => "agents/.skills"), + Match.when("claude/skills", () => "claude/skills"), + Match.when("codex/skills", () => "codex/skills"), + Match.when("gemini/skills", () => "gemini/skills"), + Match.when("grok/skills", () => "grok/skills"), + Match.orElse(() => null) + )Это применяется также к
skillScopeToId(строки 450–467) иskillScopeFromId(строки 429–448).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/src/http.ts` around lines 429 - 448, Replace the switch-based, asserted mappings in skillScopeFromId, skillScopeToId, and skillScopeFromBody with exhaustive pattern matches using Match.exhaustive(); specifically, remove any "as ProjectSkillScope" assertions, import and use Match (e.g. from ts-pattern) to match each possible string/enum case and return the correctly typed ProjectSkillScope or id string, and ensure the match is exhaustive so the default/null branch is handled by Match.exhaustive() instead of a fallback switch/default. Use the function names skillScopeFromId, skillScopeToId, and skillScopeFromBody as anchors when applying the refactor.
♻️ Duplicate comments (4)
packages/app/src/lib/usecases/auth-grok-helpers.ts (2)
54-65:⚠️ Potential issue | 🟠 Major | ⚡ Quick winЗакрепите версию
grok-devвместо@latest --force.Использование
grok-dev@latest --forceделает сборку Docker-образа недетерминированной: один коммит может проходить сегодня и падать завтра после выхода новой версии пакета. Для воспроизводимых сборок замените на конкретную версию без--force.🔧 Предлагаемое исправление
-RUN npm install -g grok-dev@latest --force +RUN npm install -g grok-dev@1.1.6🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/lib/usecases/auth-grok-helpers.ts` around lines 54 - 65, The Dockerfile generator renderGrokDockerfile currently installs grok-dev with "npm install -g grok-dev@latest --force", which makes builds nondeterministic; change that line in renderGrokDockerfile to pin a specific semantic version (e.g. grok-dev@X.Y.Z) and remove the "--force" flag so the image is reproducible and not forced to override versions. Update the string returned by renderGrokDockerfile to use the chosen fixed version token in place of "`@latest` --force".
204-218:⚠️ Potential issue | 🟠 Major | ⚡ Quick winОшибки fallback-удаления credentials директории подавляются.
Если
fs.removeи docker-fallback оба провалятся,Effect.asVoidпревратит ошибку в успех, и код продолжит работу поверх старого каталога. Новый логин может унаследовать артефакты предыдущей сессии.🔧 Предлагаемое исправление
const removeFallback = pipe( runCommandExitCode({ cwd, command: "docker", args: ["run", "--rm", "-v", `${accountPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"] }), - Effect.asVoid + Effect.asVoid, + Effect.mapError((err) => err) // propagate error instead of swallowing ) yield* _( fs.remove(credentialsDir, { recursive: true, force: true }).pipe( - Effect.orElse(() => removeFallback) + Effect.orElse(() => removeFallback), + Effect.orElse(() => Effect.void) // only swallow after both attempts ) )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/lib/usecases/auth-grok-helpers.ts` around lines 204 - 218, В текущем Effect.gen блоке удаление credentialsDir использует fs.remove(...).pipe(Effect.orElse(() => removeFallback)) и затем removeFallback обёрнут в Effect.asVoid, из-за чего ошибки обоих путей подавляются; исправьте так, чтобы при провале и fs.remove, и runCommandExitCode (removeFallback) ошибка пробрасывалась: уберите Effect.asVoid с removeFallback, вместо Effect.orElse используйте объединяющий обработчик (например, Effect.orElseFail/Effect.catchAll) который собирает/пробрасывает оригинальную ошибку или новый агрегированный Error и возвращает Effect.fail; сослаться на символы grokCredentialsPath, removeFallback, runCommandExitCode, fs.remove и Effect.asVoid при правке.packages/lib/src/usecases/auth-grok-helpers.ts (2)
203-218:⚠️ Potential issue | 🟠 Major | ⚡ Quick winОшибки fallback-удаления credentials директории подавляются.
Аналогичная проблема как в
packages/app: если оба способа удаления провалятся, ошибка будет подавлена.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 203 - 218, The fallback deletion in Effect.gen around grokCredentialsPath uses fs.remove(...).pipe(Effect.orElse(() => removeFallback)) which swallows errors if both fs.remove and removeFallback fail; update this to rethrow a composed/error from the failures instead of suppressing it: replace the Effect.orElse call so that on fs.remove failure you run removeFallback and if removeFallback also fails you propagate an error (e.g., using Effect.orElseFail or Effect.catchAll to map the second failure into a failing Effect) so the overall effect fails instead of being silently ignored; reference symbols: Effect.gen, grokCredentialsPath, removeFallback, runCommandExitCode, fs.remove.
53-64:⚠️ Potential issue | 🟠 Major | ⚡ Quick winЗакрепите версию
grok-devвместо@latest --force.Аналогичная проблема как в
packages/app: использованиеgrok-dev@latest --forceделает сборку недетерминированной.🔧 Предлагаемое исправление
-RUN npm install -g grok-dev@latest --force +RUN npm install -g grok-dev@1.1.6🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 53 - 64, The Dockerfile generator renderGrokDockerfile currently installs grok-dev using an undetermined tag ("grok-dev@latest --force"), making builds non-deterministic; change the npm install line inside renderGrokDockerfile to pin a specific released version (e.g. "grok-dev@<MAJOR.MINOR.PATCH>") and remove the --force flag so the image is reproducible and predictable, then update any docs/tests that expect the previous behavior to use the pinned version.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 239-259: The oauth marker /"oauth"\s*:/u is too permissive and
flags an oauth block even when empty; update the
grokUserSettingsCredentialMarkers array (used by hasGrokUserSettingsCredentials)
to replace the current oauth regex with a stricter pattern that requires a
non-empty credential inside the oauth object (e.g. require a string-valued key
like "token", "accessToken", "apiKey" or "access_token" with a non-empty value),
so the detector only returns true when an actual secret is present.
In `@packages/lib/tests/core/templates.test.ts`:
- Around line 218-226: Тест "installs Grok CLI for generated project containers"
asserts the Dockerfile contains the hardcoded string "npm install -g
grok-dev@latest --force", which is brittle once the version is pinned; update
the test in packages/lib/tests/core/templates.test.ts to assert on a less
fragile pattern by checking for "npm install -g grok-dev" (or a regex like "npm
install -g grok-dev(@|@\\d+)") instead of the exact "`@latest` --force" token,
locating the assertion in the spec that calls
renderDockerfile(makeTemplateConfig()) and adjusts the
expectContainsAll/expect(...) checks accordingly.
In `@packages/lib/tests/usecases/auth-grok.test.ts`:
- Around line 56-106: Add a negative test that verifies authGrokLogin rejects
empty and whitespace-only API keys: create a new it.effect in the same test
suite (use withTempDir and withPatchedEnv like the existing test) and call
authGrokLogin with "" and with " " (space-only) providing FileSystem and Path
via Effect.provideService; assert the Effect fails (typed-failure) rather than
succeeds by inspecting the Effect exit/error (e.g., run/exit or expecting a
failure/error type/message) and ensure the failure matches the login validation
invariant for empty API keys rather than writing files; reference authGrokLogin,
withTempDir, withPatchedEnv, FileSystem.FileSystem and Path.Path to locate where
to add the checks.
- Around line 107-143: Add fast-check property-based tests to auth-grok.test.ts
that generate many JSON payloads and assert the invariants for
hasGrokCredentials: use fc.property to produce (1) valid JSON objects that
always include an "apiKey" string and verify hasGrokCredentials(fs, accountPath)
returns true, and (2) valid JSON objects that explicitly do NOT include "apiKey"
but match bootstrap-like shapes (e.g., may include "sandboxMode" or
"confirmBeforeToolUse") and verify hasGrokCredentials(...) returns false; reuse
the existing withTempDir, FileSystem.FileSystem and Path.Path setup, write the
generated JSON to path.join(credentialsDir, "user-settings.json"), and call
fc.assert with reasonable limits to integrate into the test suite.
---
Outside diff comments:
In `@packages/api/src/http.ts`:
- Around line 429-448: Replace the switch-based, asserted mappings in
skillScopeFromId, skillScopeToId, and skillScopeFromBody with exhaustive pattern
matches using Match.exhaustive(); specifically, remove any "as
ProjectSkillScope" assertions, import and use Match (e.g. from ts-pattern) to
match each possible string/enum case and return the correctly typed
ProjectSkillScope or id string, and ensure the match is exhaustive so the
default/null branch is handled by Match.exhaustive() instead of a fallback
switch/default. Use the function names skillScopeFromId, skillScopeToId, and
skillScopeFromBody as anchors when applying the refactor.
---
Duplicate comments:
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 54-65: The Dockerfile generator renderGrokDockerfile currently
installs grok-dev with "npm install -g grok-dev@latest --force", which makes
builds nondeterministic; change that line in renderGrokDockerfile to pin a
specific semantic version (e.g. grok-dev@X.Y.Z) and remove the "--force" flag so
the image is reproducible and not forced to override versions. Update the string
returned by renderGrokDockerfile to use the chosen fixed version token in place
of "`@latest` --force".
- Around line 204-218: В текущем Effect.gen блоке удаление credentialsDir
использует fs.remove(...).pipe(Effect.orElse(() => removeFallback)) и затем
removeFallback обёрнут в Effect.asVoid, из-за чего ошибки обоих путей
подавляются; исправьте так, чтобы при провале и fs.remove, и runCommandExitCode
(removeFallback) ошибка пробрасывалась: уберите Effect.asVoid с removeFallback,
вместо Effect.orElse используйте объединяющий обработчик (например,
Effect.orElseFail/Effect.catchAll) который собирает/пробрасывает оригинальную
ошибку или новый агрегированный Error и возвращает Effect.fail; сослаться на
символы grokCredentialsPath, removeFallback, runCommandExitCode, fs.remove и
Effect.asVoid при правке.
In `@packages/lib/src/usecases/auth-grok-helpers.ts`:
- Around line 203-218: The fallback deletion in Effect.gen around
grokCredentialsPath uses fs.remove(...).pipe(Effect.orElse(() =>
removeFallback)) which swallows errors if both fs.remove and removeFallback
fail; update this to rethrow a composed/error from the failures instead of
suppressing it: replace the Effect.orElse call so that on fs.remove failure you
run removeFallback and if removeFallback also fails you propagate an error
(e.g., using Effect.orElseFail or Effect.catchAll to map the second failure into
a failing Effect) so the overall effect fails instead of being silently ignored;
reference symbols: Effect.gen, grokCredentialsPath, removeFallback,
runCommandExitCode, fs.remove.
- Around line 53-64: The Dockerfile generator renderGrokDockerfile currently
installs grok-dev using an undetermined tag ("grok-dev@latest --force"), making
builds non-deterministic; change the npm install line inside
renderGrokDockerfile to pin a specific released version (e.g.
"grok-dev@<MAJOR.MINOR.PATCH>") and remove the --force flag so the image is
reproducible and predictable, then update any docs/tests that expect the
previous behavior to use the pinned version.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c443bed7-adae-4577-8a81-848ac4778a6a
📒 Files selected for processing (19)
packages/api/src/api/schema.tspackages/api/src/auth-terminal-runner.tspackages/api/src/http.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/app/src/web/api-auth-schema.tspackages/app/src/web/api.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/web/api.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/auth-terminal-runner.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/usecases/auth-grok.test.tspackages/api/src/http.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/web/api-auth-schema.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/app/src/web/api.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/auth-terminal-runner.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/usecases/auth-grok.test.tspackages/api/src/http.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/web/api-auth-schema.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/app/src/web/api.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/auth-terminal-runner.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/usecases/auth-grok.test.tspackages/api/src/http.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/web/api-auth-schema.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/app/src/web/api.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/auth-terminal-runner.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/usecases/auth-grok.test.tspackages/api/src/http.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/web/api-auth-schema.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/app/src/web/api.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/auth-terminal-runner.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/usecases/auth-grok.test.tspackages/api/src/http.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/web/api-auth-schema.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/src/web/api.tspackages/api/src/services/auth-terminal-sessions.tspackages/api/src/auth-terminal-runner.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/usecases/auth-grok.test.tspackages/api/src/http.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/web/api-auth-schema.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.ts
🔇 Additional comments (26)
packages/app/src/lib/core/templates-entrypoint/grok.ts (1)
1-279: LGTM!packages/app/src/lib/core/templates/dockerfile.ts (1)
91-91: LGTM!Also applies to: 121-123, 363-364
packages/lib/src/core/templates/dockerfile.ts (1)
91-91: LGTM!Also applies to: 121-123, 363-364
packages/app/src/lib/usecases/auth-grok-oauth.ts (3)
38-44: Env-переменныеNO_BROWSERиGROK_NO_BROWSERне документированы в Grok CLI.Согласно официальной документации, Grok CLI не поддерживает эти переменные окружения для отключения автоматического открытия браузера. Браузер будет открываться при выполнении
grok login, что может противоречить ожидаемому поведению URL handoff.Проверьте актуальную документацию grok-dev или используйте альтернативный подход (CLI флаг
--no-browser, если существует).Does grok-dev npm package CLI support NO_BROWSER or --no-browser flag for OAuth login?
79-108: Скрипт исправления прав теперь использует безопасные разрешения.Предыдущая проблема с
chmod 777исправлена: теперь используетсяchown -R 1000:1000,chmod 700для директорий иchmod 600для файлов.
1-37: LGTM!Also applies to: 45-78, 109-137
packages/lib/src/usecases/auth-grok-oauth.ts (2)
38-44: Env-переменныеNO_BROWSERиGROK_NO_BROWSERне документированы.Аналогичная проблема как в
packages/app: эти переменные окружения не задокументированы в Grok CLI.
1-37: LGTM!Also applies to: 45-137
packages/app/src/lib/usecases/auth-grok-helpers.ts (1)
1-52: LGTM!Also applies to: 66-115, 139-197, 224-272
packages/app/src/lib/usecases/auth-grok.ts (1)
1-95: LGTM!packages/lib/src/usecases/auth-grok-helpers.ts (1)
1-52: LGTM!Also applies to: 65-202, 219-270
packages/lib/src/usecases/auth-grok.ts (1)
1-95: LGTM!packages/lib/tests/core/templates.test.ts (1)
30-30: LGTM!Also applies to: 421-465, 486-498, 500-528
packages/app/src/web/api.ts (1)
184-195: LGTM!packages/lib/src/core/templates-entrypoint/grok.ts (6)
13-25: LGTM!
27-121: LGTM!
122-143: LGTM!
144-188: LGTM!
189-257: LGTM!
258-278: LGTM!packages/api/src/api/schema.ts (1)
35-36: LGTM!Also applies to: 63-65, 68-68, 112-114, 122-122, 134-135, 250-250
packages/api/src/http.ts (1)
182-185: LGTM!packages/api/src/services/auth-terminal-sessions.ts (1)
3-3: LGTM!Also applies to: 72-77
packages/api/src/auth-terminal-runner.ts (1)
2-2: LGTM!Also applies to: 5-13, 37-43
packages/api/src/services/project-auth.ts (1)
20-20: LGTM!Also applies to: 30-30, 175-176, 185-185, 188-188, 191-191, 224-224, 261-280, 348-349, 351-351, 358-358, 363-363, 367-368, 384-385, 461-475
packages/app/src/web/api-auth-schema.ts (1)
26-39: LGTM!Also applies to: 52-56
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 176-185: The OAuth regex in grokUserSettingsCredentialMarkers uses
[^}]* which fails on nested objects; update the OAuth marker (or the detection
strategy in hasGrokUserSettingsCredentials) to handle nested content by
replacing the [^}]* with a non-greedy dot-all style pattern (e.g., [\s\S]*? )
or, better, parse the content as JSON and look up oauth keys
(apiKey|accessToken|access_token|authToken|refreshToken|refresh_token|token)
programmatically; adjust the grokUserSettingsCredentialMarkers array or the
detection flow to use the new pattern or JSON-based check so nested objects like
{"oauth":{"meta":{},"accessToken":"x"}} are correctly detected.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 00b8b0ca-9dbb-42f1-98d9-bcda8b88b0e0
📒 Files selected for processing (10)
packages/api/src/http.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/lib/src/core/templates/dockerfile.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/api/src/http.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/lib/src/core/templates/dockerfile.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/api/src/http.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/lib/src/core/templates/dockerfile.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/api/src/http.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/lib/src/core/templates/dockerfile.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/api/src/http.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/lib/src/core/templates/dockerfile.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/api/src/http.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/lib/src/core/templates/dockerfile.tspackages/app/src/lib/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/api/src/http.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/usecases/auth-grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
🔇 Additional comments (36)
packages/lib/src/core/templates/dockerfile.ts (2)
91-91: LGTM!Also applies to: 121-123
363-364: LGTM!packages/app/src/lib/core/templates/dockerfile.ts (1)
91-91: LGTM!Also applies to: 121-123, 363-364
packages/lib/tests/core/templates.test.ts (3)
30-30: LGTM!Also applies to: 217-228
423-467: LGTM!
488-500: LGTM!Also applies to: 502-529
packages/api/src/http.ts (2)
1-1: LGTM!Also applies to: 184-184
429-465: LGTM!packages/lib/tests/usecases/auth-grok.test.ts (3)
11-72: LGTM!
74-166: LGTM!
168-285: LGTM!packages/app/src/lib/usecases/auth-grok.ts (2)
30-52: LGTM!
54-66: LGTM!Also applies to: 73-98
packages/lib/src/usecases/auth-grok.ts (2)
30-52: LGTM!
54-66: LGTM!Also applies to: 73-98
packages/api/src/services/project-auth.ts (5)
20-20: LGTM!Also applies to: 30-30
173-197: LGTM!Also applies to: 224-224
239-280: LGTM!
348-368: LGTM!
384-385: LGTM!Also applies to: 461-475
packages/lib/src/usecases/auth-grok-helpers.ts (8)
158-184: 💤 Low valueRegex-паттерн для OAuth может не сработать при вложенных JSON-объектах.
Аналогично
packages/appверсии: паттерн[^}]*на линии 180 не обрабатывает вложенные объекты внутриoauth.
1-16: LGTM!
17-43: LGTM!
44-65: LGTM!
67-115: LGTM!
117-156: LGTM!
186-227: LGTM!
229-275: LGTM!packages/app/src/lib/usecases/auth-grok-helpers.ts (8)
1-16: LGTM!
17-43: LGTM!
68-116: LGTM!
118-157: LGTM!
187-198: LGTM!
200-228: LGTM!
230-277: LGTM!
55-66: Версияgrok-dev@1.1.7существует и корректна.Пакет опубликован 15 мая 2026 года и является актуальной стабильной версией. Использование точной версии вместо
@latestсоответствует требованиям к воспроизводимости.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 261-280: The current hasGrokAccountCredentials only checks for the
presence of `${accountPath}/.api-key` via hasFileAtPath and treats an empty file
as valid; change it to read and validate the file contents and only
succeed(true) when the trimmed contents are non-empty (consistent with
readGrokApiKey behavior). Concretely, inside hasGrokAccountCredentials replace
the hasFileAtPath branch with a readFile (or existing read helper) for
`${accountPath}/.api-key`, check that the result is a non-empty string after
trimming, return Effect.succeed(true) only then, and otherwise fall back to
hasApiKeyInEnvFile and hasGrokUserSettingsCredentials (or return false) to
preserve the existing flow.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: fcf63705-5ecd-4438-99da-0c5d52b8681f
📒 Files selected for processing (4)
packages/api/src/services/project-auth.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: Test
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok-helpers.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/usecases/auth-grok.test.ts
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
packages/api/src/services/project-auth.ts (1)
253-259:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftДетектор
oauthвсё ещё может дать ложноположительный match.
[\s\S]*?после"oauth": {не ограничен границей объекта, поэтому regex спокойно перескакивает через}и подцепляет любой следующий"token": "..."ниже по файлу. В таком случае пустойoauth-блок будет засчитан как валидные Grok credentials, иProjectGrokConnectсможет вернуть ложный success. Здесь нужен разбор JSON/точная проверка только внутриoauth, а не поиск по сырому тексту.#!/bin/bash python - <<'PY' import re pattern = re.compile( r'"oauth"\s*:\s*\{[\s\S]*?"(?:apiKey|accessToken|access_token|authToken|refreshToken|refresh_token|token)"\s*:\s*"[^"]+"' ) sample = '{"oauth": {}, "telemetry": {"token": "abc"}}' print("matches =", bool(pattern.search(sample))) PY🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/src/services/project-auth.ts` around lines 253 - 259, The current grokUserSettingsCredentialMarkers regex (used by ProjectGrokConnect) can false-positive because the `"oauth"\s*:\s*\{[\s\S]*?` pattern is not confined to the oauth object; change the detection to parse the user settings string as JSON when possible and then explicitly inspect the oauth object for keys like apiKey, accessToken, access_token, authToken, refreshToken, refresh_token, token (i.e., add a JSON-parse branch that checks typeof parsed.oauth === 'object' and checks those properties), and only fall back to a conservative regex if parsing fails—update references to grokUserSettingsCredentialMarkers and the ProjectGrokConnect credential detection logic accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 481-484: The error text narrows remediation to only the CLI flow;
update the failure message in the Effect.fail call that uses missingSecret(...)
(invoked when matched === null) so it refers to neutral "Grok credentials" or
explicitly mentions both supported methods (".api-key file or GROK_API_KEY env")
instead of "Grok CLI login"; locate the call site where
hasGrokAccountCredentials() and missingSecret(...) are used (the Effect.flatMap
branch that currently calls upsertEnvKey(projectEnvText, projectGrokLabelKey,
normalizedLabel)) and replace the literal `"Grok CLI login"` with the
neutral/expanded text to cover both CLI and API-key login flows.
In `@packages/api/tests/project-auth.test.ts`:
- Around line 77-133: Add a fast-check property-based test around the existing
scenario: generate arbitrary strings (e.g., fc.string and fc.stringOf with
whitespace chars) and for each generated apiKey call the same setup/flow used in
the test (use withTempDir, buildProjectDetails, create grokDefaultAuth and write
the generated apiKey to ".api-key", then import the service and call
service.runProjectAuthFlow with flow "ProjectGrokConnect" and label "default").
Assert the invariant: if apiKey.trim().length === 0 then the result flips to an
ApiBadRequestError and envProjectPath does not contain
"GROK_AUTH_LABEL=default"; if apiKey.trim().length > 0 then the flow succeeds,
snapshot.activeGrokLabel === "default" and envProjectPath contains
"GROK_AUTH_LABEL=default". Use fc.property(...) and appropriate preconditions to
cover whitespace-only and non-empty cases.
In `@scripts/e2e/browser-command.sh`:
- Around line 24-25: The export lines for DOCKER_GIT_API_PORT and
DOCKER_GIT_WEB_PORT are hiding dg_pick_free_port failures; change to first
assign the result of dg_pick_free_port to a local variable (e.g.
api_port="$(dg_pick_free_port 34000 34999)"), test the command exit status and
that the value is non-empty, exit with a clear error message on failure, and
only then export DOCKER_GIT_API_PORT="$api_port" (repeat similarly for
dg_pick_free_port 41000 41999 -> DOCKER_GIT_WEB_PORT); reference the symbols
DOCKER_GIT_API_PORT, DOCKER_GIT_WEB_PORT and dg_pick_free_port when locating the
changes.
In `@scripts/e2e/opencode-autoconnect.sh`:
- Line 27: The current combined export masks failures from dg_pick_free_port;
change to first capture the value with DOCKER_GIT_API_PORT="$(dg_pick_free_port
34000 34999)", then immediately check the command’s success and result (e.g. if
[ $? -ne 0 ] || [ -z "$DOCKER_GIT_API_PORT" ]; then printf 'Failed to pick free
port\n' >&2; exit 1; fi), and only then run export DOCKER_GIT_API_PORT so
dg_pick_free_port errors are detected and handled properly.
---
Duplicate comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 253-259: The current grokUserSettingsCredentialMarkers regex (used
by ProjectGrokConnect) can false-positive because the `"oauth"\s*:\s*\{[\s\S]*?`
pattern is not confined to the oauth object; change the detection to parse the
user settings string as JSON when possible and then explicitly inspect the oauth
object for keys like apiKey, accessToken, access_token, authToken, refreshToken,
refresh_token, token (i.e., add a JSON-parse branch that checks typeof
parsed.oauth === 'object' and checks those properties), and only fall back to a
conservative regex if parsing fails—update references to
grokUserSettingsCredentialMarkers and the ProjectGrokConnect credential
detection logic accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c713abf2-9770-478c-97b4-b40b5ea2005b
📒 Files selected for processing (9)
packages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tsscripts/e2e/_lib.shscripts/e2e/browser-command.shscripts/e2e/clone-auto-open-ssh.shscripts/e2e/clone-cache.shscripts/e2e/login-context.shscripts/e2e/opencode-autoconnect.shscripts/e2e/runtime-volumes-ssh.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
scripts/e2e/browser-command.shscripts/e2e/clone-cache.shscripts/e2e/_lib.shscripts/e2e/login-context.shscripts/e2e/clone-auto-open-ssh.shscripts/e2e/runtime-volumes-ssh.shscripts/e2e/opencode-autoconnect.shpackages/api/tests/project-auth.test.tspackages/api/src/services/project-auth.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
scripts/e2e/browser-command.shscripts/e2e/clone-cache.shscripts/e2e/_lib.shscripts/e2e/login-context.shscripts/e2e/clone-auto-open-ssh.shscripts/e2e/runtime-volumes-ssh.shscripts/e2e/opencode-autoconnect.shpackages/api/tests/project-auth.test.tspackages/api/src/services/project-auth.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
scripts/e2e/browser-command.shscripts/e2e/clone-cache.shscripts/e2e/_lib.shscripts/e2e/login-context.shscripts/e2e/clone-auto-open-ssh.shscripts/e2e/runtime-volumes-ssh.shscripts/e2e/opencode-autoconnect.shpackages/api/tests/project-auth.test.tspackages/api/src/services/project-auth.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
scripts/e2e/browser-command.shscripts/e2e/clone-cache.shscripts/e2e/_lib.shscripts/e2e/login-context.shscripts/e2e/clone-auto-open-ssh.shscripts/e2e/runtime-volumes-ssh.shscripts/e2e/opencode-autoconnect.shpackages/api/tests/project-auth.test.tspackages/api/src/services/project-auth.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/api/tests/project-auth.test.tspackages/api/src/services/project-auth.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/api/tests/project-auth.test.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/api/tests/project-auth.test.tspackages/api/src/services/project-auth.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/api/tests/project-auth.test.ts
🪛 Shellcheck (0.11.0)
scripts/e2e/browser-command.sh
[warning] 24-24: Declare and assign separately to avoid masking return values.
(SC2155)
[warning] 25-25: Declare and assign separately to avoid masking return values.
(SC2155)
scripts/e2e/opencode-autoconnect.sh
[warning] 27-27: Declare and assign separately to avoid masking return values.
(SC2155)
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (4)
packages/app/src/lib/usecases/auth-grok-oauth.ts (1)
38-43:⚠️ Potential issue | 🟠 Major | ⚡ Quick winПроверьте, что
NO_BROWSER/GROK_NO_BROWSERреально поддерживаются текущим Grok CLI.На Line 40–41 используются env-переменные, которые могут быть недокументированы для нужной версии CLI; если они игнорируются, flow “paste callback URL” может работать не так, как ожидается.
Для официального Grok CLI (x.ai installer, версия 0.1.211) поддерживаются ли переменные окружения NO_BROWSER или GROK_NO_BROWSER для отключения авто-открытия браузера в `grok login`? Если нет, какой документированный флаг/механизм используется вместо этого?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/lib/usecases/auth-grok-oauth.ts` around lines 38 - 43, The env array in usecases/auth-grok-oauth.ts currently sets NO_BROWSER and GROK_NO_BROWSER which may not be supported by the Grok CLI; verify whether the official Grok CLI for your target version supports those env vars and, if not, switch to the documented mechanism (e.g., the CLI flag such as --no-browser or the official login flow flag) when invoking the Grok process in the code that builds the child process command, and add a fallback: detect CLI version/output and if env vars are ignored, pass the documented flag or drive the “paste callback URL” flow programmatically (capture stdout/stderr and feed stdin) so the auth flow behaves deterministically.packages/api/tests/project-auth.test.ts (1)
77-168:⚠️ Potential issue | 🟠 Major | ⚡ Quick winДобавьте property-based проверку инварианта для Grok API key.
На Line 77–168 сейчас покрыты только несколько примерных входов; инвариант
trim(apiKey).length === 0/> 0лучше зафиксировать черезfc.property, иначе остаётся неполное покрытие граничных случаев.As per coding guidelines, "
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/tests/project-auth.test.ts` around lines 77 - 168, Add a property-based test around the Grok API key trimming invariant: use fast-check's fc.property to generate diverse apiKey strings (including whitespace-only and non-empty-with-whitespace cases), write them to path.join(grokDefaultAuth, ".api-key") via fs.writeFileString, then call service.runProjectAuthFlow(project, { flow: "ProjectGrokConnect", label: "default" }) and assert the invariant—if trimmed apiKey length === 0 expect an ApiBadRequestError and that fs.readFileString(envProjectPath) does not contain "GROK_AUTH_LABEL=default", otherwise expect success (snapshot.activeGrokLabel === "default" and env contains the label); place this alongside or replacing the current example cases in the it.effect test and reuse withTempDir, withProjectsRoot, fs, path, and service helpers shown in the diff.packages/lib/src/usecases/auth-grok-oauth.ts (1)
38-43:⚠️ Potential issue | 🟠 Major | ⚡ Quick winСинхронизируйте с документированным способом headless OAuth для Grok CLI.
На Line 40–41 используются потенциально неподдерживаемые env-переменные; для shared-слоя лучше закрепить только официально подтверждённый механизм, иначе поведение будет зависеть от версии CLI.
Какие официальные параметры (env или CLI flags) у Grok CLI управляют browser auto-open в `grok login` в версиях, устанавливаемых через https://x.ai/cli/install.sh?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/lib/src/usecases/auth-grok-oauth.ts` around lines 38 - 43, The env array in usecases/auth-grok-oauth.ts currently sets unverified variables ("NO_BROWSER" and "GROK_NO_BROWSER") which may not be supported by the Grok CLI; remove these unsupported entries and replace them with the officially documented headless-login mechanism (either the documented environment variable or CLI flag) used by the Grok installer builds. Locate the env array in the auth-grok-oauth module (where env: [...] is defined) and update it to only include the officially supported key/value or add the documented CLI flag to the grok login invocation after consulting the Grok CLI docs/installer (https://x.ai/cli/install.sh) so the code uses the canonical headless option rather than fragile, unofficial variables.packages/api/src/services/project-auth.ts (1)
509-512:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winТекст ошибки не отражает все поддерживаемые способы авторизации.
hasGrokAccountCredentials()проверяет как.api-key, так иGROK_API_KEYиз.env, но при отсутствии credentials ошибка возвращает только"Grok CLI login". Это может направить пользователя на неверную remediation-ветку, хотя по ТЗ API-key login также first-class.💡 Предлагаемое исправление
- ? Effect.fail(missingSecret("Grok CLI login", normalizedLabel, grokAuthRoot)) + ? Effect.fail(missingSecret("Grok credentials", normalizedLabel, grokAuthRoot))As per coding guidelines, "Сверь изменения с исходным ТЗ/спекой ... флагай любой уход от спеки".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/api/src/services/project-auth.ts` around lines 509 - 512, The error message passed to missingSecret currently says "Grok CLI login" but hasGrokAccountCredentials() actually checks both the CLI login and API-key (e.g., .api-key file or GROK_API_KEY), so update the failure message in the Effect.flatMap branch (where missingSecret is called with "Grok CLI login", normalizedLabel, grokAuthRoot) to mention both supported auth methods (for example "Grok CLI login or API key") so users are routed to the correct remediation path; keep the rest of the upsertEnvKey call (projectEnvText, projectGrokLabelKey, normalizedLabel) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-status.ts`:
- Around line 25-29: The current branching on authMethod using an if/else is
non-exhaustive; replace it with an exhaustive pattern match via
Match.match(authMethod).exhaustive() (or authMethod.Match.exhaustive() according
to your Effect API) so every union case is handled; inside each branch emit the
appropriate Effect.log (e.g., the "none" case logs "Grok not connected" and
other cases log "Grok connected" with accountLabel and authMethod) and remove
the ad-hoc if/return to satisfy the union-exhaustiveness rule.
In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 124-136: The current successive if blocks using
grokDeploymentKeyDefaultExpansion, grokApiKeyDefaultExpansion, and
xaiApiKeyDefaultExpansion overwrite each other so the final exported key ends up
being the last non-empty check (XAI); choose a clear behavior and implement it:
either (A) enforce a documented priority by turning the three independent ifs
into an ordered if/elif chain that sets GROK_API_KEY, GROK_DEPLOYMENT_KEY, and
XAI_API_KEY only from the highest-priority non-empty expansion, or (B) resolve a
single shared value (e.g., resolvedKey = first non-empty of
grokDeploymentKeyDefaultExpansion, grokApiKeyDefaultExpansion,
xaiApiKeyDefaultExpansion or the file-derived value) and export GROK_API_KEY,
GROK_DEPLOYMENT_KEY, and XAI_API_KEY all to that resolved value; update the
block around
grokDeploymentKeyDefaultExpansion/grokApiKeyDefaultExpansion/xaiApiKeyDefaultExpansion
accordingly and add a short comment describing the chosen priority/behavior.
In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 125-133: The Dockerfile currently downloads and executes the
remote installer referenced by grokCliInstallScriptUrl into /tmp/grok-install.sh
without integrity checks; change the RUN step to first download the script to
/tmp/grok-install.sh, compute its SHA256 (e.g., sha256sum /tmp/grok-install.sh),
compare that checksum against a pinned value injected by the template (add a
GROK_INSTALL_SHA256 or similar template variable), and exit non‑zero if it
doesn't match; only after successful verification, run
HOME=/tmp/grok-install-home GROK_BIN_DIR=/usr/local/bin bash
/tmp/grok-install.sh ${grokCliVersion} and proceed with the existing install/mv
cleanup steps.
In `@packages/lib/src/usecases/auth-grok-status.ts`:
- Around line 25-29: Replace the partial if-check on authMethod with an
exhaustive pattern match using Match.exhaustive() (or .exhaustive()) so all
possible authMethod union cases are handled; specifically, change the logic
around the `authMethod` variable in the `auth-grok-status` flow to use
Match.exhaustive(authMethod) and produce the appropriate Effect.log messages
(e.g., for "none" log "Grok not connected (accountLabel)" and for other cases
log "Grok connected (accountLabel, authMethod)"), and ensure any new authMethod
variants get explicit branches rather than falling through.
---
Duplicate comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 509-512: The error message passed to missingSecret currently says
"Grok CLI login" but hasGrokAccountCredentials() actually checks both the CLI
login and API-key (e.g., .api-key file or GROK_API_KEY), so update the failure
message in the Effect.flatMap branch (where missingSecret is called with "Grok
CLI login", normalizedLabel, grokAuthRoot) to mention both supported auth
methods (for example "Grok CLI login or API key") so users are routed to the
correct remediation path; keep the rest of the upsertEnvKey call
(projectEnvText, projectGrokLabelKey, normalizedLabel) unchanged.
In `@packages/api/tests/project-auth.test.ts`:
- Around line 77-168: Add a property-based test around the Grok API key trimming
invariant: use fast-check's fc.property to generate diverse apiKey strings
(including whitespace-only and non-empty-with-whitespace cases), write them to
path.join(grokDefaultAuth, ".api-key") via fs.writeFileString, then call
service.runProjectAuthFlow(project, { flow: "ProjectGrokConnect", label:
"default" }) and assert the invariant—if trimmed apiKey length === 0 expect an
ApiBadRequestError and that fs.readFileString(envProjectPath) does not contain
"GROK_AUTH_LABEL=default", otherwise expect success (snapshot.activeGrokLabel
=== "default" and env contains the label); place this alongside or replacing the
current example cases in the it.effect test and reuse withTempDir,
withProjectsRoot, fs, path, and service helpers shown in the diff.
In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 38-43: The env array in usecases/auth-grok-oauth.ts currently sets
NO_BROWSER and GROK_NO_BROWSER which may not be supported by the Grok CLI;
verify whether the official Grok CLI for your target version supports those env
vars and, if not, switch to the documented mechanism (e.g., the CLI flag such as
--no-browser or the official login flow flag) when invoking the Grok process in
the code that builds the child process command, and add a fallback: detect CLI
version/output and if env vars are ignored, pass the documented flag or drive
the “paste callback URL” flow programmatically (capture stdout/stderr and feed
stdin) so the auth flow behaves deterministically.
In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 38-43: The env array in usecases/auth-grok-oauth.ts currently sets
unverified variables ("NO_BROWSER" and "GROK_NO_BROWSER") which may not be
supported by the Grok CLI; remove these unsupported entries and replace them
with the officially documented headless-login mechanism (either the documented
environment variable or CLI flag) used by the Grok installer builds. Locate the
env array in the auth-grok-oauth module (where env: [...] is defined) and update
it to only include the officially supported key/value or add the documented CLI
flag to the grok login invocation after consulting the Grok CLI docs/installer
(https://x.ai/cli/install.sh) so the code uses the canonical headless option
rather than fragile, unofficial variables.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 40722653-ddf0-453a-aa33-addd5bbfb38f
📒 Files selected for processing (22)
packages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/core/auth-domain.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/auth-domain.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/lib/src/core/auth-domain.tspackages/lib/src/usecases/auth-grok-logout.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/core/auth-domain.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/lib/src/core/auth-domain.tspackages/lib/src/usecases/auth-grok-logout.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/core/auth-domain.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/lib/src/core/auth-domain.tspackages/lib/src/usecases/auth-grok-logout.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/core/auth-domain.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/lib/src/core/auth-domain.tspackages/lib/src/usecases/auth-grok-logout.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/core/auth-domain.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/lib/src/core/auth-domain.tspackages/lib/src/usecases/auth-grok-logout.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/core/auth-domain.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/lib/src/core/auth-domain.tspackages/lib/src/usecases/auth-grok-logout.tspackages/app/src/docker-git/frontend-lib/core/auth-domain.tspackages/app/src/lib/usecases/auth-grok-logout.tspackages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/docker-git/cli/parser-auth.tspackages/app/src/lib/core/templates/dockerfile.tspackages/app/src/lib/core/auth-domain.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/usecases/auth-grok.test.tspackages/app/src/lib/usecases/auth-grok.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/lib/src/usecases/auth-grok.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/api/tests/project-auth.test.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/api/tests/project-auth.test.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
🔇 Additional comments (23)
packages/lib/src/core/auth-domain.ts (1)
109-137: LGTM!Also applies to: 155-157
packages/lib/src/usecases/auth-grok-logout.ts (1)
21-35: LGTM!packages/app/src/docker-git/frontend-lib/core/auth-domain.ts (1)
110-137: LGTM!Also applies to: 156-158
packages/app/src/lib/usecases/auth-grok-logout.ts (1)
21-35: LGTM!packages/app/src/docker-git/cli/parser-auth.ts (1)
14-15: LGTM!Also applies to: 47-47, 54-54, 197-229, 244-244
packages/app/src/lib/core/templates/dockerfile.ts (1)
126-127: ⚡ Quick winПоставка Grok CLI несёт риск supply-chain, но предложенное исправление не осуществимо.
На Lines 126-127 выполняется удалённый скрипт без проверки целостности. Однако xAI не публикует официальные SHA256-контрольные суммы или immutable версионные URL для
install.sh[веб-поиск 18.05.2026]. Предложенное в diff добавление SHA256-константы не имеет источника и не может быть реализовано без прямого участия xAI.Что можно сделать вместо этого:
- Свяжитесь с xAI и попросите опубликовать хеш-суммы для releases (или подпишите скрипт/release в формате cosign/minisign).
- Если xAI не поддерживает это, рассмотрите зеркалирование/vendoring скрипта в репозитории с явной версией вместо загрузки из интернета на build-time.
- Текущий подход (скачивание в файл перед выполнением, а не piping) лучше, чем рекомендуемый xAI метод, и обеспечивает возможность локальной проверки.
packages/lib/src/core/templates-entrypoint/grok.ts (3)
1-27: LGTM!
140-182: LGTM!
183-298: LGTM!packages/api/src/services/project-auth.ts (4)
20-32: LGTM!
174-198: LGTM!Also applies to: 239-239
200-322: LGTM!
382-414: LGTM!packages/lib/src/usecases/auth-grok.ts (3)
30-52: LGTM!
54-66: LGTM!
73-95: LGTM!packages/app/src/lib/usecases/auth-grok-helpers.ts (5)
1-46: LGTM!
58-74: LGTM!
97-224: LGTM!
226-255: LGTM!
256-304: LGTM!packages/lib/src/usecases/auth-grok-helpers.ts (1)
1-303: LGTM!packages/app/src/lib/core/templates-entrypoint/grok.ts (1)
1-300: LGTM!
| RUN set -eu; \ | ||
| curl -fsSL --retry 5 --retry-all-errors --retry-delay 2 ${grokCliInstallScriptUrl} -o /tmp/grok-install.sh; \ | ||
| HOME=/tmp/grok-install-home GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh ${grokCliVersion}; \ | ||
| install -m 0755 "$(readlink -f /usr/local/bin/grok)" /usr/local/bin/grok.real; \ | ||
| install -m 0755 "$(readlink -f /usr/local/bin/agent)" /usr/local/bin/agent.real; \ | ||
| mv -f /usr/local/bin/grok.real /usr/local/bin/grok; \ | ||
| mv -f /usr/local/bin/agent.real /usr/local/bin/agent; \ | ||
| rm -rf /tmp/grok-install.sh /tmp/grok-install-home | ||
| RUN grok --version` |
There was a problem hiding this comment.
Не исполняйте удалённый install.sh без проверки целостности.
На Line 126–127 скрипт с x.ai скачивается и сразу запускается. Добавьте pinned checksum (или signature verification), иначе это supply-chain риск.
Возможный минимальный фикс
+ARG GROK_INSTALL_SHA256=<pin-this>
RUN set -eu; \
curl -fsSL --retry 5 --retry-all-errors --retry-delay 2 ${grokCliInstallScriptUrl} -o /tmp/grok-install.sh; \
+ echo "${GROK_INSTALL_SHA256} /tmp/grok-install.sh" | sha256sum -c -; \
HOME=/tmp/grok-install-home GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh ${grokCliVersion}; \🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/src/core/templates/dockerfile.ts` around lines 125 - 133, The
Dockerfile currently downloads and executes the remote installer referenced by
grokCliInstallScriptUrl into /tmp/grok-install.sh without integrity checks;
change the RUN step to first download the script to /tmp/grok-install.sh,
compute its SHA256 (e.g., sha256sum /tmp/grok-install.sh), compare that checksum
against a pinned value injected by the template (add a GROK_INSTALL_SHA256 or
similar template variable), and exit non‑zero if it doesn't match; only after
successful verification, run HOME=/tmp/grok-install-home
GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh ${grokCliVersion} and
proceed with the existing install/mv cleanup steps.
2a1eded to
12059aa
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 183-184: Replace the hardcoded chown "1000:1000" with the
configured SSH user ownership: read the owner from config.sshUser (e.g.,
config.sshUser.uid and config.sshUser.gid) and use those values when running
chown on GROK_SETTINGS_DIR (and keep the chmod for GROK_CONFIG_SETTINGS_FILE and
GROK_USER_SETTINGS_FILE); if config.sshUser is not present, fall back to the
runtime user IDs (e.g., id -u/id -g) to avoid breaking permissions in rootless
or remapped containers.
In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 185-190: Функция renderGrokSudoConfig создаёт sudo-файл с опасной
записью "${config.sshUser} ALL=(ALL) NOPASSWD:ALL"; ограничьте привилегии либо
перечислением конкретных необходимых команд вместо NOPASSWD:ALL (например только
/usr/bin/systemctl, /usr/bin/journalctl или скрипты агента) с явным указанием
пути, либо, если полный безпарольный sudo — это осознанное решение, добавьте в
renderGrokSudoConfig/рядом с шаблоном комментарий, объясняющий
причинно-следственную обоснованность и риск-обоснование для config.sshUser в
TemplateConfig, чтобы ревью явно видел выбор.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 208e2981-82ab-4a57-b62e-a8aee628acb0
📒 Files selected for processing (17)
packages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-status.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.tsscripts/e2e/_lib.shscripts/e2e/browser-command.shscripts/e2e/opencode-autoconnect.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/lib/src/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/lib/src/usecases/auth-grok-status.tsscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shscripts/e2e/browser-command.shpackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/lib/src/usecases/auth-grok-status.tsscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shscripts/e2e/browser-command.shpackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/lib/src/usecases/auth-grok-status.tsscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shscripts/e2e/browser-command.shpackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/lib/src/usecases/auth-grok-status.tsscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shscripts/e2e/browser-command.shpackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/src/services/project-auth.tspackages/api/tests/project-auth.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/tests/project-auth.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/usecases/auth-grok.test.tspackages/lib/tests/core/templates.test.tspackages/api/tests/project-auth.test.ts
🔇 Additional comments (24)
packages/lib/src/usecases/auth-grok-status.ts (1)
1-33: LGTM!scripts/e2e/opencode-autoconnect.sh (1)
22-22: LGTM!Also applies to: 27-28
scripts/e2e/_lib.sh (1)
137-202: LGTM!scripts/e2e/browser-command.sh (1)
24-27: LGTM!packages/app/src/lib/usecases/auth-grok-credential-text.ts (1)
1-77: LGTM!packages/lib/src/usecases/auth-grok-credential-text.ts (1)
1-75: LGTM!packages/app/src/lib/usecases/auth-grok-status.ts (1)
1-33: LGTM!packages/app/src/lib/usecases/auth-grok-oauth.ts (1)
1-135: LGTM!packages/lib/src/usecases/auth-grok-oauth.ts (3)
44-65: Отсутствует TSDoc для экспортируемой функцииbuildDockerGrokAuthArgs.Согласно coding guidelines, все экспортируемые функции должны иметь TSDoc с
@pure,@effect,@invariant,@precondition,@postcondition,@complexity.
108-135: Отсутствует TSDoc для экспортируемой функцииrunGrokOauthLoginWithPrompt.Согласно coding guidelines, все экспортируемые функции должны иметь TSDoc с
@pure,@effect,@invariant,@precondition,@postcondition,@complexity.
77-106: LGTM!packages/lib/src/core/templates-entrypoint/grok.ts (2)
1-12: LGTM!Also applies to: 281-300
111-140: LGTM!packages/lib/tests/usecases/auth-grok.test.ts (1)
83-108: LGTM!Also applies to: 109-159, 160-200, 202-261, 262-276, 278-291, 293-312, 314-333, 335-371, 373-416
packages/lib/tests/core/templates.test.ts (1)
30-30: LGTM!Also applies to: 218-229, 424-468, 489-508, 510-538
packages/api/src/services/project-auth.ts (1)
21-33: LGTM!Also applies to: 175-199, 201-213, 255-309, 369-401, 403-416, 490-504
packages/api/tests/project-auth.test.ts (1)
1-127: LGTM!Also applies to: 129-162, 164-321
packages/app/src/lib/usecases/auth-grok-helpers.ts (1)
1-75: LGTM!Also applies to: 98-125, 127-169, 171-206, 208-236, 237-285
packages/lib/src/usecases/auth-grok-helpers.ts (1)
1-74: LGTM!Also applies to: 76-124, 126-168, 170-205, 207-235, 237-283
packages/app/src/lib/core/templates-entrypoint/grok.ts (5)
275-275: Тот же захардкоженный UID 1000.Аналогичная проблема с
chown 1000:1000— см. комментарий выше (строка 183).
1-28: LGTM!
29-147: LGTM!
282-302: LGTM!
186-191: ⚡ Quick winВалидация
config.sshUserзащищена на достаточном уровне и не требует дополнительных мер.Функция
parseSshUserвcommand-builders-shared.tsобязательно валидирует входное значение против регулярного выражения/^[a-z_][a-z0-9_-]{0,31}$/, которое математически исключает все shell-метасимволы, включая символы новой строки. Попытки внедрить произвольные sudoers-правила вроде"user\nroot ALL=(ALL) NOPASSWD:ALL"отклоняются на этапе парсинга перед созданиемTemplateConfig. В коде уже задокументирована FORMAT THEOREM, подтверждающая что любое значение, прошедшееisUnixUserName, не содержит опасных символов.
# Conflicts: # packages/app/src/docker-git/cli/usage.ts # packages/lib/src/core/templates/docker-compose.ts
There was a problem hiding this comment.
Actionable comments posted: 8
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/api/tests/project-auth.test.ts`:
- Around line 118-120: Remove the forbidden type assertion "as const" from the
objects returned by the Effect.match handlers (the onFailure and onSuccess
results) — e.g., change the returned {_tag: "failure" as const, ...} and {_tag:
"success" as const, ...} to plain {_tag: "failure", ...} and {_tag: "success",
...}; TypeScript will infer literal string types and existing narrowing logic
(used later in the test around the snapshot checks) will continue to work
without the cast.
In `@packages/app/src/docker-git/cli/usage.ts`:
- Line 79: Обновите весь блок help/usage в файле containing usage.ts так, чтобы
упоминания провайдеров аутентификации и секция "Авторизация"/"Auth providers"
включали Grok (Grok) повсеместно, и чтобы описание флага --auto (строка
"--auto[=claude|codex|gemini|grok") согласовывалось с этим: добавьте Grok в
список провайдеров, обновите пояснения выбора агента при --auto (как по
умолчанию при авторизации или при нескольких доступных) и приведите
примеры/текст секции "auth" и "Auth providers" к одному стилю с остальными
провайдерами (используйте те же формулировки и порядок, что для
claude|codex|gemini).
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 29-45: The grokAuthConfigTemplate uses direct expansions of
GROK_AUTH_LABEL (via GROK_LABEL_RAW="$GROK_AUTH_LABEL") which will fail under
set -u; update the template so GROK_LABEL_RAW is assigned with a safe default
expansion (e.g. use parameter expansion like "${GROK_AUTH_LABEL:-}" or
"${GROK_AUTH_LABEL:-default}") and keep the existing fallback logic for
GROK_LABEL_NORM; modify the occurrences inside the grokAuthConfigTemplate string
(referencing variable grokAuthConfigTemplate and the template variables
GROK_LABEL_RAW, GROK_AUTH_LABEL, GROK_LABEL_NORM, GROK_AUTH_ROOT) to use the
safe expansions so the bootstrap won’t abort when GROK_AUTH_LABEL is unset
(apply same fix for the other block at lines 193-211).
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 215-220: The fallback uses raw accountPath in the docker -v mount
which can fail on some hosts; before building removeFallback (the pipe that
calls runCommandExitCode), compute the Docker-safe host path using the same
resolver used in the Grok OAuth flow (call it the Docker-safe host path resolver
used elsewhere) and store it in hostPath, then replace `${accountPath}` with
`${hostPath}` in the docker args so the container gets a normalized mount path.
Ensure you reference removeFallback, runCommandExitCode, and accountPath when
making this change.
In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 29-45: The script reads GROK_AUTH_LABEL directly which breaks when
shell is run with set -u; change the direct reads to parameter-expansion
defaults (e.g., use GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" instead of
GROK_LABEL_RAW="$GROK_AUTH_LABEL") so unset variable access becomes safe, keep
the existing normalization in GROK_LABEL_NORM and fallback to "default" intact,
and apply the same defensive ${VAR:-} pattern to other occurrences of
GROK_AUTH_LABEL referenced later in the file (the block around GROK_LABEL_RAW,
GROK_LABEL_NORM and any uses in the 192-210 range).
In `@packages/lib/src/usecases/auth-grok-helpers.ts`:
- Around line 237-252: The defaults in defaultGrokProjectSettings and
defaultGrokUserSettings disable sandboxing and auto-trust the MCP server
(sandboxMode: "off", mcpServers.playwright.trust: true, and
confirmBeforeToolUse: false), which weakens security; update the code by adding
a concise inline comment and/or JSDoc above defaultGrokProjectSettings and
defaultGrokUserSettings that explains the security implications, notes these are
permissive defaults intended for dev/testing only, lists recommended safer
alternatives (e.g., sandboxMode: "on"/"strict", trust: false,
confirmBeforeToolUse: true) for production, and reference issue-304 for context
so readers see why these defaults exist and how to harden them.
- Around line 203-204: The variable name hasUserSettings is misleading because
it holds the result of hasGrokCredentials(fs, accountPath), which checks API key
and auth.json as well; rename the variable to hasGrokCredentials (or
hasCredentials) and update its usage in this function (the const declaration and
the ternary return that currently returns "oauth" or "none") so the name
reflects the actual semantic of the check and avoids confusion with
user-settings-only checks.
In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 83-106: fixGrokAuthPermissions currently swallows chmod/chown
failures by logging them then returning Effect.void, which makes the overall
auth step appear successful; change it so the effect fails instead of returning
success: in fixGrokAuthPermissions (the runCommandWithExitCodes pipeline that
can throw CommandFailedError), remove orElse(() => Effect.void) and either let
the original error propagate or map it to an AuthError (e.g.,
Effect.mapError(err => new AuthError({ cause: err }))) so callers see a failure
rather than a silent success.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2b1ede22-1cc7-4a96-a999-c7b73bc59fd8
📒 Files selected for processing (33)
packages/api/src/api/contracts.tspackages/api/src/api/schema.tspackages/api/src/http.tspackages/api/src/services/agents.tspackages/api/src/services/project-auth.tspackages/api/src/services/projects.tspackages/api/tests/project-auth.test.tspackages/api/tests/projects.test.tspackages/app/src/docker-git/api-client-create.tspackages/app/src/docker-git/api-client.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/app/src/web/api.tspackages/lib/src/core/templates-entrypoint.tspackages/lib/src/core/templates-entrypoint/base.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/core/templates/docker-compose.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/lib/src/usecases/auth-grok-helpers.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.tsscripts/e2e/_lib.shscripts/e2e/browser-command.shscripts/e2e/opencode-autoconnect.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/docker-git/api-client.tspackages/lib/src/core/templates-entrypoint.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/api-client-create.tspackages/api/src/services/projects.tspackages/app/src/web/api.tspackages/api/src/services/agents.tspackages/lib/src/core/templates-entrypoint/base.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/api/tests/projects.test.tspackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/api/src/http.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/docker-compose.tspackages/api/src/api/contracts.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/app/src/docker-git/api-client.tspackages/lib/src/core/templates-entrypoint.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/api-client-create.tspackages/api/src/services/projects.tspackages/app/src/web/api.tspackages/api/src/services/agents.tspackages/lib/src/core/templates-entrypoint/base.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/api/tests/projects.test.tspackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/api/src/http.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/docker-compose.tspackages/api/src/api/contracts.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/app/src/docker-git/api-client.tspackages/lib/src/core/templates-entrypoint.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/api-client-create.tspackages/api/src/services/projects.tspackages/app/src/web/api.tspackages/api/src/services/agents.tspackages/lib/src/core/templates-entrypoint/base.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/api/tests/projects.test.tsscripts/e2e/browser-command.shscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shpackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/api/src/http.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/docker-compose.tspackages/api/src/api/contracts.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/app/src/docker-git/api-client.tspackages/lib/src/core/templates-entrypoint.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/api-client-create.tspackages/api/src/services/projects.tspackages/app/src/web/api.tspackages/api/src/services/agents.tspackages/lib/src/core/templates-entrypoint/base.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/api/tests/projects.test.tsscripts/e2e/browser-command.shscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shpackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/api/src/http.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/docker-compose.tspackages/api/src/api/contracts.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/app/src/docker-git/api-client.tspackages/lib/src/core/templates-entrypoint.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/api-client-create.tspackages/api/src/services/projects.tspackages/app/src/web/api.tspackages/api/src/services/agents.tspackages/lib/src/core/templates-entrypoint/base.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/api/tests/projects.test.tsscripts/e2e/browser-command.shscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shpackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/api/src/http.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/docker-compose.tspackages/api/src/api/contracts.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/src/docker-git/api-client.tspackages/lib/src/core/templates-entrypoint.tspackages/app/src/docker-git/cli/usage.tspackages/app/src/docker-git/api-client-create.tspackages/api/src/services/projects.tspackages/app/src/web/api.tspackages/api/src/services/agents.tspackages/lib/src/core/templates-entrypoint/base.tspackages/app/src/docker-git/program-unsupported.tspackages/app/src/lib/usecases/auth-grok-status.tspackages/api/tests/projects.test.tsscripts/e2e/browser-command.shscripts/e2e/opencode-autoconnect.shscripts/e2e/_lib.shpackages/lib/src/usecases/auth-grok-status.tspackages/lib/src/usecases/auth-grok-credential-text.tspackages/api/src/http.tspackages/app/src/lib/usecases/auth-grok-credential-text.tspackages/api/src/api/schema.tspackages/lib/src/core/templates/dockerfile.tspackages/lib/src/usecases/auth-sync-helpers.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/api/tests/project-auth.test.tspackages/lib/src/core/templates/docker-compose.tspackages/api/src/api/contracts.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/usecases/auth-grok-helpers.tspackages/lib/tests/usecases/auth-grok.test.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/api/src/services/project-auth.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/api/tests/projects.test.tspackages/api/tests/project-auth.test.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/api/tests/projects.test.tspackages/api/tests/project-auth.test.tspackages/lib/tests/core/templates.test.tspackages/lib/tests/usecases/auth-grok.test.ts
🔇 Additional comments (30)
packages/app/src/docker-git/api-client.ts (1)
261-261: LGTM!packages/lib/src/core/templates-entrypoint.ts (1)
26-26: LGTM!Also applies to: 67-67
packages/app/src/docker-git/api-client-create.ts (1)
50-51: LGTM!packages/api/src/services/projects.ts (1)
441-442: LGTM!packages/app/src/web/api.ts (1)
188-188: LGTM!packages/api/src/services/agents.ts (1)
72-74: LGTM!packages/lib/src/core/templates-entrypoint/base.ts (1)
27-27: LGTM!packages/app/src/docker-git/program-unsupported.ts (1)
14-16: LGTM!Also applies to: 57-68
packages/app/src/lib/usecases/auth-grok-status.ts (1)
19-33: LGTM!packages/api/tests/projects.test.ts (1)
210-210: LGTM!scripts/e2e/browser-command.sh (1)
24-27: LGTM!scripts/e2e/opencode-autoconnect.sh (1)
22-22: LGTM!Also applies to: 27-28
scripts/e2e/_lib.sh (1)
137-202: LGTM!packages/lib/src/usecases/auth-grok-status.ts (1)
19-33: LGTM!packages/lib/src/usecases/auth-grok-credential-text.ts (1)
1-47: LGTM!packages/lib/src/core/templates/dockerfile.ts (1)
125-133: Исполнение удалённого install.sh всё ещё без проверки целостности.Здесь всё ещё выполняется скачанный скрипт без pinned checksum/signature, поэтому supply-chain риск не закрыт.
packages/lib/src/core/templates/docker-compose.ts (1)
234-234: Смешаны разные env-фрагменты под одним комментарием.Строка по-прежнему объединяет
maybeGrokAuthLabelEnvсmaybeAgentModeEnv/maybeAgentAutoEnv, из-за чего комментарий не соответствует всем переменным на строке.packages/api/src/http.ts (1)
185-185: LGTM!Also applies to: 430-466
packages/app/src/lib/usecases/auth-grok-credential-text.ts (1)
1-77: LGTM!packages/api/src/api/schema.ts (1)
37-38: LGTM!Also applies to: 65-67, 70-70, 114-117, 124-124, 136-138, 256-256
packages/lib/src/usecases/auth-sync-helpers.ts (1)
9-10: LGTM!Also applies to: 118-126, 177-177
packages/app/src/lib/usecases/auth-grok-oauth.ts (1)
1-136: LGTM!packages/lib/src/usecases/auth-grok-helpers.ts (8)
1-33: LGTM!
35-47: LGTM!
49-74: LGTM!
76-96: LGTM!
98-124: LGTM!
126-168: LGTM!
254-283: LGTM!
214-225: ⚡ Quick winПуть защищён от path traversal атак на уровне нормализации label.
Хотя
accountPathиспользуется в Docker volume mount, рисков нет. ФункцияnormalizeAccountLabelиспользует строгий regex/[^a-z0-9]+/g, который оставляет только буквы и цифры, переводя все остальные символы (включая..,/,.) в дефисы или удаляя их. Так, попытка path traversal вроде../../../etcпреобразуется вetcpasswdили подобное. Затемpath.join(rootPath, sanitizedLabel)конкатенирует пути безопасно. Кроме того, аргументы Docker передаются массивом["run", "--rm", "-v", "${accountPath}:/target", ...], а не через интерполяцию shell, поэтому command injection также невозможна.> Likely an incorrect or invalid review comment.
| onFailure: (error) => ({ _tag: "failure" as const, errorTag: error._tag }), | ||
| onSuccess: (snapshot) => ({ _tag: "success" as const, activeGrokLabel: snapshot.activeGrokLabel }) | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "project-auth.test.ts" -type fRepository: ProverCoderAI/docker-git
Length of output: 110
🏁 Script executed:
sed -n '100,140p' ./packages/api/tests/project-auth.test.tsRepository: ProverCoderAI/docker-git
Length of output: 1450
🏁 Script executed:
head -50 ./packages/api/tests/project-auth.test.tsRepository: ProverCoderAI/docker-git
Length of output: 1774
🏁 Script executed:
sed -n '118,160p' ./packages/api/tests/project-auth.test.tsRepository: ProverCoderAI/docker-git
Length of output: 1717
🏁 Script executed:
grep -n "as const\|as " ./packages/api/tests/project-auth.test.ts | head -20Repository: ProverCoderAI/docker-git
Length of output: 423
Удалите as const из результатов Effect.match.
Согласно coding guidelines, type casting с as запрещен в регулярном коде. В этом случае as const является избыточным: TypeScript автоматически выводит литеральные типы для строковых литералов в объектах. Тип narrowing на линиях 141-153 работает корректно без этих каст.
Рекомендуемое исправление
- onFailure: (error) => ({ _tag: "failure" as const, errorTag: error._tag }),
- onSuccess: (snapshot) => ({ _tag: "success" as const, activeGrokLabel: snapshot.activeGrokLabel })
+ onFailure: (error) => ({ _tag: "failure", errorTag: error._tag }),
+ onSuccess: (snapshot) => ({ _tag: "success", activeGrokLabel: snapshot.activeGrokLabel })🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/api/tests/project-auth.test.ts` around lines 118 - 120, Remove the
forbidden type assertion "as const" from the objects returned by the
Effect.match handlers (the onFailure and onSuccess results) — e.g., change the
returned {_tag: "failure" as const, ...} and {_tag: "success" as const, ...} to
plain {_tag: "failure", ...} and {_tag: "success", ...}; TypeScript will infer
literal string types and existing narrowing logic (used later in the test around
the snapshot checks) will continue to work without the cast.
| const removeFallback = pipe( | ||
| runCommandExitCode({ | ||
| cwd, | ||
| command: "docker", | ||
| args: ["run", "--rm", "-v", `${accountPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"] | ||
| }), |
There was a problem hiding this comment.
Нормализуйте host path перед docker run fallback.
В этой recovery-ветке в -v уходит raw accountPath, хотя в OAuth flow вы уже используете отдельный resolver для Docker-safe host path. Если fs.remove() упадёт на платформе/пути, который Docker не умеет монтировать напрямую, fallback тоже не сработает, и старый .grok останется на месте.
💡 Минимальная правка
- args: ["run", "--rm", "-v", `${accountPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"]
+ args: ["run", "--rm", "-v", `${hostPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"]Перед этим получите hostPath тем же способом, что уже используется в Grok OAuth flow.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts` around lines 215 - 220,
The fallback uses raw accountPath in the docker -v mount which can fail on some
hosts; before building removeFallback (the pipe that calls runCommandExitCode),
compute the Docker-safe host path using the same resolver used in the Grok OAuth
flow (call it the Docker-safe host path resolver used elsewhere) and store it in
hostPath, then replace `${accountPath}` with `${hostPath}` in the docker args so
the container gets a normalized mount path. Ensure you reference removeFallback,
runCommandExitCode, and accountPath when making this change.
| const hasUserSettings = yield* _(hasGrokCredentials(fs, accountPath)) | ||
| return hasUserSettings ? "oauth" : "none" |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Вводящее в заблуждение имя переменной.
Переменная hasUserSettings содержит результат hasGrokCredentials(), которая проверяет не только user-settings, но также apiKey и auth.json. Имя переменной не отражает фактическую семантику.
♻️ Предлагаемое исправление
- const hasUserSettings = yield* _(hasGrokCredentials(fs, accountPath))
- return hasUserSettings ? "oauth" : "none"
+ const hasCredentials = yield* _(hasGrokCredentials(fs, accountPath))
+ return hasCredentials ? "oauth" : "none"🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 203 - 204, The
variable name hasUserSettings is misleading because it holds the result of
hasGrokCredentials(fs, accountPath), which checks API key and auth.json as well;
rename the variable to hasGrokCredentials (or hasCredentials) and update its
usage in this function (the const declaration and the ternary return that
currently returns "oauth" or "none") so the name reflects the actual semantic of
the check and avoids confusion with user-settings-only checks.
| export const defaultGrokProjectSettings = { | ||
| sandboxMode: "off", | ||
| mcpServers: { | ||
| playwright: { | ||
| command: "docker-git-playwright-mcp", | ||
| args: [], | ||
| trust: true | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export const defaultGrokUserSettings = (apiKey: string | null) => ({ | ||
| ...(apiKey === null ? {} : { apiKey }), | ||
| sandboxMode: "off", | ||
| confirmBeforeToolUse: false | ||
| }) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Отключённый sandbox и trust: true снижают защиту — убедитесь, что это задокументировано.
Конфигурация по умолчанию отключает sandbox (sandboxMode: "off") и автоматически доверяет MCP-серверу (trust: true), а также отключает подтверждение перед использованием инструментов (confirmBeforeToolUse: false). Это соответствует спецификации issue-304, но пользователи должны понимать последствия для безопасности.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 237 - 252, The
defaults in defaultGrokProjectSettings and defaultGrokUserSettings disable
sandboxing and auto-trust the MCP server (sandboxMode: "off",
mcpServers.playwright.trust: true, and confirmBeforeToolUse: false), which
weakens security; update the code by adding a concise inline comment and/or
JSDoc above defaultGrokProjectSettings and defaultGrokUserSettings that explains
the security implications, notes these are permissive defaults intended for
dev/testing only, lists recommended safer alternatives (e.g., sandboxMode:
"on"/"strict", trust: false, confirmBeforeToolUse: true) for production, and
reference issue-304 for context so readers see why these defaults exist and how
to harden them.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
packages/app/src/lib/core/templates-entrypoint/grok.ts (1)
29-45:⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
GROK_AUTH_LABELвсё ещё падает подset -u.Первое же чтение
GROK_LABEL_RAW="$GROK_AUTH_LABEL"аварийно завершает bootstrap до fallback наdefault, а ниже тот же optional env снова читается при генерации profile/SSH env. В контейнере без явно выбранного label Grok setup не поднимется.Предлагаемая правка
-GROK_LABEL_RAW="$GROK_AUTH_LABEL" +GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" if [[ -z "$GROK_LABEL_RAW" ]]; then GROK_LABEL_RAW="default" fi GROK_LABEL_NORM="$(printf "%s" "$GROK_LABEL_RAW" \ | tr '[:upper:]' '[:lower:]' \ | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')" if [[ -z "$GROK_LABEL_NORM" ]]; then GROK_LABEL_NORM="default" fi +export GROK_AUTH_LABEL="$GROK_LABEL_NORM"Also applies to: 199-217
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/src/lib/core/templates-entrypoint/grok.ts` around lines 29 - 45, The template reads GROK_AUTH_LABEL directly which breaks under set -u; update grokAuthConfigTemplate to safely reference the optional env using shell parameter expansion (e.g. replace GROK_LABEL_RAW="$GROK_AUTH_LABEL" with GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" and any other direct uses of GROK_AUTH_LABEL later in the template/profile/SSH env generation with ${GROK_AUTH_LABEL:-} so the bootstrap won't abort and the existing fallback to "default" via GROK_LABEL_NORM still applies); ensure changes are made inside the grokAuthConfigTemplate string containing GROK_LABEL_RAW, GROK_LABEL_NORM, GROK_AUTH_ROOT and GROK_CONFIG_DIR.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 96-119: fixGrokAuthPermissions currently swallows chmod/chown
failures by logging them and returning Effect.void, making login appear
successful; remove the swallow so failures propagate: keep the
Effect.tapError(log) if you want diagnostics but drop the Effect.orElse(() =>
Effect.void) (or replace it with a no-op that re-throws/returns the original
failure) so the runCommandWithExitCodes result from fixGrokAuthPermissions (and
its CommandFailedError) bubbles up to abort the login flow; look for function
fixGrokAuthPermissions and the chained Effect.tapError / Effect.orElse calls and
change them accordingly.
In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 51-64: In docker_git_link_grok_file, when link_path exists as a
regular file the current logic copies it to source_path and returns early,
leaving link_path as a plain file and breaking auto-sync; change this so after
copying (if source_path doesn't already exist) you always replace link_path with
a symlink to source_path (i.e., remove the early return and run ln -sfn
"$source_path" "$link_path" afterwards), preserving the permission step (chmod
0600 on source_path) and ensuring ln -sfn is used to atomically create/overwrite
the symlink for selected-label state consistency.
In `@packages/lib/tests/core/templates.test.ts`:
- Around line 218-229: The test installs Grok CLI in a way that contradicts the
spec: update the test "installs Grok CLI for generated project containers" (and
the helper usage of renderDockerfile(makeTemplateConfig())) to assert the
intended behavior from the PR/issue (expect "grok-dev@latest" and the original
installer lines like "npm install -g grok-dev" or any legacy fallback), or if
the new pinned official installer ("https://x.ai/cli/install.sh" and pinned
version string) is the intended change, update the PR/issue description and
user-facing docs and change the test assertions to reflect the new installer
contract instead of forbidding "grok-dev". Ensure assertions reference the
relevant strings used in the code (e.g., checks around "grok-dev", "npm install
-g grok-dev", the install script URL, and the pinned version invocation) so the
test matches the documented/specified installer behavior.
---
Duplicate comments:
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 29-45: The template reads GROK_AUTH_LABEL directly which breaks
under set -u; update grokAuthConfigTemplate to safely reference the optional env
using shell parameter expansion (e.g. replace GROK_LABEL_RAW="$GROK_AUTH_LABEL"
with GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" and any other direct uses of
GROK_AUTH_LABEL later in the template/profile/SSH env generation with
${GROK_AUTH_LABEL:-} so the bootstrap won't abort and the existing fallback to
"default" via GROK_LABEL_NORM still applies); ensure changes are made inside the
grokAuthConfigTemplate string containing GROK_LABEL_RAW, GROK_LABEL_NORM,
GROK_AUTH_ROOT and GROK_CONFIG_DIR.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c6f13dfe-6d20-4a5b-adb1-6d0f4ab4db78
📒 Files selected for processing (5)
packages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/core/templates.test.ts
| it("installs Grok CLI for generated project containers", () => { | ||
| const dockerfile = renderDockerfile(makeTemplateConfig()) | ||
|
|
||
| expectContainsAll(dockerfile, [ | ||
| "https://x.ai/cli/install.sh", | ||
| "GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh 0.1.211", | ||
| "grok --version" | ||
| ]) | ||
| expect(dockerfile).not.toContain("grok-dev") | ||
| expect(dockerfile).not.toContain("npm install -g grok-dev") | ||
| expect(dockerfile).not.toContain("grok --version >/dev/null || true") | ||
| }) |
There was a problem hiding this comment.
Тест закрепляет поведение, расходящееся с заявленным ТЗ по установке Grok CLI.
В PR objectives и issue #304 явно указан шаблон с grok-dev@latest, а этот тест теперь фиксирует противоположный контракт: официальный install script c pinned-версией и явный запрет на grok-dev. Если переход на другой installer — осознанное решение, это нужно синхронно обновить в issue/PR description и user-facing docs; иначе тест сейчас цементирует неверное поведение.
As per coding guidelines, "Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход от спеки, недокументированное изменение поведения, отсутствие тестов для заявленного поведения и security-риск."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/lib/tests/core/templates.test.ts` around lines 218 - 229, The test
installs Grok CLI in a way that contradicts the spec: update the test "installs
Grok CLI for generated project containers" (and the helper usage of
renderDockerfile(makeTemplateConfig())) to assert the intended behavior from the
PR/issue (expect "grok-dev@latest" and the original installer lines like "npm
install -g grok-dev" or any legacy fallback), or if the new pinned official
installer ("https://x.ai/cli/install.sh" and pinned version string) is the
intended change, update the PR/issue description and user-facing docs and change
the test assertions to reflect the new installer contract instead of forbidding
"grok-dev". Ensure assertions reference the relevant strings used in the code
(e.g., checks around "grok-dev", "npm install -g grok-dev", the install script
URL, and the pinned version invocation) so the test matches the
documented/specified installer behavior.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 90-94: The grokAuthPermissionScript constant currently hardcodes
UID/GID "1000:1000"; change it to determine UID/GID dynamically like the fix in
packages/lib: build the chown operand from the runtime user/group (e.g. use id
-u and id -g or respect environment variables such as CHOWN_UID/CHOWN_GID) and
substitute that value into grokAuthPermissionScript so the chown uses the actual
container/user IDs rather than 1000:1000; update the grokAuthPermissionScript
symbol accordingly and mirror the same implementation approach used in
packages/lib/src/usecases/auth-grok-oauth.ts.
In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 90-94: The hardcoded chown in grokAuthPermissionScript (chown -R
1000:1000 "$1") will break in rootless Docker or when sshUser/UID differ; change
grokAuthPermissionScript to determine owner UID/GID dynamically or accept
UID/GID as parameters and use them in the chown command (e.g., mirror the
GROK_SETTINGS_OWNER_UID approach used in
packages/lib/src/core/templates-entrypoint/grok.ts), so that
grokAuthPermissionScript runs chown with the actual runtime owner instead of
1000:1000.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8c13ed0c-c6cf-4784-a6a4-83323786f3e6
📒 Files selected for processing (7)
README.mdpackages/app/src/docker-git/cli/usage.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/src/core/templates-entrypoint/grok.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (9)
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
README.mdpackages/app/src/docker-git/cli/usage.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/docker-git/cli/usage.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/app/src/docker-git/cli/usage.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/app/src/docker-git/cli/usage.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/app/src/docker-git/cli/usage.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/app/src/docker-git/cli/usage.tspackages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/lib/tests/core/templates.test.tspackages/app/src/lib/core/templates-entrypoint/grok.tspackages/lib/src/core/templates-entrypoint/grok.ts
**/packages/app/**/*.{ts,tsx,js}
📄 CodeRabbit inference engine (README.md)
APP layer (CLI + React Frontend) should only communicate with the API layer and not access LIB directly
Files:
packages/app/src/docker-git/cli/usage.tspackages/app/src/lib/usecases/auth-grok-oauth.tspackages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example:fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example:Effect.provide(MockService), Effect.runPromise.
Files:
packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
Files:
packages/lib/tests/core/templates.test.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ProverCoderAI/docker-git
Timestamp: 2026-05-18T07:43:12.431Z
Learning: Default project location is `~/.docker-git`
Learnt from: CR
Repo: ProverCoderAI/docker-git
Timestamp: 2026-05-18T07:43:12.431Z
Learning: Projects should be created for each repository, issue, or PR separately with isolated Docker environments
Learnt from: CR
Repo: ProverCoderAI/docker-git
Timestamp: 2026-05-18T07:43:12.431Z
Learning: Controller runtime contract requires host-Docker-backed design with bind-mounted `/var/run/docker.sock` for managing per-project containers
Learnt from: CR
Repo: ProverCoderAI/docker-git
Timestamp: 2026-05-18T07:43:12.431Z
Learning: When CLI cannot acquire Docker access, diagnostic messages must identify the specific failure mode (daemon unreachable, socket permission denied, or controller not running) and provide remediation steps
Learnt from: CR
Repo: ProverCoderAI/docker-git
Timestamp: 2026-05-18T07:43:12.431Z
Learning: Controller diagnostics implementation should be in `packages/app/src/docker-git/controller-docker-diagnostics.ts`
🔇 Additional comments (13)
README.md (1)
28-34: LGTM!Also applies to: 53-54
packages/app/src/docker-git/cli/usage.ts (1)
37-37: LGTM!Also applies to: 73-74, 81-81, 114-115, 130-131
packages/lib/src/usecases/auth-grok-oauth.ts (1)
1-56: LGTM!Also applies to: 57-78, 80-88, 96-118, 120-162
packages/app/src/lib/usecases/auth-grok-oauth.ts (1)
1-56: LGTM!Also applies to: 57-78, 80-88, 96-118, 120-162
packages/lib/tests/core/templates.test.ts (3)
30-30: LGTM!Also applies to: 218-229
424-468: LGTM!
489-576: LGTM!packages/app/src/lib/core/templates-entrypoint/grok.ts (3)
1-145: LGTM!
147-221: LGTM!
223-315: LGTM!packages/lib/src/core/templates-entrypoint/grok.ts (3)
1-145: LGTM!
146-221: LGTM!
222-313: LGTM!
Fixes #304
Summary
--auto grokagent selection..docker-git/.orch/auth/grok/<label>storage, and state auto-sync.https://x.ai/cli/install.sh, configure~/.grok, disable sandbox by default, wire Playwright MCP, provide the intentional container-local sudo policy, and support Grok project rules/system prompt hooks.GROK_AUTH_LABEL,GROK_API_KEY,GROK_DEPLOYMENT_KEY, andXAI_API_KEYunderset -u.~/.grokfiles with symlinks into the selected.orch/auth/grok/<label>account directory.Reproduction / Verification
auth grok ...,--auto grok, Grok provider schemas, and Grok template auth paths were absent.set -u.Mathematical Guarantees
Invariants
forall label: authGrokLogin(label, key) -> exists .docker-git/.orch/auth/grok/normalize(label)/.api-keyforall project: grokAuthLabel(project) -> Grok credentials are mounted from the selected label onlyforall generated Grok entrypoint: unset(optional_grok_env) -> no nounset failure during bootstrapforall Grok agent run: command includes sandbox disabled and Playwright MCP isolation enabledforall credential status checks: no API key value is loggedPreconditions
grok login --device-authin the auth image.Postconditions
.grok/settings.jsonwith Playwright MCP and sandbox off..api-key,.env, and.grokcredential material for the selected label.Tests
bun run --cwd packages/lib test tests/core/templates.test.ts tests/usecases/auth-grok.test.tsbun run --filter @effect-template/lib typecheckbun run --filter @prover-coder-ai/docker-git typecheckbun x @ton-ai-core/vibecode-linter src/core/templates-entrypoint/grok.tsfrompackages/libbun x @ton-ai-core/vibecode-linter src/usecases/auth-grok-oauth.tsfrompackages/libbun x @ton-ai-core/vibecode-linter src/lib/usecases/auth-grok-oauth.tsfrompackages/apppackages/app/src/lib/core/templates-entrypoint/grok.tsandpackages/app/src/docker-git/cli/usage.tsjscpd src --silentfrompackages/libNotes
vibecode-linterwrapper can be OOM-killed locally on the large mirrored app Grok template file, so that file was validated through direct ESLint plus app typecheck; CI runs the full lint job.