Fix app lint failures and terminal copy regression#342
Conversation
|
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)**/*.{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:
**/*⚙️ CodeRabbit configuration file
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
packages/app/**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (README.md)
Files:
🔇 Additional comments (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughМногофайловый рефакторинг: create-flow разделён на модули (parsing, inputs, steps, apply, advance), веб-интерфейс вынесен в рендеры/типы/панели, терминальная подсистема модульно реорганизована (UI, inline-image runtime, cleanup), SSH-link логика выделена в core, copy/selection контроллеры и тесты обновлены. ChangesРасслоение Create Flow логики
Реорганизация веб-интерфейса
Терминальная UI — компоненты и типы
Терминальный runtime
Copy/selection и тесты
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 18
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/app/src/web/app-ready-ssh-link-hook.ts (2)
227-237:⚠️ Potential issue | 🟠 Major | ⚡ Quick winНе помечайте SSH-link обработанным до успешного разрешения.
handledTokenRef.current = requestKeyвыполняется до того, как найден проект и завершён attach/load. Из-за этого любой временный промах — пустойdashboard.projectsна первом рендере, кратковременный API failure, неуспешный attach — превращается в постоянный dead-end: следующийuseEffectуже выйдет поhandledTokenRef.current === requestKeyи повторной попытки не будет.🤖 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/web/app-ready-ssh-link-hook.ts` around lines 227 - 237, The code marks a SSH request handled too early by setting handledTokenRef.current = requestKey before the project/session is actually found and attached; instead, remove that early assignment and only set handledTokenRef.current = requestKey after successful resolution. Update calls to handleProjectSshLink and handleSessionSshLink so they return a success indicator (boolean or Promise<boolean>), await their result in the caller (or handle the returned promise), and only assign handledTokenRef.current = requestKey when the handler returns true (successful attach/load); keep the initial guard (args.busyLabel !== null || args.handledTokenRef.current === requestKey) unchanged.
240-282: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winДобавьте обязательный TSDoc и functional comments к
useSshLink.Новый публичный hook экспортируется без требуемых
@pure/@effect/@invariant/@precondition/@postcondition/@complexityи без блоков CHANGE/WHY/...; для shell-оркестратора это особенно важно, потому что побочные эффекты, таймер и инвариантыhandledTokenRefсейчас не зафиксированы по спекам репозитория.As per coding guidelines, "TypeScript functions must include comprehensive TSDoc with parameters, return types,
@puremarker,@effectdependencies,@invariant(mathematical),@precondition,@postcondition, and@complexityO-notation." and "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."🤖 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/web/app-ready-ssh-link-hook.ts` around lines 240 - 282, Add comprehensive TSDoc and the repo-required functional comment block to the exported hook useSshLink: document all parameters and return type, add `@pure/`@effect/@invariant/@precondition/@postcondition/@complexity tags, and mark the hook PURITY as SHELL because it creates side-effects (connectTimerRef timer and handledTokenRef invariants) and calls handleSshLinkEffect; in the FUNCTIONAL COMMENTS include CHANGE, WHY, QUOTE (or n/a), REF, SOURCE (or n/a), FORMAT THEOREM, PURITY (SHELL), an EFFECT signature listing explicit dependencies (actionContext, activeTerminalSessionId, addTerminalSession, busyLabel, dashboard.projects, deactivateTerminalWorkspace, selectTerminalSession, terminalSessions, locationSignature), state the INVARIANT for handledTokenRef (nullable string that, once set, must not be reused) and connectTimerRef (cleared on unmount), and add a COMPLEXITY note (O(1) per render) so reviewers can verify the side-effect and timer invariants.packages/app/src/web/app-ready-terminal-screen.tsx (1)
12-23:⚠️ Potential issue | 🟠 Major | ⚡ Quick winДобавьте fallback на первую доступную сессию.
Если
activeTerminalSessionIdпришёлnullили уже устарел, функция возвращаетnull, ноTerminalScreenниже всё равно рендерит layout при непустомterminalSessions. В итоге вкладки могут остаться видимыми, аActiveTerminalPaneпокажет пустой экран вместо терминала.💡 Локальная правка
const resolveActiveTerminalSessionId = ( sessions: ReadonlyArray<ActiveTerminalSession>, activeTerminalSessionId: string | null ): string | null => { if ( activeTerminalSessionId !== null && sessions.some((session) => terminalSessionId(session) === activeTerminalSessionId) ) { return activeTerminalSessionId } - return null + return sessions.length > 0 ? terminalSessionId(sessions[0]) : null }🤖 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/web/app-ready-terminal-screen.tsx` around lines 12 - 23, The resolveActiveTerminalSessionId currently returns null when activeTerminalSessionId is null or no longer present; change it to fall back to the first available session id when sessions is non-empty: inside resolveActiveTerminalSessionId, if the provided activeTerminalSessionId is null or not found via terminalSessionId(session) checks, return terminalSessionId(sessions[0]) (or the first session's id) instead of null; this will ensure TerminalScreen and ActiveTerminalPane render the first available terminal rather than an empty pane.
🤖 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/menu-create-advance.ts`:
- Around line 175-183: The function resolveNextCreateFlowStep currently uses
currentStepIndex when delegating to clampCreateSettingsStep, causing the flow to
possibly return the same index and stall; change the delegation to pass
currentStepIndex + 1 (i.e., advance to the next index) and ensure
clampCreateSettingsStep is still used to bound that value against
nextSteps.length - 1; apply the same +1 fix to the analogous logic around the
other occurrence that mirrors lines 204-207 so normal progression advances the
step index.
In `@packages/app/src/docker-git/menu-create-command-parse.ts`:
- Around line 19-53: The parser currently mutates the CreateTokenizeState
in-place (see pushCreateToken and consumeCreateTokenChar) — refactor both to
return a new CreateTokenizeState instead of mutating fields: change
pushCreateToken to return an updated state with tokens = state.current ?
[...state.tokens, state.current] : state.tokens and current = "" (and preserve
escaping/quote), and change consumeCreateTokenChar to return a new state on
every branch (handle escaping, setting escaping flag, entering/exiting quote by
returning {...state, escaping: true}, {...state, escaping: false, current:
state.current + char}, {...state, quote: char}, whitespace branch returning
result of pushCreateToken(state), etc. Update callers to use the returned state
and ensure tokens/current/quote/escaping are treated as readonly (use new
arrays/objects rather than push or direct assignments).
In `@packages/app/src/docker-git/menu-create-flow-types.ts`:
- Around line 50-54: Add full functional comment blocks and TSDoc to the three
exported predicate functions isCreateModeFlowView, isDisplayModeFlowView, and
isCreateFlowRepoStep: include the required functional-comment sections (CHANGE,
WHY, QUOTE or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL),
EFFECT signature for SHELL functions, INVARIANT) and the TSDoc contract tags
(`@pure`, `@effect`, `@invariant`, `@precondition`, `@postcondition`, `@complexity`, `@throws`
Never). For each predicate provide a one-line description, mark `@pure` true,
specify any effect as none, state the precondition/postcondition about the
CreateFlowView discriminant and step, declare invariants (e.g., mode values and
step range), and give time/space complexity (O(1)); attach these blocks
immediately above each exported function declaration.
In `@packages/app/src/docker-git/menu-create-inputs.ts`:
- Around line 34-74: The exported functions normalizeCreateFlowContext,
resolveDefaultOutDir, and resolveCreateInputs lack the required formal TSDoc
contract; add comprehensive TSDoc blocks above each export that specify
parameters and return types, include the mandated metadata fields (CHANGE, WHY,
QUOTE or n/a, REF, SOURCE or n/a), and the formal annotations: `@pure` or PURITY
(CORE|SHELL), `@effect` signature (list external deps for SHELL), `@invariant`
(mathematical), `@precondition`, `@postcondition`, and `@complexity` (Big-O). Ensure
the TSDoc also documents behavior examples/format theorems where required and
mentions any interactions with helpers like resolveRepoInput,
deriveRepoPathParts, defaultProjectsRoot, and joinPath so the effect/invariant
sections are accurate.
In `@packages/app/src/docker-git/menu-create-navigation.ts`:
- Around line 12-97: All navigation helpers lack the project's required formal
TSDoc; add comprehensive TSDoc blocks to clampCreateSettingsStep,
nextCreateSettingsStep, moveCreateSettingsWithin, booleanChoiceBuffer,
gpuChoiceBuffer, resolveCreateSettingsChoiceBuffer, moveCreateSettingsStep and
moveCreateDisplaySettingsStep that include: a short
CHANGE/WHY/QUOTE(ТЗ)/REF/SOURCE header, `@param` and `@returns`, `@pure` marker,
PURITY (CORE|SHELL) and EFFECT signature for any SHELL functions, `@invariant`
(mathematical) describing valid step ranges (e.g., firstCreateSettingsStepIndex
≤ step ≤ lastStep), `@precondition` (inputs must be in range), `@postcondition`
(returned step/view is clamped or null and when view is mutated it resets
buffer/inputError), `@complexity` Big-O, and a FORMAT THEOREM line; ensure the
invariant and postconditions cover clampCreateSettingsStep and
nextCreateSettingsStep behavior and that moveCreateSettingsWithin documents when
it returns null vs modified view and the exact fields it resets.
In `@packages/app/src/docker-git/menu-create-step-apply.ts`:
- Around line 28-53: The helpers (applyTextStep, applyGpuStep, applyBooleanStep
and the call that does Object.assign(input.nextValues, parsed.right)) currently
mutate input.nextValues; change them to return an immutable
Partial<CreateInputs> (e.g., Either.Either<Partial<CreateInputs>, ParseError> or
Either<true, ParseError> plus a Partial payload) instead of writing into
input.nextValues, and have the caller merge results using object spread to
produce a new nextValues object (e.g., nextValues = { ...nextValues,
...partialFromApply }) rather than Object.assign or direct property assignment;
update applyGpuStep to return the partial containing gpu when parseGpuInput
succeeds and update applyTextStep/applyBooleanStep to return the appropriate
partials for the given key so composition is immutable.
In `@packages/app/src/docker-git/menu-create-steps.ts`:
- Around line 6-37: Add full TSDoc and functional comment blocks above hasOwn,
isCreateStepSatisfied, resolveCreateFlowSteps, and resolveCreateDisplaySteps:
for each function include a formal FUNCTIONAL comment (CHANGE, WHY, QUOTE or
n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature
for SHELL functions, INVARIANT) and a complete TSDoc with `@pure` (true/false),
`@effect` (required services or none), `@invariant` (mathematical invariants),
`@precondition`, `@postcondition`, `@complexity` (time and space), and `@throws` Never,
plus parameter and return descriptions referencing CreateInputs, CreateStep and
createSteps where applicable; ensure the FUNCTIONAL block documents any state
changes or dependencies and the TSDoc matches those assertions and types.
In `@packages/app/src/web/actions-project-terminal.ts`:
- Around line 41-43: The code currently accesses
globalThis.crypto.getRandomValues and globalThis.crypto.randomUUID directly
which will throw if globalThis.crypto is undefined; update the checks and calls
to use optional chaining (e.g., globalThis.crypto?.getRandomValues and
globalThis.crypto?.randomUUID) so the existence of crypto is tested before
invoking methods and allow your fallback logic to run; apply this change in
packages/app/src/web/actions-project-terminal.ts where
getRandomValues/randomUUID are referenced.
In `@packages/app/src/web/app-ready-ssh-link-core.ts`:
- Around line 47-138: Add full TSDoc and repository-style functional comment
blocks for each new public export: readSshLinkRequestFromHref,
findProjectBySshToken, findLocalTerminalSession, selectLocalProjectTerminal,
selectWorkspaceTerminalSession, sshLinkRequestKey, and
resolveMissingSshSessionFallbackPath; each TSDoc must include parameter/return
descriptions plus required tags (`@pure` or `@effect`, `@invariant`, `@precondition`,
`@postcondition`, `@complexity`) and each functional comment must contain CHANGE,
WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL)
with EFFECT signature for SHELL, INVARIANT, and COMPLEXITY entries documenting
parsing and session-selection invariants and costs.
- Around line 15-25: decodePathTail and readSessionPathRequest currently call
decodeURIComponent on user-controlled segments and let URIError propagate
(causing crashes for malformed % encodings); wrap decodeURIComponent calls in a
safe wrapper (e.g., try/catch or a safeDecode function used by decodePathTail
and readSessionPathRequest) that returns a fallback (empty string or original
percent-encoded segment) so malformed segments yield null/ignored values rather
than throwing, and ensure readSshLinkRequestFromHref catches any remaining
decode errors and returns null on failure; additionally add TSDoc comments and
repository-required functional markers (e.g., `@public/`@internal and brief
description, params, returns) to the exported functions
readSshLinkRequestFromHref, findProjectBySshToken, findLocalTerminalSession,
selectLocalProjectTerminal, selectWorkspaceTerminalSession, sshLinkRequestKey,
and resolveMissingSshSessionFallbackPath to satisfy the doc rules.
In `@packages/app/src/web/app-ready-terminal-pane.tsx`:
- Around line 129-137: The code in handleTerminalKill inverts the
pending-session branch so backend-close is only called for non-pending sessions:
change the condition that calls
requestTerminalSessionClose(props.terminalSession.closePath) and
props.terminalSession.onExit to run for pending sessions
(runtime.pendingSession) instead of !runtime.pendingSession, ensuring
delete/close is sent to the server for pending sessions; keep
detachTerminalSession(props, runtime) and the onTerminalMessage call (which
already uses runtime.pendingSession to pick the message) intact.
- Around line 42-44: The call to deleteTerminalSessionByPath inside
requestTerminalSessionClose currently swallows errors (using
Effect.runPromise(...pipe(Effect.either, Effect.asVoid))) and handleTerminalKill
treats runtime.pendingSession as closed without calling backend close; change
requestTerminalSessionClose to propagate and surface errors (resolve the Effect
result and log/return failures instead of asVoid) and update handleTerminalKill
so that the pendingSession branch also calls requestTerminalSessionClose and
only calls detachTerminalSession when the backend close succeeded (or otherwise
show an error state); use the identifiers requestTerminalSessionClose,
deleteTerminalSessionByPath, handleTerminalKill, detachTerminalSession and
runtime.pendingSession to locate and modify the logic.
In `@packages/app/src/web/app-ready-terminal-tabs.tsx`:
- Around line 74-92: The "+" New terminal button is rendered even when no active
project exists (activeProject === null); update the render logic in
app-ready-terminal-tabs so that after computing activeProject via
activeTerminalProject(props.terminalSessions, props.activeSessionId) you return
null (or render an explicitly disabled button state) when activeProject is null
instead of rendering the clickable Box, and if you choose the disabled state
ensure onOpenProjectTerminalById is not called and the UI reflects disabled
styling.
In `@packages/app/src/web/panel-content-renderers.tsx`:
- Around line 99-106: В renderContentBody уберите небезопасный привязанный cast
в Match.orElse и замените на полное ветвление по оставшимся
BrowserMenuTag-значениям: перечислите явные Match.when для всех статических
панелей, которые должны попадать в renderStaticMenuPanel (указать явные ключи
StaticMenuTag), а для прочих BrowserMenuTag (например
"Browser","Databases","Ports","Prompts","Share","Skills","Tasks") либо добавьте
явную защиту/guard перед вызовом renderStaticMenuPanel, либо маршрутизируйте их
в безопасный обработчик; используйте Match.exhaustive() или явные Match.when
ветви вместо Match.orElse((menu) => renderStaticMenuPanel(menu as
StaticMenuTag)) чтобы исключить runtime-cast и гарантировать, что
renderStaticMenuPanel всегда получает действительный StaticMenuTag.
In `@packages/app/src/web/panel-project-terminal-sessions.tsx`:
- Line 72: When starting a new fetch for sessions (where setSessionsState is
called), the code preserves current.sessions which causes stale sessions from
the previous selectedProjectKey to be shown and allow attach/kill on wrong
sessions; change the update in the request-start branch of setSessionsState to
clear the list (e.g., set sessions to an empty array) so the UI does not show
previous sessions while loading—locate the call to setSessionsState((current) =>
({ error: null, loading: true, sessions: current.sessions })) and replace it so
sessions are reset when initiating a new load for the selectedProjectKey or
inside the fetchSessions flow.
In `@packages/app/src/web/panel-terminal-mobile-controls.tsx`:
- Line 115: Remove the forbidden type assertion by replacing the inline
(["left","up","down","right"] as const). Define a separate constant like keys:
ReadonlyArray<MobileTerminalKey> = ["left","up","down","right"] and then use
keys.map(...) in the JSX; update references to the existing map call where the
anonymous array is used so the code uses the new keys constant and the
MobileTerminalKey type instead of an as const assertion.
In `@packages/app/src/web/terminal-panel-inline-images-runtime.ts`:
- Around line 49-99: The fetchTerminalInlineImageBlob/loadTerminalImageEntry
flow currently waits indefinitely for client.get(...).arrayBuffer and has no
size limit; update fetchTerminalInlineImageBlob to abort the request on a hard
timeout (use an AbortController or Effect.timeout/timeoutTo) and enforce a max
response size by first checking response.headers["content-length"] and/or
streaming the body and stopping if accumulated bytes exceed a configured
MAX_INLINE_IMAGE_BYTES, returning terminalInlineImageFetchError; in
loadTerminalImageEntry ensure the Effect branch maps failures/timeouts/oversize
to unavailableTerminalInlineImageEntry(path, fetchUrl) (same as other failures)
and also cancel/skip processing if handlers.lifecycle.disposed so no hanging
fetch or memory growth occurs.
In `@packages/app/src/web/terminal-panel-optional-operation.ts`:
- Around line 3-13: The function runOptionalTerminalOperation currently
collapses the Effect.either result into a boolean via Either.isRight, losing the
typed error; instead return the actual Either produced by
Effect.runSync(Effect.either(Effect.try(...))) so callers can inspect the error.
Change runOptionalTerminalOperation to return the Either (e.g. Either<unknown,
void> or a more specific error type) and remove the Either.isRight folding; keep
using Effect.try({ try: operation, catch: error => error }) and return the
result of Effect.runSync(Effect.either(...)) so recoverable vs non-recoverable
errors are preserved for callers.
---
Outside diff comments:
In `@packages/app/src/web/app-ready-ssh-link-hook.ts`:
- Around line 227-237: The code marks a SSH request handled too early by setting
handledTokenRef.current = requestKey before the project/session is actually
found and attached; instead, remove that early assignment and only set
handledTokenRef.current = requestKey after successful resolution. Update calls
to handleProjectSshLink and handleSessionSshLink so they return a success
indicator (boolean or Promise<boolean>), await their result in the caller (or
handle the returned promise), and only assign handledTokenRef.current =
requestKey when the handler returns true (successful attach/load); keep the
initial guard (args.busyLabel !== null || args.handledTokenRef.current ===
requestKey) unchanged.
- Around line 240-282: Add comprehensive TSDoc and the repo-required functional
comment block to the exported hook useSshLink: document all parameters and
return type, add
`@pure/`@effect/@invariant/@precondition/@postcondition/@complexity tags, and mark
the hook PURITY as SHELL because it creates side-effects (connectTimerRef timer
and handledTokenRef invariants) and calls handleSshLinkEffect; in the FUNCTIONAL
COMMENTS include CHANGE, WHY, QUOTE (or n/a), REF, SOURCE (or n/a), FORMAT
THEOREM, PURITY (SHELL), an EFFECT signature listing explicit dependencies
(actionContext, activeTerminalSessionId, addTerminalSession, busyLabel,
dashboard.projects, deactivateTerminalWorkspace, selectTerminalSession,
terminalSessions, locationSignature), state the INVARIANT for handledTokenRef
(nullable string that, once set, must not be reused) and connectTimerRef
(cleared on unmount), and add a COMPLEXITY note (O(1) per render) so reviewers
can verify the side-effect and timer invariants.
In `@packages/app/src/web/app-ready-terminal-screen.tsx`:
- Around line 12-23: The resolveActiveTerminalSessionId currently returns null
when activeTerminalSessionId is null or no longer present; change it to fall
back to the first available session id when sessions is non-empty: inside
resolveActiveTerminalSessionId, if the provided activeTerminalSessionId is null
or not found via terminalSessionId(session) checks, return
terminalSessionId(sessions[0]) (or the first session's id) instead of null; this
will ensure TerminalScreen and ActiveTerminalPane render the first available
terminal rather than an empty pane.
🪄 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: f93b86c4-3d62-476f-878c-c83e5d604d0e
📒 Files selected for processing (41)
packages/app/src/docker-git/menu-create-advance.tspackages/app/src/docker-git/menu-create-choices.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-draft.tspackages/app/src/docker-git/menu-create-errors.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/panel-content-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/web/panel-create-select.tsxpackages/app/src/web/panel-project-details.tsxpackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-terminal.tsxpackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/terminal-panel-runtime-core.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 (Clone cache)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{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/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.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/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.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/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.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/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.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/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/src/docker-git/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.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/menu-create-errors.tspackages/app/src/web/panel-terminal-header.tsxpackages/app/src/web/actions-project-terminal.tspackages/app/src/web/panel-terminal-types.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-draft.tspackages/app/src/web/app-ready-main-panel-labels.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-types.tspackages/app/src/web/terminal-panel-cleanup-runtime.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/docker-git/menu-create-labels.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/app-ready-terminal-task-manager.tsxpackages/app/src/web/app-ready-terminal-types.tspackages/app/src/web/panel-content.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/app-ready-project-action-bar.tsxpackages/app/src/docker-git/menu-create-choices.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/web/app-ready-project-picker-screen.tsxpackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/panel-terminal-styles.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/web/actions-project-menu-commands.tspackages/app/src/web/panel-project-details.tsxpackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-main-panels.tsxpackages/app/src/web/panel-terminal.tsxpackages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-runtime-core.ts
🔇 Additional comments (25)
packages/app/src/docker-git/menu-create-shared.ts (1)
1-30: LGTM!packages/app/src/web/app-ready-project-action-bar.tsx (1)
1-164: LGTM!packages/app/src/web/panel-project-terminal-sessions.tsx (1)
1-71: LGTM!Also applies to: 73-222
packages/app/src/web/panel-terminal-header.tsx (1)
1-190: LGTM!packages/app/src/web/app-ready-project-picker-screen.tsx (1)
1-223: LGTM!packages/app/src/web/app-ready-main-panel-labels.ts (1)
1-47: LGTM!packages/app/src/web/app-ready-main-panels.tsx (1)
5-13: LGTM!Also applies to: 70-97
packages/app/src/web/actions-project-menu-commands.ts (1)
12-140: LGTM!packages/app/src/web/actions-projects.ts (1)
25-27: LGTM!Also applies to: 111-139
packages/app/src/docker-git/menu-create-inputs.ts (1)
22-31: ⚡ Quick winПроверьте защиту от path traversal при вычислении
outDir(контейнмент вprojectsRoot)В
packages/app/src/docker-git/menu-create-inputs.tsпуть собирается вручную (Lines 22-31 и 46-50) без явной нормализации/каноникализации и запрета опасных сегментов./..на уровне результата. Нужна гарантированная проверка, что итоговый путь после построения лежит внутриprojectsRoot(и чтоderiveRepoPathParts(...)/resolveRepoInput(...)не пропускают traversal-сегменты).packages/app/src/web/app-ready-terminal-types.ts (1)
1-63: LGTM!packages/app/src/web/panel-terminal.tsx (1)
3-310: LGTM!packages/app/src/web/panel-terminal-styles.ts (1)
1-219: LGTM!packages/app/src/web/panel-terminal-types.ts (1)
1-21: LGTM!packages/app/src/web/panel-terminal-mobile-controls.tsx (1)
1-114: LGTM!Also applies to: 116-167
packages/app/src/web/app-ready-terminal-tabs.tsx (1)
1-73: LGTM!Also applies to: 93-136
packages/app/src/docker-git/menu-create-choices.ts (1)
6-57: LGTM!packages/app/src/docker-git/menu-create-errors.ts (1)
3-7: LGTM!packages/app/src/docker-git/menu-create-labels.ts (1)
10-67: LGTM!packages/app/src/docker-git/menu-create-draft.ts (1)
4-28: LGTM!packages/app/src/web/panel-content-types.ts (1)
1-37: LGTM!packages/app/src/web/panel-content.tsx (1)
3-14: LGTM!packages/app/src/web/panel-create-select.tsx (1)
20-216: LGTM!packages/app/src/web/panel-project-details.tsx (1)
1-31: LGTM!Also applies to: 127-165
packages/app/src/web/app-ready-terminal-task-manager.tsx (1)
32-68: LGTM!
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/web/terminal-copy-interaction.ts`:
- Around line 291-294: The mousedown suppression unconditionally calls
suppressTerminalMouseReport(event) when forceSelectionContext is true, which
blocks events even if mouse tracking is disabled; update the condition in the
relevant block (where forceSelectionContext is checked and
suppressTerminalMouseReport(event) is called) to only suppress when
mouseTrackingMode !== "none" (e.g., if (forceSelectionContext &&
mouseTrackingMode !== "none") { suppressTerminalMouseReport(event); return; })
so right-click/selection events can propagate to external handlers when mouse
tracking is off.
In `@packages/app/tests/docker-git/terminal-copy-interaction.test.ts`:
- Around line 208-248: Replace the single example test with a property-based
test using fast-check: write an fc.assert(fc.property(fc.string({ minLength: 1
}), (selectedText) => { ... })) that for any non-empty selection recreates the
same setup (FakeTerminalCopyEventTarget, FakeTerminalCopyHost,
TerminalCopyInteractionTerminal with modes.mouseTrackingMode="any",
attachTerminalCopyInteraction, mouseEvent(2), copyEvent(...)), mutates
terminalSelection on host mousedown, dispatches mousedown and copy, and asserts
the same invariants currently checked (shiftKey true, no preventDefault on
mousedown, propagation/stopping counts, terminalSelection unchanged, no drag
listeners, clipboardWrites contains the original selectedText,
copy.preventDefaultCalls/stopPropagationCalls as before); keep using existing
helpers (attachTerminalCopyInteraction, copyEvent, mouseEvent,
FakeTerminalCopyHost, FakeTerminalCopyEventTarget) and do not use async/await or
Effect test utilities in this synchronous property test.
🪄 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: 76db857f-f15f-42a8-b4d8-7b1d6426425d
📒 Files selected for processing (3)
packages/app/src/web/terminal-copy-interaction.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.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 (Clone cache)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/app/tests/docker-git/terminal-copy-interaction.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/app/tests/docker-git/terminal-copy-interaction.test.ts
🔇 Additional comments (3)
packages/app/src/web/terminal-copy-interaction.ts (1)
211-214: LGTM!packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts (1)
138-154: LGTM!Also applies to: 220-227, 276-279
packages/app/tests/docker-git/terminal-copy-interaction.test.ts (1)
13-13: LGTM!
| it("keeps selected terminal text copyable after right-click while mouse tracking is active", () => { | ||
| const documentTarget = new FakeTerminalCopyEventTarget() | ||
| const host = new FakeTerminalCopyHost(documentTarget) | ||
| const selectedText = "line one\nline two" | ||
| let terminalSelection = selectedText | ||
| const terminal: TerminalCopyInteractionTerminal = { | ||
| getSelection: () => terminalSelection, | ||
| hasSelection: () => terminalSelection.length > 0, | ||
| modes: { mouseTrackingMode: "any" } | ||
| } | ||
| const terminalMouseReports: Array<TerminalCopyTestMouseEvent> = [] | ||
| const clipboardWrites: Array<{ readonly data: string; readonly format: string }> = [] | ||
| const disposable = attachTerminalCopyInteraction({ host, terminal }) | ||
| host.addBubbleMouseListener("mousedown", (event) => { | ||
| terminalMouseReports.push(event) | ||
| terminalSelection = "" | ||
| }) | ||
| const rightClick = mouseEvent(2) | ||
| const clipboardData = { | ||
| setData: (format: string, data: string) => { | ||
| clipboardWrites.push({ data, format }) | ||
| } | ||
| } | ||
| const copy = copyEvent(clipboardData) | ||
|
|
||
| host.dispatchMouse("mousedown", rightClick) | ||
| host.dispatchCopy(copy) | ||
|
|
||
| expect(rightClick.shiftKey).toBe(true) | ||
| expect(rightClick.preventDefaultCalls).toBe(0) | ||
| expect(rightClick.stopImmediatePropagationCalls).toBe(1) | ||
| expect(rightClick.stopPropagationCalls).toBeGreaterThanOrEqual(1) | ||
| expect(terminalMouseReports).toEqual([]) | ||
| expect(terminalSelection).toBe(selectedText) | ||
| expectNoDragListeners(documentTarget) | ||
| expect(clipboardWrites).toEqual([{ data: selectedText, format: "text/plain" }]) | ||
| expect(copy.preventDefaultCalls).toBe(1) | ||
| expect(copy.stopPropagationCalls).toBe(1) | ||
|
|
||
| disposable.dispose() | ||
| }) |
There was a problem hiding this comment.
Добавьте property-based тест для инварианта copy-after-right-click.
Сейчас проверяется один сценарий. Для этого поведения нужен инвариантный тест через fast-check (например: для любой непустой строки selection при активном tracking копируется ровно исходный текст и событие copy корректно перехватывается).
As per coding guidelines **/*.{test,spec}.{ts,tsx}: Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.
🤖 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/tests/docker-git/terminal-copy-interaction.test.ts` around lines
208 - 248, Replace the single example test with a property-based test using
fast-check: write an fc.assert(fc.property(fc.string({ minLength: 1 }),
(selectedText) => { ... })) that for any non-empty selection recreates the same
setup (FakeTerminalCopyEventTarget, FakeTerminalCopyHost,
TerminalCopyInteractionTerminal with modes.mouseTrackingMode="any",
attachTerminalCopyInteraction, mouseEvent(2), copyEvent(...)), mutates
terminalSelection on host mousedown, dispatches mousedown and copy, and asserts
the same invariants currently checked (shiftKey true, no preventDefault on
mousedown, propagation/stopping counts, terminalSelection unchanged, no drag
listeners, clipboardWrites contains the original selectedText,
copy.preventDefaultCalls/stopPropagationCalls as before); keep using existing
helpers (attachTerminalCopyInteraction, copyEvent, mouseEvent,
FakeTerminalCopyHost, FakeTerminalCopyEventTarget) and do not use async/await or
Effect test utilities in this synchronous property test.
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/web/terminal-copy-selection-drag.ts`:
- Around line 149-152: The return uses an `as` cast in
resolveTerminalSelectionDragTarget because TerminalSelectionDragHost currently
only types ownerDocument; update the type so the host already includes the
target interface: change TerminalSelectionDragHost to an intersection type
(TerminalSelectionDragTarget & { ownerDocument: Document | null | undefined })
so it guarantees addEventListener/removeEventListener/dispatchEvent exist on
host, then remove the `(host as TerminalSelectionDragTarget)` cast and return
host.ownerDocument ?? host directly in resolveTerminalSelectionDragTarget.
In `@packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts`:
- Line 78: Remove the unnecessary "as" casts: change the const declaration
pressedButtonsByMouseButton (currently "const pressedButtonsByMouseButton = [1,
4, 2] as const") to a normal typed array/readonly without an "as" cast, and
replace the unsafe cast "return events[0] as TerminalCopyTestMouseEvent" with a
proper runtime check and narrowing (e.g. if events[0] is undefined throw or
handle the missing case, then return events[0] typed as
TerminalCopyTestMouseEvent after the check) so the code respects
noUncheckedIndexedAccess and does not hide potential undefined values.
In `@packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts`:
- Around line 68-171: Добавьте property-based тесты с fast-check в тот же файл,
используя createRightClickCopyHarness и структуру flow (flow.clipboardWrites,
flow.copy, flow.host и т.д.): 1) генерация произвольного непустого selectedText
(string) и проверка, что после последовательности событий right-click
(dispatchMouse mousedown/rightRelease, contextmenu, dispatchCopy)
flow.clipboardWrites содержит ровно один объект с data === выбранный текст и
format === "text/plain"; 2) генерация пустой или whitespace selection и
проверка, что flow.clipboardWrites остаётся пустым и события обработки
(stopPropagation/stopImmediatePropagation/preventDefault на
flow.rightClick/flow.rightRelease/flow.contextMenu/flow.copy) соответствуют
существующим example-based ожиданиям; используйте fc.assert(fc.property(...)) и
реиспользуйте createRightClickCopyHarness(terminal, ...) с
terminal.getSelection()/hasSelection() привязанными к сгенерированному тексту.
🪄 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: f84559c1-4ef8-4f29-b21c-2d2c37c1cbb2
📒 Files selected for processing (5)
packages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.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 (OpenCode)
- GitHub Check: E2E (Login context)
- GitHub Check: Lint
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.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/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.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/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.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/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.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/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.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/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.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/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.ts
🪛 GitHub Check: Lint Effect-TS
packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
[failure] 78-78:
Casting is only allowed in src/core/axioms.ts
[failure] 297-297:
Casting is only allowed in src/core/axioms.ts
packages/app/src/web/terminal-copy-selection-drag.ts
[failure] 151-151:
Casting is only allowed in src/core/axioms.ts
🔇 Additional comments (2)
packages/app/src/web/terminal-copy-interaction.ts (1)
54-55: LGTM!Also applies to: 88-216
packages/app/tests/docker-git/terminal-copy-interaction.test.ts (1)
216-217: LGTM!
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/app/tests/docker-git/terminal-copy-interaction.test.ts (1)
1-221: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winДобавьте property-based тесты для инвариантов selection modifier.
Файл содержит только example-based тесты. Согласно coding guidelines, property-based тесты с fast-check обязательны для проверки математических инвариантов.
Пример инварианта: для любого события мыши и платформы,
forceTerminalSelectionModifierустанавливает ровно один изaltKeyилиshiftKeyвtrue.import * as fc from "fast-check" it.prop([ fc.record({ altKey: fc.boolean(), shiftKey: fc.boolean() }), fc.oneof(fc.constant("MacIntel"), fc.constant("Win32"), fc.constant("Linux")) ])("always sets exactly one selection modifier key", (event, platform) => { const result = forceTerminalSelectionModifier(event, platform) expect(result).toBe(true) const modifierCount = (event.altKey ? 1 : 0) + (event.shiftKey ? 1 : 0) expect(modifierCount).toBeGreaterThanOrEqual(1) })As per coding guidelines
**/*.{test,spec}.{ts,tsx}: Property-based tests (fast-check) must verify mathematical 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/app/tests/docker-git/terminal-copy-interaction.test.ts` around lines 1 - 221, Add a property-based test using fast-check that verifies the invariant of forceTerminalSelectionModifier: for any input mouse event object and platform string it returns true and sets exactly one of event.altKey or event.shiftKey to true; import fast-check (fc), generate arbitrary boolean altKey/shiftKey via fc.record and platform via fc.oneof(fc.constant("MacIntel"), fc.constant("Win32"), fc.constant("Linux")), call forceTerminalSelectionModifier(event, platform), assert the function returns true and that (event.altKey ? 1 : 0) + (event.shiftKey ? 1 : 0) === 1, and add this test into terminal-copy-interaction.test.ts alongside the existing tests.
♻️ Duplicate comments (2)
packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts (1)
68-171: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winДобавьте property-based тесты для инварианта right-click copy.
В файле нет property-based тестов с fast-check. Для инварианта "любой непустой текст selection после right-click flow копируется в clipboard без искажений" требуется property-based тест.
import * as fc from "fast-check" it.prop([fc.string({ minLength: 1, maxLength: 1000 })])( "preserves any non-empty selection text through right-click copy flow", (selectedText) => { let terminalSelection = selectedText const terminal: TerminalCopyInteractionTerminal = { getSelection: () => terminalSelection, hasSelection: () => terminalSelection.length > 0, modes: { mouseTrackingMode: "any" } } const flow = createRightClickCopyHarness( terminal, () => { terminalSelection = "" }, () => { terminalSelection = "" } ) flow.host.dispatchMouse("mousedown", flow.rightClick) flow.host.dispatchBubblingMouse("mouseup", flow.rightRelease) flow.host.dispatchMouse("contextmenu", flow.contextMenu) flow.host.dispatchCopy(flow.copy) expect(flow.clipboardWrites).toHaveLength(1) expect(flow.clipboardWrites[0]?.data).toBe(selectedText) flow.disposable.dispose() } )As per coding guidelines
**/*.{test,spec}.{ts,tsx}: Property-based tests (fast-check) must verify mathematical 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/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts` around lines 68 - 171, Add a property-based test using fast-check that verifies the invariant "any non-empty terminal selection is preserved through the right-click copy flow": import fast-check (fc) in the test file, create a test using it.prop or fc.property that generates non-empty strings (e.g., fc.string({ minLength: 1, maxLength: 1000 })), initialize terminalSelection from the generated string and build the TerminalCopyInteractionTerminal stub as in other tests, call createRightClickCopyHarness(terminal, ...clear callbacks), run the same sequence (host.dispatchMouse "mousedown", host.dispatchBubblingMouse "mouseup", host.dispatchMouse "contextmenu", host.dispatchCopy) and assert flow.clipboardWrites contains exactly one entry whose data equals the original generated string, then dispose flow.disposable. Ensure the test resides alongside the existing "terminal copy right-click interaction" tests and follows project test naming/guidelines.packages/app/src/web/terminal-copy-interaction.ts (1)
171-175:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winОграничьте подавление
mousedownтолько активным mouse tracking.При
forceSelectionContext=trueиmouseTrackingMode === "none"событие подавляетсяsuppressTerminalMouseReport, хотя mouse tracking неактивен. Это может помешать правильной работе контекстного меню при отключённом mouse tracking.💡 Предлагаемое исправление
forceTerminalSelectionModifier(event) if (forceSelectionContext) { this.selectionContext.refresh() - suppressTerminalMouseReport(event) + if (hasActiveMouseTracking(this.args.terminal)) { + suppressTerminalMouseReport(event) + } return }🤖 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/web/terminal-copy-interaction.ts` around lines 171 - 175, When forceSelectionContext is true you refresh the selection and suppress the mousedown unconditionally; change this so suppressTerminalMouseReport(event) is only called when mouse tracking is active (i.e. mouseTrackingMode !== "none"). Update the block that contains forceSelectionContext, this.selectionContext.refresh(), and suppressTerminalMouseReport(event) to check the current mouseTrackingMode (or this.mouseTrackingMode) before calling suppressTerminalMouseReport so context menus still work when mouseTrackingMode === "none".
🤖 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.
Outside diff comments:
In `@packages/app/tests/docker-git/terminal-copy-interaction.test.ts`:
- Around line 1-221: Add a property-based test using fast-check that verifies
the invariant of forceTerminalSelectionModifier: for any input mouse event
object and platform string it returns true and sets exactly one of event.altKey
or event.shiftKey to true; import fast-check (fc), generate arbitrary boolean
altKey/shiftKey via fc.record and platform via fc.oneof(fc.constant("MacIntel"),
fc.constant("Win32"), fc.constant("Linux")), call
forceTerminalSelectionModifier(event, platform), assert the function returns
true and that (event.altKey ? 1 : 0) + (event.shiftKey ? 1 : 0) === 1, and add
this test into terminal-copy-interaction.test.ts alongside the existing tests.
---
Duplicate comments:
In `@packages/app/src/web/terminal-copy-interaction.ts`:
- Around line 171-175: When forceSelectionContext is true you refresh the
selection and suppress the mousedown unconditionally; change this so
suppressTerminalMouseReport(event) is only called when mouse tracking is active
(i.e. mouseTrackingMode !== "none"). Update the block that contains
forceSelectionContext, this.selectionContext.refresh(), and
suppressTerminalMouseReport(event) to check the current mouseTrackingMode (or
this.mouseTrackingMode) before calling suppressTerminalMouseReport so context
menus still work when mouseTrackingMode === "none".
In `@packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts`:
- Around line 68-171: Add a property-based test using fast-check that verifies
the invariant "any non-empty terminal selection is preserved through the
right-click copy flow": import fast-check (fc) in the test file, create a test
using it.prop or fc.property that generates non-empty strings (e.g., fc.string({
minLength: 1, maxLength: 1000 })), initialize terminalSelection from the
generated string and build the TerminalCopyInteractionTerminal stub as in other
tests, call createRightClickCopyHarness(terminal, ...clear callbacks), run the
same sequence (host.dispatchMouse "mousedown", host.dispatchBubblingMouse
"mouseup", host.dispatchMouse "contextmenu", host.dispatchCopy) and assert
flow.clipboardWrites contains exactly one entry whose data equals the original
generated string, then dispose flow.disposable. Ensure the test resides
alongside the existing "terminal copy right-click interaction" tests and follows
project test naming/guidelines.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 31560750-762a-4a5f-80a4-3db2cb5eb86b
📒 Files selected for processing (5)
packages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.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 (Browser command)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: Lint
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.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/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.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/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.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/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/fixtures/terminal-copy-interaction.tspackages/app/src/web/terminal-copy-selection-drag.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/terminal-copy-interaction.ts
🔇 Additional comments (11)
packages/app/src/web/terminal-copy-interaction.ts (3)
1-12: LGTM!
88-125: LGTM!
127-215: LGTM!packages/app/src/web/terminal-copy-selection-drag.ts (4)
1-47: LGTM!
48-68: LGTM!
69-147: LGTM!
149-203: LGTM!packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts (3)
78-85: LGTM!
101-163: LGTM!
172-298: LGTM!packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts (1)
16-66: LGTM!
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/api/src/services/terminal-sessions.ts`:
- Around line 784-787: Add TSDoc and a short functional comment to the
renderTmuxRightClickBindingCommands function: document that it aggregates tmux
right-click configuration commands by mapping tmuxRightClickPaneBindings through
renderTmuxPaneRightClickBinding and tmuxRightClickStatusBindings through
renderTmuxStatusRightClickUnbind, state that it returns a ReadonlyArray<string>
of tmux command strings, note immutability/no side effects, and mention any
expectations about the input arrays (e.g. non-empty or already-valid binding
objects) so readers know how the function is used.
- Around line 776-782: Add comprehensive TSDoc and functional comment blocks for
renderTmuxPaneRightClickBinding and renderTmuxStatusRightClickUnbind: for each
function add a TSDoc summary, `@param` for the binding string, `@returns` describing
the tmux shell command, `@pure` true, an `@invariant` stating the returned string
contains properly shell-escaped arguments, and `@complexity` O(1); also include
functional comment markers (CHANGE, WHY, QUOTE(`#340`), REF, SOURCE, FORMAT
THEOREM, PURITY (CORE), INVARIANT, COMPLEXITY) explaining the behavioral intent,
pre/postconditions, and that the functions are pure and side-effect free. Ensure
the text references the exact function names (renderTmuxPaneRightClickBinding,
renderTmuxStatusRightClickUnbind) so reviewers can locate the changes.
- Around line 768-774: Add TSDoc and functional comments above the two constants
tmuxRightClickPaneBindings and tmuxRightClickStatusBindings: document purpose
(they control tmux right-click behavior for panes vs status bar), include a
CHANGE line describing what's added, a WHY line explaining why these specific
bindings are required (to capture right-click events in tmux and support
modifiers), a QUOTE line referencing issue `#340` as the spec, and a PURITY line
set to CORE; ensure the comments follow TSDoc format and sit immediately above
the const declarations for tmuxRightClickPaneBindings and
tmuxRightClickStatusBindings.
🪄 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: 92010357-ae41-42a2-9996-890376c11eb1
📒 Files selected for processing (2)
packages/api/src/services/terminal-sessions.tspackages/api/tests/terminal-sessions.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). (8)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: Final build (windows-latest)
- GitHub Check: E2E (Browser command)
- GitHub Check: Lint
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/terminal-sessions.tspackages/api/tests/terminal-sessions.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/src/services/terminal-sessions.tspackages/api/tests/terminal-sessions.test.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/terminal-sessions.tspackages/api/tests/terminal-sessions.test.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/terminal-sessions.tspackages/api/tests/terminal-sessions.test.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/terminal-sessions.tspackages/api/tests/terminal-sessions.test.ts
packages/api/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
API layer should work only with LIB and serve as the intermediary between APP and LIB
Files:
packages/api/src/services/terminal-sessions.tspackages/api/tests/terminal-sessions.test.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/terminal-sessions.tspackages/api/tests/terminal-sessions.test.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/terminal-sessions.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/terminal-sessions.test.ts
🧠 Learnings (1)
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.
Applied to files:
packages/api/src/services/terminal-sessions.ts
🔇 Additional comments (3)
packages/api/src/services/terminal-sessions.ts (1)
1006-1006: LGTM!packages/api/tests/terminal-sessions.test.ts (2)
257-265: LGTM!
276-293: LGTM!
|
Добавили фичу: полностью отключили дефолтное tmux-меню на правую кнопку в browser terminal. Что покрыто:
Pane mouse events теперь только прокидываются через Проверки прошли локально и в PR checks: test/typecheck/lint/e2e green. |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/app/src/web/terminal-panel-inline-images-runtime.ts (1)
267-275: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
enqueueTerminalOutputэкспортирован без обязательного контракта runtime-инвариантов.Для этой точки входа важны pre/postconditions вокруг
outputQueue,outputWriting,disposedи последовательногоflush, но у нового export всё ещё нет TSDoc и required functional markers. As per coding guidelines, "TypeScript functions must include comprehensive TSDoc with parameters, return types,@puremarker,@effectdependencies,@invariant(mathematical),@precondition,@postcondition, and@complexityO-notation" and "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."🤖 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/web/terminal-panel-inline-images-runtime.ts` around lines 267 - 275, Add comprehensive TSDoc and required functional markers to the exported function enqueueTerminalOutput: document params and return, add `@pure` or `@effect` (SHELL) as appropriate, and include explicit `@precondition/`@postcondition and `@invariant` clauses that state the runtime contract for handlers.lifecycle.outputQueue (non-null, array structure), handlers.lifecycle.outputWriting (boolean semaphore semantics), handlers.lifecycle.disposed (false before enqueue), and that flushTerminalOutputQueue(handlers) is called sequentially and only after queueing; include a brief CHANGE/WHY/REF block, a QUOTE or n/a, FORMAT THEOREM line, and an explicit `@complexity` (O(n) where n is segments) plus an EFFECT signature if marked SHELL so reviewers can verify the side-effect on lifecycle flags and flush ordering.packages/app/src/docker-git/menu-create-advance.ts (1)
260-267:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winНа финальном шаге create-flow может зациклиться вместо завершения.
Для non-
repoUrlшага вычисляетсяcurrentStepIndex + 1, но затем он сразу clamped до максимального индекса. На последнем шаге это возвращает тот же индекс, и веткаContinueостаётся достижимой, поэтомуCompleteне наступает.Предлагаемое исправление
const resolveNextCreateFlowStep = ( currentStep: CreateStep, currentStepIndex: number, - nextSteps: ReadonlyArray<CreateStep> + _nextSteps: ReadonlyArray<CreateStep> ): number => currentStep === "repoUrl" ? firstCreateSettingsStepIndex - : clampCreateSettingsStep(currentStepIndex + 1, nextSteps.length - 1) + : currentStepIndex + 1 @@ const nextSteps = resolveCreateFlowSteps(nextValues) const nextStep = resolveNextCreateFlowStep(step, view.step, nextSteps) return nextSteps.length > firstCreateSettingsStepIndex && nextStep < nextSteps.length - ? continueCreateFlow(nextStep, nextValues) + ? continueCreateFlow(clampCreateSettingsStep(nextStep, nextSteps.length - 1), nextValues) : completeCreateFlow(context, nextValues)Also applies to: 305-309
🤖 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-create-advance.ts` around lines 260 - 267, The function resolveNextCreateFlowStep can return the same last-index for non-"repoUrl" steps which allows the flow to loop instead of completing; update resolveNextCreateFlowStep (and the analogous logic around lines 305-309) so that when currentStep !== "repoUrl" you advance to currentStepIndex + 1 and if that equals nextSteps.length (i.e., past the last index) return a sentinel or value that indicates completion (not the clamped last index) — use firstCreateSettingsStepIndex only for "repoUrl" case and rely on clampCreateSettingsStep(currentStepIndex + 1, nextSteps.length - 1) only after checking bounds or change the clamp call to allow nextSteps.length as a valid "complete" indicator; modify resolveNextCreateFlowStep and the other occurrence to return this distinct completion value so the Continue branch is no longer reachable on the final step.
🤖 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/menu-create-command-parse.ts`:
- Around line 69-85: The recursive tokenizer consumeCreateTokenInput can cause
stack overflow on long inputs; replace the recursive call with an iterative loop
inside consumeCreateTokenInput so it advances index and updates state until
index >= input.length, calling consumeCreateTokenChar for each char; preserve
the existing checks for codePointAt returning undefined and use char.length (to
handle surrogate pairs) when advancing the index, and return the final state
when finished.
In `@packages/app/src/web/app-ready-ssh-link-hook.ts`:
- Around line 199-206: Current code marks the deep-link handled immediately
after calling connectProjectById, which can leave the link unretryable if the
SSH session fails; change the flow so markSshLinkHandled(args, requestKey) is
only called after the connectProjectById pipeline signals a real success and
clearPendingSshLink(args, requestKey) is called on failure. Concretely, update
connectProjectById (or its caller contract) to return a Promise or accept
success/failure callbacks/events that resolve when attach/open completes (or
reject on error), then await or attach handlers in this block: if
request.terminalId is undefined, call connectProjectById(...).then(() =>
markSshLinkHandled(args, requestKey)).catch(() => clearPendingSshLink(args,
requestKey)); keep the existing immediate clearPendingSshLink(args, requestKey)
and message in the request.terminalId !== undefined branch unchanged.
In `@packages/app/src/web/terminal-copy-interaction.ts`:
- Around line 68-71: Add a full contract-style TSDoc to the exported function
shouldForceTerminalSelectionContext documenting parameters (event, terminal),
return boolean, and include the required repository markers: `@pure`, `@effect`
(dependencies: isSecondaryMouseButton, hasActiveMouseTracking,
terminal.hasSelection()), `@precondition` (describe when event/terminal must be
non-null and that hasActiveMouseTracking may be required), `@postcondition` (true
iff secondary button AND active mouse tracking AND terminal.hasSelection()),
`@invariant` (logical relation), and `@complexity` (O(1)); also include the
functional comment block with CHANGE, WHY, QUOTE or n/a, REF, SOURCE or n/a,
FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature and COMPLEXITY, ensuring
the new precondition referencing hasActiveMouseTracking is explicitly described.
---
Outside diff comments:
In `@packages/app/src/docker-git/menu-create-advance.ts`:
- Around line 260-267: The function resolveNextCreateFlowStep can return the
same last-index for non-"repoUrl" steps which allows the flow to loop instead of
completing; update resolveNextCreateFlowStep (and the analogous logic around
lines 305-309) so that when currentStep !== "repoUrl" you advance to
currentStepIndex + 1 and if that equals nextSteps.length (i.e., past the last
index) return a sentinel or value that indicates completion (not the clamped
last index) — use firstCreateSettingsStepIndex only for "repoUrl" case and rely
on clampCreateSettingsStep(currentStepIndex + 1, nextSteps.length - 1) only
after checking bounds or change the clamp call to allow nextSteps.length as a
valid "complete" indicator; modify resolveNextCreateFlowStep and the other
occurrence to return this distinct completion value so the Continue branch is no
longer reachable on the final step.
In `@packages/app/src/web/terminal-panel-inline-images-runtime.ts`:
- Around line 267-275: Add comprehensive TSDoc and required functional markers
to the exported function enqueueTerminalOutput: document params and return, add
`@pure` or `@effect` (SHELL) as appropriate, and include explicit
`@precondition/`@postcondition and `@invariant` clauses that state the runtime
contract for handlers.lifecycle.outputQueue (non-null, array structure),
handlers.lifecycle.outputWriting (boolean semaphore semantics),
handlers.lifecycle.disposed (false before enqueue), and that
flushTerminalOutputQueue(handlers) is called sequentially and only after
queueing; include a brief CHANGE/WHY/REF block, a QUOTE or n/a, FORMAT THEOREM
line, and an explicit `@complexity` (O(n) where n is segments) plus an EFFECT
signature if marked SHELL so reviewers can verify the side-effect on lifecycle
flags and flush ordering.
🪄 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: c6be95d9-6cdf-469f-8a30-d54190431c13
📒 Files selected for processing (25)
packages/api/src/services/terminal-sessions.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/src/web/panel-content-renderers.tsxpackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.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 (Login context)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{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/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/api/src/services/terminal-sessions.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.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/app/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.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/app/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/api/src/services/terminal-sessions.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.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/app/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/tests/docker-git/terminal-copy-interaction.test.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/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/api/src/services/terminal-sessions.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.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/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/api/src/services/terminal-sessions.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.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/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/api/src/services/terminal-sessions.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/tests/docker-git/app-ready-ssh-link-hook.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/terminal-panel-optional-operation.tspackages/app/src/web/panel-content-renderers.tsxpackages/app/src/docker-git/menu-create-steps.tspackages/app/src/web/app-ready-terminal-tabs.tsxpackages/api/src/services/terminal-sessions.tspackages/app/tests/docker-git/terminal-copy-right-click-interaction.test.tspackages/app/src/web/panel-project-terminal-sessions.tsxpackages/app/src/docker-git/menu-create-command-parse.tspackages/app/tests/docker-git/terminal-copy-interaction.test.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/menu-create-step-apply.tspackages/app/src/web/app-ready-terminal-pane.tsxpackages/app/src/docker-git/menu-create-inputs.tspackages/app/src/web/panel-terminal-mobile-controls.tsxpackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/app-ready-ssh-link-core.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/src/web/terminal-panel-runtime-core.tspackages/app/src/docker-git/menu-create-advance.ts
packages/api/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
API layer should work only with LIB and serve as the intermediary between APP and LIB
Files:
packages/api/src/services/terminal-sessions.ts
🧠 Learnings (1)
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.
Applied to files:
packages/api/src/services/terminal-sessions.ts
🔇 Additional comments (18)
packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts (1)
63-66: LGTM!packages/app/tests/docker-git/menu-create-shared.test.ts (1)
172-184: LGTM!packages/app/src/web/terminal-panel-optional-operation.ts (1)
1-21: LGTM!packages/app/src/web/panel-content-renderers.tsx (1)
99-126: LGTM!packages/app/src/docker-git/menu-create-steps.ts (1)
26-42: LGTM!Also applies to: 52-69
packages/app/src/web/app-ready-terminal-tabs.tsx (1)
75-84: LGTM!packages/api/src/services/terminal-sessions.ts (1)
768-934: LGTM!packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts (1)
2-224: LGTM!packages/app/src/web/panel-project-terminal-sessions.tsx (1)
72-72: LGTM!packages/app/tests/docker-git/terminal-copy-interaction.test.ts (1)
41-41: LGTM!packages/app/src/web/app-ready-terminal-screen.tsx (1)
22-23: LGTM!packages/app/src/docker-git/menu-create-step-apply.ts (1)
17-53: LGTM!Also applies to: 55-69, 101-101
packages/app/src/web/app-ready-terminal-pane.tsx (1)
42-52: LGTM!Also applies to: 137-150
packages/app/src/docker-git/menu-create-inputs.ts (1)
34-50: LGTM!Also applies to: 63-79, 87-103
packages/app/src/web/panel-terminal-mobile-controls.tsx (1)
27-36: LGTM!Also applies to: 126-129
packages/app/src/docker-git/menu-create-flow-types.ts (1)
50-105: Блоки TSDoc здесь всё ещё не закрывают обязательный контракт этих предикатов.У
isCreateModeFlowView,isDisplayModeFlowViewиisCreateFlowRepoStepвсё ещё нет@param,@returns,@precondition,@postconditionи@throws Never, поэтому формальный контракт для CORE-TS остаётся неполным. As per coding guidelines, "TypeScript functions must include comprehensive TSDoc with parameters, return types,@puremarker,@effectdependencies,@invariant(mathematical),@precondition,@postcondition, and@complexityO-notation" and "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."packages/app/src/docker-git/menu-create-navigation.ts (1)
12-165: Формальный контракт навигационных helper'ов всё ещё неполный.У экспортов здесь по-прежнему отсутствуют
@param,@returns,@precondition,@postconditionи@throws Never, аnextCreateSettingsStep,moveCreateSettingsWithin,booleanChoiceBufferиgpuChoiceBufferостаются без обязательных functional comments/TSDoc вовсе. As per coding guidelines, "TypeScript functions must include comprehensive TSDoc with parameters, return types,@puremarker,@effectdependencies,@invariant(mathematical),@precondition,@postcondition, and@complexityO-notation" and "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."packages/app/src/docker-git/menu-create-advance.ts (1)
22-45: LGTM!Also applies to: 57-80, 167-258, 269-304, 310-347
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
packages/app/src/web/actions-project-terminal.ts (1)
173-185:⚠️ Potential issue | 🟠 Major | ⚡ Quick winНе показывайте ошибку после уже завершённой pending-сессии.
Сейчас
wasFinalizedзащищает толькоlifecycle.onFailure, но функция всё равно пишет ошибку в output и заново добавляет error-tab. Если поздний stream callback прилетит уже после успешного attach, пользователь получит ложную ошибку поверх живой SSH-сессии.💡 Минимальное исправление
const showPendingTerminalError = ( context: BrowserActionContext, runtime: ConnectProjectRuntime, error: string ): void => { const wasFinalized = runtime.pendingSessionFinalized + if (wasFinalized) { + return + } runtime.pendingSessionFinalized = true - if (!wasFinalized) { - runtime.lifecycle.onFailure?.(error) - } + runtime.lifecycle.onFailure?.(error) appendOutputLine(context, `[error] ${error}`) context.addTerminalSession(renderPendingTerminalSession(context, runtime, error, "error")) }🤖 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/web/actions-project-terminal.ts` around lines 173 - 185, The function showPendingTerminalError currently sets runtime.pendingSessionFinalized and only guards lifecycle.onFailure, but still writes to the output and adds an error tab even when the pending session was already finalized; change showPendingTerminalError so that after reading/setting wasFinalized on runtime.pendingSessionFinalized it returns early when wasFinalized is true (i.e., do not call appendOutputLine or context.addTerminalSession) while still invoking lifecycle.onFailure only once; locate showPendingTerminalError and adjust its control flow around runtime.pendingSessionFinalized, lifecycle.onFailure, appendOutputLine, context.addTerminalSession and renderPendingTerminalSession accordingly.packages/app/src/docker-git/menu-create-advance.ts (1)
268-315:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winЗавершайте flow после применения последнего settings-шага.
Сейчас completion проверяется только по
nextSteps.length <= firstCreateSettingsStepIndex. Когда пользователь применяет последний доступный settings-step,nextStep === nextSteps.length, и код возвращаетContinueнаnextSteps.length - 1— то есть снова на тот же последний шаг.💡 Минимальное исправление
const shouldCompleteCreateFlow = ( - nextSteps: ReadonlyArray<CreateStep> -): boolean => nextSteps.length <= firstCreateSettingsStepIndex + nextSteps: ReadonlyArray<CreateStep>, + nextStep: number +): boolean => + nextSteps.length <= firstCreateSettingsStepIndex || nextStep >= nextSteps.length @@ const nextSteps = resolveCreateFlowSteps(nextValues) const nextStep = resolveNextCreateFlowStep(step, view.step) - if (shouldCompleteCreateFlow(nextSteps)) { + if (shouldCompleteCreateFlow(nextSteps, nextStep)) { return completeCreateFlow(context, nextValues) } - return nextStep < nextSteps.length - ? continueCreateFlow(clampCreateSettingsStep(nextStep, nextSteps.length - 1), nextValues) - : continueCreateFlow(nextSteps.length - 1, nextValues) + return continueCreateFlow( + clampCreateSettingsStep(nextStep, nextSteps.length - 1), + nextValues + )🤖 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-create-advance.ts` around lines 268 - 315, advanceCreateFlow currently treats applying the last settings-step as "Continue" because when resolveNextCreateFlowStep returns nextStep === nextSteps.length the code falls through and clamps back to nextSteps.length - 1; change the logic so that if nextStep >= nextSteps.length (or nextStep === nextSteps.length) you call completeCreateFlow(context, nextValues) instead of returning continueCreateFlow. Update the branch in advanceCreateFlow that computes nextStep (using resolveNextCreateFlowStep) to check for nextStep >= nextSteps.length before clamping/continuing and call completeCreateFlow; keep existing use of shouldCompleteCreateFlow(nextSteps) and clampCreateSettingsStep for other cases.packages/app/src/web/app-ready-ssh-link-hook.ts (1)
83-118:⚠️ Potential issue | 🟠 Major | ⚡ Quick winДобавьте guard от устаревших async-результатов перед UI-мутациями.
markSshLinkHandled()уже игнорирует старыйrequestKey, но самиonSuccess/onFailureветки всё ещё меняют history, screen, terminals и message без такой проверки. Если пользователь быстро откроет другой SSH-link, поздний ответ от предыдущего запроса сможет перетереть актуальное состояние.💡 Что поправить
Effect.match({ onFailure: (error) => { + if (args.pendingTokenRef.current !== requestKey) { + return + } // existing side effects }, onSuccess: (result) => { + if (args.pendingTokenRef.current !== requestKey) { + return + } // existing side effects } })Also applies to: 156-183
🤖 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/web/app-ready-ssh-link-hook.ts` around lines 83 - 118, The onSuccess/onFailure branches must guard against stale async results: at the top of each branch in the Effect.match for loadTerminalSessionById (the block containing markSshLinkHandled, clearPendingSshLink, requestKey and args.handledTokenRef.current), check that the incoming requestKey matches the current pending/handled token (e.g. args.handledTokenRef.current or your pending SSH-link ref) and early-return if it does not; only proceed to call markSshLinkHandled, clearPendingSshLink, history.replaceState, showProjectTerminalScreen, args.addTerminalSession and args.actionContext.setMessage when the keys match so late responses cannot overwrite UI state.packages/app/tests/docker-git/actions-projects.test.ts (1)
13-24:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftЗамените module-level
vi.mock()на моки через Effect Layer/Context Tag
packages/app/tests/docker-git/actions-projects.test.ts(13-24) подменяет../../src/web/api.jsчерез module-level monkey-patching (vi.mock()), а не через Effect test utilities на том же DI boundary (TypedContext.Tag+Layer/MockLayer). Это ослабляет тестовый контракт и расходится с правилами репозитория. То же относится к мокам в районе 44-45.🤖 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/tests/docker-git/actions-projects.test.ts` around lines 13 - 24, Replace the module-level vi.mock() usage that patches "../../src/web/api.js" (and the similar mocks around lines 44-45) with test-scoped mocks provided via the project's Effect/DI utilities: create a MockLayer/Layer that binds the Context.Tag for the web api to a mocked implementation (using applyAllProjectsMock, applyProjectMock, deleteProject, etc.), and then provide that layer to the test runtime instead of calling vi.mock(); update tests to import and use the Context.Tag and the Layer/MockLayer factory so the api functions are injected via the DI boundary rather than global module monkey-patching.
🤖 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/web/app-ready-ssh-link-terminal.ts`:
- Around line 17-54: Add full TSDoc and the required functional comment blocks
above showProjectTerminalScreen, buildProjectTerminalSession, and
attachProjectWorkspaceSessions: include a one-line summary,
`@param/`@returns/@throws as appropriate, then a functional comment block
containing CHANGE, WHY, QUOTE (or "n/a"), REF, SOURCE (or "n/a"), FORMAT
THEOREM, PURITY (mark CORE or SHELL), EFFECT signature for any SHELL functions,
INVARIANT (state assumptions like non-null args, sorted order), and COMPLEXITY
(time/space Big-O); ensure buildProjectTerminalSession documents that it
constructs an ActiveTerminalSession and that attachProjectWorkspaceSessions
documents the ordering behavior (uses createdAt sort) and selection side-effects
(calls args.addTerminalSession and args.selectTerminalSession).
In `@packages/app/tests/docker-git/actions-projects.test.ts`:
- Around line 49-54: Move the global unstub call out of the beforeEach and into
an afterEach to ensure global stubs (e.g., confirm) are removed after each test
run; specifically, remove vi.unstubAllGlobals() from the beforeEach block that
currently contains vi.restoreAllMocks(), applyAllProjectsMock.mockReset(),
applyProjectMock.mockReset() and instead call vi.unstubAllGlobals() inside an
afterEach so globals do not leak between tests/files.
In `@packages/app/tests/docker-git/menu-create-shared.test.ts`:
- Around line 92-100: Replace the two fixed-case tests with fast-check property
tests: for the long outDir case, use fc.property to generate a range of
directory name patterns/lengths (e.g., repeated segments) and assert that
advanceCreateFlow(createInitialFlowView(`${featureCreateRepoUrl} --out-dir
"${longOutDir}"`)) passed into expectCreateContinueView yields
view.values.outDir === generated outDir; for the "single remaining step" case,
use fc.property to generate valid partial CreateInputs and feed them into
createInitialFlowView/advanceCreateFlow and assert the flow completes directly
(e.g., expectCreateContinueView returns a terminal view), ensuring you import
fast-check (fc) and constrain generators to valid inputs used by
advanceCreateFlow and CreateInputs.
---
Outside diff comments:
In `@packages/app/src/docker-git/menu-create-advance.ts`:
- Around line 268-315: advanceCreateFlow currently treats applying the last
settings-step as "Continue" because when resolveNextCreateFlowStep returns
nextStep === nextSteps.length the code falls through and clamps back to
nextSteps.length - 1; change the logic so that if nextStep >= nextSteps.length
(or nextStep === nextSteps.length) you call completeCreateFlow(context,
nextValues) instead of returning continueCreateFlow. Update the branch in
advanceCreateFlow that computes nextStep (using resolveNextCreateFlowStep) to
check for nextStep >= nextSteps.length before clamping/continuing and call
completeCreateFlow; keep existing use of shouldCompleteCreateFlow(nextSteps) and
clampCreateSettingsStep for other cases.
In `@packages/app/src/web/actions-project-terminal.ts`:
- Around line 173-185: The function showPendingTerminalError currently sets
runtime.pendingSessionFinalized and only guards lifecycle.onFailure, but still
writes to the output and adds an error tab even when the pending session was
already finalized; change showPendingTerminalError so that after reading/setting
wasFinalized on runtime.pendingSessionFinalized it returns early when
wasFinalized is true (i.e., do not call appendOutputLine or
context.addTerminalSession) while still invoking lifecycle.onFailure only once;
locate showPendingTerminalError and adjust its control flow around
runtime.pendingSessionFinalized, lifecycle.onFailure, appendOutputLine,
context.addTerminalSession and renderPendingTerminalSession accordingly.
In `@packages/app/src/web/app-ready-ssh-link-hook.ts`:
- Around line 83-118: The onSuccess/onFailure branches must guard against stale
async results: at the top of each branch in the Effect.match for
loadTerminalSessionById (the block containing markSshLinkHandled,
clearPendingSshLink, requestKey and args.handledTokenRef.current), check that
the incoming requestKey matches the current pending/handled token (e.g.
args.handledTokenRef.current or your pending SSH-link ref) and early-return if
it does not; only proceed to call markSshLinkHandled, clearPendingSshLink,
history.replaceState, showProjectTerminalScreen, args.addTerminalSession and
args.actionContext.setMessage when the keys match so late responses cannot
overwrite UI state.
In `@packages/app/tests/docker-git/actions-projects.test.ts`:
- Around line 13-24: Replace the module-level vi.mock() usage that patches
"../../src/web/api.js" (and the similar mocks around lines 44-45) with
test-scoped mocks provided via the project's Effect/DI utilities: create a
MockLayer/Layer that binds the Context.Tag for the web api to a mocked
implementation (using applyAllProjectsMock, applyProjectMock, deleteProject,
etc.), and then provide that layer to the test runtime instead of calling
vi.mock(); update tests to import and use the Context.Tag and the
Layer/MockLayer factory so the api functions are injected via the DI boundary
rather than global module monkey-patching.
🪄 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: aa922468-2de9-4e27-bfdb-baaa8def86d5
📒 Files selected for processing (13)
packages/app/src/docker-git/menu-create-advance.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/menu-create-shared.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.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/app/src/web/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.test.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/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.test.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/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.test.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/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.test.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.test.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/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-test-fixtures.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-command-parse.tspackages/app/src/docker-git/menu-create-navigation.tspackages/app/src/docker-git/menu-create-flow-types.tspackages/app/src/web/terminal-panel-inline-images-runtime.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/terminal-copy-interaction.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.tspackages/app/tests/docker-git/actions-projects.test.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/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/tests/docker-git/actions-projects.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/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/tests/docker-git/actions-projects.test.ts
🔇 Additional comments (10)
packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts (1)
1-54: LGTM!packages/app/src/docker-git/menu-create-command-parse.ts (1)
73-85: LGTM!packages/app/src/docker-git/menu-create-navigation.ts (1)
12-289: LGTM!packages/app/src/docker-git/menu-create-flow-types.ts (1)
50-123: LGTM!packages/app/src/web/terminal-panel-inline-images-runtime.ts (1)
267-299: LGTM!packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts (1)
1-256: LGTM!packages/app/src/web/actions-project-terminal.ts (1)
14-17: LGTM!Also applies to: 19-45, 126-149, 205-214, 278-320
packages/app/src/web/terminal-copy-interaction.ts (1)
68-95: LGTM!packages/app/src/web/app-ready-ssh-link-hook.ts (1)
67-73: LGTM!Also applies to: 249-314
packages/app/tests/docker-git/actions-projects.test.ts (1)
3-7: LGTM!
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/web/actions-project-terminal.ts`:
- Around line 179-183: The current handler sets runtime.pendingSessionFinalized
= true and calls runtime.lifecycle.onFailure?.(error) when wasFinalized is
false, but the caller still unconditionally executes setMessage(failure),
allowing a late "ssh.failed" to overwrite a previously successful state; fix
this by gating the caller's failure path with the same finalized flag—before
calling setMessage(failure) (and any other failure-side effects), check
runtime.pendingSessionFinalized (or the return value from the handler) and skip
setMessage(failure) when pendingSessionFinalized is true so late events cannot
overwrite a finalized 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: a57de27f-f75b-4445-937d-c02047cf1ad3
📒 Files selected for processing (7)
packages/app/src/docker-git/menu-create-advance.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/menu-create-shared.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 (Clone cache)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.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/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.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/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.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/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.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/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.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/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.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/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/actions-projects.test.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/app-ready-ssh-link-terminal.tspackages/app/src/web/actions-project-terminal.tspackages/app/src/web/app-ready-ssh-link-hook.tspackages/app/src/docker-git/menu-create-advance.ts
🔇 Additional comments (7)
packages/app/tests/docker-git/menu-create-shared.test.ts (1)
92-105: LGTM!Also applies to: 258-277, 279-315
packages/app/tests/docker-git/actions-projects.test.ts (1)
3-3: LGTM!Also applies to: 53-57
packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts (1)
48-60: LGTM!Also applies to: 86-112, 222-238, 276-277
packages/app/src/web/app-ready-ssh-link-terminal.ts (1)
17-30: LGTM!Also applies to: 31-55, 64-103, 105-184
packages/app/src/web/actions-project-terminal.ts (1)
269-271: LGTM!Also applies to: 311-315
packages/app/src/web/app-ready-ssh-link-hook.ts (1)
72-73: LGTM!Also applies to: 76-77, 83-117, 177-186
packages/app/src/docker-git/menu-create-advance.ts (1)
269-271: LGTM!Also applies to: 311-315
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/app/src/web/actions-project-terminal.ts (1)
325-346: 🧹 Nitpick | 🔵 Trivial | 💤 Low valueОтсутствует TSDoc для экспортируемой функции
attachProjectTerminalById.Согласно coding guidelines, все функции должны иметь TSDoc с
@pure,@effect,@invariant,@precondition,@postcondition,@complexity,@throws Never. ФункцияconnectProjectByIdзадокументирована корректно, ноattachProjectTerminalById— нет.📝 Предлагаемое добавление TSDoc
+/** + * Attaches an existing SSH terminal session to the browser UI. + * + * `@param` projectId - Project identifier. + * `@param` projectKey - Project key for API calls. + * `@param` projectDisplayName - Human-readable project name for UI messages. + * `@param` sessionId - Existing terminal session identifier to attach. + * `@param` context - Browser action context used for state updates. + * `@returns` Nothing; state changes are emitted through `context`. + * `@pure` false + * `@effect` BrowserActionContext, loadProjectTerminalSession Effect. + * `@invariant` Terminal session is added only on successful load. + * `@precondition` `sessionId` identifies an existing terminal session. + * `@postcondition` On success, terminal session is added to context. + * `@complexity` O(1) setup plus O(1) API call. + * `@throws` Never + */ export const attachProjectTerminalById = (🤖 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/web/actions-project-terminal.ts` around lines 325 - 346, Add a TSDoc comment block above the exported function attachProjectTerminalById that mirrors the project's TSDoc requirements (include `@pure`, `@effect`, `@invariant`, `@precondition`, `@postcondition`, `@complexity`, and `@throws` Never) and briefly describe the function's purpose, parameters (projectId, projectKey, projectDisplayName, sessionId, context), side effects (calls resolveProjectTerminalKey, sets selected project, invokes withBusy/loadProjectTerminalSession, calls addProjectTerminalSession, sets a message) and any invariants or preconditions (e.g., resolvedProjectKey !== null). Use the existing connectProjectById TSDoc as a template for wording and tag usage so format and content are consistent with the codebase.
🤖 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.
Outside diff comments:
In `@packages/app/src/web/actions-project-terminal.ts`:
- Around line 325-346: Add a TSDoc comment block above the exported function
attachProjectTerminalById that mirrors the project's TSDoc requirements (include
`@pure`, `@effect`, `@invariant`, `@precondition`, `@postcondition`, `@complexity`, and
`@throws` Never) and briefly describe the function's purpose, parameters
(projectId, projectKey, projectDisplayName, sessionId, context), side effects
(calls resolveProjectTerminalKey, sets selected project, invokes
withBusy/loadProjectTerminalSession, calls addProjectTerminalSession, sets a
message) and any invariants or preconditions (e.g., resolvedProjectKey !==
null). Use the existing connectProjectById TSDoc as a template for wording and
tag usage so format and content are consistent with the codebase.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: fb894933-d035-4e03-a65e-a01a374ba152
📒 Files selected for processing (2)
packages/app/src/web/actions-project-terminal.tspackages/app/tests/docker-git/actions-project-terminal-lifecycle.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). (1)
- GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{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/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.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/app/tests/docker-git/actions-project-terminal-lifecycle.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/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.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/app/tests/docker-git/actions-project-terminal-lifecycle.test.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/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.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/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.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/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.ts
packages/app/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (README.md)
App layer (APP) should work only with API and not have direct access to LIB layer
Files:
packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.tspackages/app/src/web/actions-project-terminal.ts
🔇 Additional comments (6)
packages/app/src/web/actions-project-terminal.ts (4)
48-81: LGTM!
177-186: LGTM!
227-240: LGTM!
1-47: LGTM!Also applies to: 83-149, 151-167, 189-219, 242-279, 307-323
packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts (2)
226-242: LGTM!
1-127: LGTM!Also applies to: 129-189, 191-214, 216-224, 244-286
Summary
Verification
Closes #339
Closes #340