[codex] keep Create settings visible#316
Conversation
📝 WalkthroughSummary by CodeRabbit
<review_stack_artifact> </review_stack_artifact> 🚥 Pre-merge checks | ✅ 7✅ Passed checks (7 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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-shared.ts`:
- Around line 46-50: Add formal TSDoc comments for the exported navigation API:
CreateSettingsNavigationDirection, createSettingsHint, and
moveCreateSettingsStep; the docs must state invariants (valid values for
CreateSettingsNavigationDirection and that moveCreateSettingsStep never moves
outside [firstCreateSettingsStepIndex, lastStep]), preconditions (e.g., valid
current index and non-empty steps), postconditions (resulting index and side
effects), mark pure or impure with `@pure/`@effect as appropriate, and include
`@complexity` (Big-O) and any `@invariant` mathematical relations. Reference the
symbols CreateSettingsNavigationDirection, createSettingsHint,
moveCreateSettingsStep (and firstCreateSettingsStepIndex where relevant) in the
TSDoc so callers and automated checks can validate behavior.
In `@packages/app/tests/docker-git/create-flow-render.test.ts`:
- Around line 63-86: Add a fast-check property test that asserts the invariant:
renderCreatePanel(view) contains createSettingsHint if and only if view.step > 0
for all valid CreateFlowView instances; implement this using fast-check (import
fc) and fc.assert(fc.property(...)) with a generator that produces valid
CreateFlowView objects (or derive from existing helpers like
createInitialFlowView/createSettingsView for seeds), then call
renderCreatePanel(view) and assert (html.includes(createSettingsHint)) ===
(view.step > 0); include the test alongside the existing tests in this file and
reference CreateFlowView, renderCreatePanel, createSettingsHint,
createInitialFlowView/createSettingsView when locating code to modify.
In `@packages/app/tests/docker-git/menu-create-shared.test.ts`:
- Around line 142-199: Add property-based tests (using fast-check) around
moveCreateSettingsStep/advanceCreateFlow/createInitialFlowView to validate three
invariants at scale: 1) wraparound navigation (moving "up" from step 1 wraps to
last settings step and "down" from last wraps to 1), 2) navigation is forbidden
when step === 0 (calls return null), and 3) buffer is cleared only when the
returned view's step differs from the input view's step (i.e., buffer becomes ""
iff step changed). Generate random valid flow views (use
createInitialFlowView/advanceCreateFlow to reach settings region and vary
buffer/step) and assert these properties for both "up" and "down" moves; also
use resolveCreateFlowSteps to verify the set of unresolved steps remains
consistent after navigation where appropriate.
In `@packages/app/tests/docker-git/menu-create.test.ts`:
- Around line 39-61: Add property-based tests using fast-check to verify
invariants for handleCreateInput: test wraparound behavior when
incrementing/decrementing step, ensure arrows are ignored when view.step === 0,
and assert buffer is cleared whenever step changes; replace example-only tests
in menu-create.test.ts by parameterized fast-check properties (referencing
handleCreateInput, createContext, createSettingsView) and implement unit checks
using the repository's Effect test utilities (not async/await) so assertions
call the Effect-based test runner and mocks like
context.setViewMock/context.setMessageMock are asserted via those utilities.
🪄 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: c0a13a13-19a6-4bdc-81aa-c82284a48ce3
📒 Files selected for processing (11)
packages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/menu-create.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). (9)
- GitHub Check: E2E (Login context)
- GitHub Check: Test
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: Lint
- GitHub Check: E2E (Clone cache)
- GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-render.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-create.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/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-render.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-create.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/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-render.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-create.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/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-render.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-create.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/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-render.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-create.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/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-render.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-create.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/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.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/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.ts
🔇 Additional comments (7)
packages/app/src/web/actions-projects.ts (1)
451-451: LGTM!packages/app/src/web/app-ready-url.ts (1)
91-91: LGTM!packages/app/src/web/app-ready-create.ts (1)
9-10: LGTM!Also applies to: 113-122
packages/app/src/web/panel-create-select.tsx (1)
6-6: LGTM!Also applies to: 110-120, 166-167
packages/app/tests/docker-git/app-ready-create.test.ts (1)
14-14: LGTM!Also applies to: 120-130, 162-209
packages/app/src/docker-git/menu-create.ts (1)
14-14: LGTM!Also applies to: 182-183, 196-203
packages/app/src/docker-git/menu-render.ts (1)
4-4: LGTM!Also applies to: 123-123, 133-144
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/tests/docker-git/app-ready-create.test.ts`:
- Around line 179-209: Add a new test case that mirrors the existing "moves
between settings with arrows and clears the uncommitted buffer" but uses
createKeyEvent("ArrowUp") to exercise the other branch of handleCreateKey;
instantiate the same CreateFlowView (with step: 1 and buffer: "30%"), call
handleCreateKey with the same context/controllerCwd/projectsRoot/setCreateView
spy, and assert the returned handled is true, event.preventDefault was called
once, setCreateView was called with the view having step adjusted (to the
expected value for ArrowUp) and buffer cleared (""), and context.setMessage was
called with null; reference handleCreateKey, createKeyEvent, CreateFlowView,
setCreateViewSpy and requireCreateViewValue when adding the test.
In `@packages/app/tests/docker-git/create-flow-render.test.ts`:
- Around line 39-40: The property-based test currently hardcodes the step range
(0..6); change it to derive the upper bound from the actual flow definition by
calling resolveCreateFlowSteps(...) and using its length minus one as the max
step, then generate create views via createViewForStep(step) (which uses
createInitialFlowView and createSettingsView) so the invariant adapts when
create-flow steps change; update the fast-check Arbitrary or integer bounds to
use that computed max instead of 6.
In `@packages/app/tests/docker-git/menu-create-shared.test.ts`:
- Around line 44-49: The property-based test uses hardcoded step bounds (1..6)
in expectedSettingsStep; replace those literals by deriving min/max from the
actual createSteps length so the wrap-around logic adapts to changes. Update the
expectedSettingsStep implementation to compute the lastIndex (e.g.,
createSteps.length or the variable that defines number of settings) and use that
instead of 6 and 1, and make the alternative branch use 0..lastIndex-1 or
1..lastIndex consistently; apply the same change to the other occurrence
referenced around lines 54-56 so both instances reference the dynamic
createSteps length rather than fixed bounds.
- Line 55: Remove the `as const` type assertion from the
`settingsDirectionArbitrary` declaration and replace it with a generic type
parameter on `fc.constantFrom` to preserve literal types without using `as`;
locate the `settingsDirectionArbitrary` constant and change the call to
`fc.constantFrom` to explicitly provide the union literal generic (e.g., `<"up"
| "down">`) so the arbitrary remains type-safe without `as const`.
🪄 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: b5681e85-2c73-4ef4-a8db-3f1faef64b02
📒 Files selected for processing (11)
packages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/menu-create.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). (13)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Local package CLI)
- GitHub Check: Types
- GitHub Check: Lint Effect-TS
- GitHub Check: Test
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: Lint
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Browser command)
- GitHub Check: Snapshot
- GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/panel-create-select.tsx
**/*.{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/actions-projects.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/panel-create-select.tsx
**/*.{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/actions-projects.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/panel-create-select.tsx
**/*.{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/actions-projects.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/panel-create-select.tsx
**/*.{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/actions-projects.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/panel-create-select.tsx
**/*
⚙️ 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/actions-projects.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/panel-create-select.tsx
**/*.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/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.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/app-ready-create.test.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.ts
🔇 Additional comments (10)
packages/app/src/docker-git/menu-create.ts (1)
14-16: LGTM!Also applies to: 182-203
packages/app/tests/docker-git/menu-create.test.ts (1)
53-100: LGTM!packages/app/src/web/app-ready-create.ts (1)
9-10: LGTM!Also applies to: 113-122
packages/app/tests/docker-git/app-ready-create.test.ts (1)
14-15: LGTM!Also applies to: 120-130, 162-177
packages/app/src/web/app-ready-url.ts (1)
91-91: LGTM!packages/app/src/web/actions-projects.ts (1)
451-451: LGTM!packages/app/src/docker-git/menu-create-shared.ts (1)
46-70: LGTM!Also applies to: 491-549, 587-588
packages/app/tests/docker-git/menu-create-shared.test.ts (1)
152-237: LGTM!packages/app/src/docker-git/menu-render.ts (1)
4-4: LGTM!Also applies to: 123-124, 133-144
packages/app/src/web/panel-create-select.tsx (1)
6-6: LGTM!Also applies to: 110-120, 166-167
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/tests/docker-git/app-ready-create.test.ts`:
- Around line 179-209: Add a test for the "null" arrow-branch in the web
handler: create a CreateFlowView with step: 0 (settings mode starting state),
fire the same createKeyEvent("ArrowDown") and call handleCreateKey with the same
context/controllerCwd/projectsRoot and a spy for setCreateView (like
setCreateViewSpy), then assert that handled is false and that
event.preventDefault and setCreateView were not called (and context.setMessage
was not changed); this mirrors the existing ArrowDown test but verifies the
step:0 path returns false and does not mutate state.
🪄 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: 376a6349-ddf1-4d6f-af3c-9a2025c2364e
📒 Files selected for processing (11)
packages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/menu-create.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/web/actions-projects.tspackages/app/src/docker-git/menu-render.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/create-flow-render.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/actions-projects.tspackages/app/src/docker-git/menu-render.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/create-flow-render.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/actions-projects.tspackages/app/src/docker-git/menu-render.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/create-flow-render.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/actions-projects.tspackages/app/src/docker-git/menu-render.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/create-flow-render.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/actions-projects.tspackages/app/src/docker-git/menu-render.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/create-flow-render.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/actions-projects.tspackages/app/src/docker-git/menu-render.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/app-ready-url.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/panel-create-select.tsxpackages/app/src/docker-git/menu-create-shared.tspackages/app/tests/docker-git/create-flow-render.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.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/create-flow-render.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.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/create-flow-render.test.ts
🔇 Additional comments (10)
packages/app/tests/docker-git/create-flow-render.test.ts (1)
93-93: Дубликат: уберите хардкод верхней границы шага в property-тесте.На Line 93 значение
max: 6остаётся хрупким — при добавлении/удалении шагов инвариант начнёт проверяться неполно.As per coding guidelines
**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants.packages/app/src/docker-git/menu-render.ts (1)
4-4: LGTM!Also applies to: 123-124, 133-144
packages/app/src/web/panel-create-select.tsx (1)
6-6: LGTM!Also applies to: 110-120, 166-167
packages/app/src/docker-git/menu-create.ts (1)
14-16: LGTM!Also applies to: 180-203
packages/app/tests/docker-git/menu-create.test.ts (1)
1-100: LGTM!packages/app/src/web/actions-projects.ts (1)
451-451: LGTM!packages/app/src/web/app-ready-url.ts (1)
91-91: LGTM!packages/app/tests/docker-git/menu-create-shared.test.ts (2)
44-49: Жёстко прошитые границы (1..6) делают тесты хрупкими.Проблема остаётся с прошлого ревью:
expectedSettingsStepиsettingsStepIndexArbitraryсодержат магические числа 1 и 6, привязанные к текущему количеству settings-шагов. При добавлении/удалении шагов вcreateStepsтесты сломаются.Рекомендуемое исправление
+const computeLastSettingsStep = (): number => { + const view = expectContinueResult( + advanceCreateFlow(process.cwd(), createInitialFlowView("https://github.com/org/repo")) + ) + return resolveCreateFlowSteps(view.values).length - 1 +} + -const expectedSettingsStep = (step: number, direction: "up" | "down"): number => { +const expectedSettingsStep = (step: number, lastStep: number, direction: "up" | "down"): number => { if (direction === "up") { - return step === 1 ? 6 : step - 1 + return step === 1 ? lastStep : step - 1 } - return step === 6 ? 1 : step + 1 + return step === lastStep ? 1 : step + 1 } describe("menu-create-shared", () => { const cwd = process.cwd() const defaultRoot = `${process.env["HOME"] ?? cwd}/.docker-git/org/repo` - const settingsStepIndexArbitrary = fc.integer({ min: 1, max: 6 }) + const lastSettingsStep = computeLastSettingsStep() + const settingsStepIndexArbitrary = fc.integer({ min: 1, max: lastSettingsStep })Also applies to: 54-54
152-236: LGTM!packages/app/src/docker-git/menu-create-shared.ts (1)
46-70: LGTM!Also applies to: 491-548, 587-588
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/menu-create-shared.test.ts (1)
80-124: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winДобавьте тест на комбинацию
quickCreateи inline-флагов.Сейчас эти ветки проверяются по отдельности, но не их пересечение. Это как раз тот путь, где
advanceCreateFlowсначала парсит repo-step флаги, а потом может сделать раннийComplete, поэтому регрессия здесь тихо сломает сохранение--force/--no-up/--mcp-playwright.Пример минимального теста
+ it("quick-creates from repo URL while preserving inline flags", () => { + const inputs = expectCompleteResult(advanceCreateFlow( + cwd, + createInitialFlowView( + "https://github.com/org/repo/tree/feature-x --force --mcp-playwright --no-up" + ), + { quickCreate: true } + )) + + expectFeatureRepoDefaults(inputs, defaultRoot) + expect(inputs.force).toBe(true) + expect(inputs.enableMcpPlaywright).toBe(true) + expect(inputs.runUp).toBe(false) + })As per coding guidelines "Флагай любой уход от спеки, недокументированное изменение поведения, отсутствие тестов для заявленного поведения".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/app/tests/docker-git/menu-create-shared.test.ts` around lines 80 - 124, Add a new test that covers the intersection of quickCreate and inline CLI flags: call advanceCreateFlow with createInitialFlowView containing the repo URL plus inline flags (e.g. "--force --mcp-playwright --no-up") and pass { quickCreate: true } to simulate the quick-create path, then assert that advanceCreateFlow returns a completed result (use expectCompleteResult), that expectFeatureRepoDefaults(inputs, defaultRoot) still holds, and that inputs.force === true, inputs.enableMcpPlaywright === true and inputs.runUp === false; reference advanceCreateFlow, createInitialFlowView, expectCompleteResult and expectFeatureRepoDefaults when locating where to add the new test.
🤖 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/menu-create-shared.test.ts`:
- Around line 80-124: Add a new test that covers the intersection of quickCreate
and inline CLI flags: call advanceCreateFlow with createInitialFlowView
containing the repo URL plus inline flags (e.g. "--force --mcp-playwright
--no-up") and pass { quickCreate: true } to simulate the quick-create path, then
assert that advanceCreateFlow returns a completed result (use
expectCompleteResult), that expectFeatureRepoDefaults(inputs, defaultRoot) still
holds, and that inputs.force === true, inputs.enableMcpPlaywright === true and
inputs.runUp === false; reference advanceCreateFlow, createInitialFlowView,
expectCompleteResult and expectFeatureRepoDefaults when locating where to add
the new test.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 18a942e5-e2b7-459c-9608-714e1be7c48f
📒 Files selected for processing (11)
packages/app/src/docker-git/menu-create-shared.tspackages/app/src/docker-git/menu-create.tspackages/app/src/docker-git/menu-render.tspackages/app/src/web/actions-projects.tspackages/app/src/web/app-ready-create.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/menu-create.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 (Login context)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: Lint
- GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/docker-git/menu-render.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/app-ready-create.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/actions-projects.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.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-render.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/app-ready-create.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/actions-projects.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.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-render.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/app-ready-create.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/actions-projects.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.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-render.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/app-ready-create.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/actions-projects.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.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-render.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/app-ready-create.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/actions-projects.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.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-render.tspackages/app/src/web/app-ready-url.tspackages/app/src/web/app-ready-create.tspackages/app/src/docker-git/menu-create.tspackages/app/src/web/actions-projects.tspackages/app/tests/docker-git/menu-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/src/web/panel-create-select.tsxpackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/src/docker-git/menu-create-shared.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.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.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.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/menu-create-shared.test.ts
🔇 Additional comments (12)
packages/app/tests/docker-git/create-flow-render.test.ts (1)
1-108: LGTM!packages/app/src/docker-git/menu-create.ts (1)
14-16: LGTM!Also applies to: 182-203
packages/app/src/docker-git/menu-render.ts (1)
4-5: LGTM!Also applies to: 123-124, 133-144
packages/app/tests/docker-git/menu-create.test.ts (1)
1-106: LGTM!packages/app/src/docker-git/menu-create-shared.ts (1)
46-68: LGTM!Also applies to: 491-588
packages/app/tests/docker-git/menu-create-shared.test.ts (1)
44-59: LGTM!Also applies to: 155-241
packages/app/tests/docker-git/app-ready-create.test.ts (2)
216-222: Добавьте тест для null-ветки стрелок на repo step (step=0).Сейчас покрыт только успешный переход в settings-mode; нужен отдельный кейс, где на Line 216+ при
step = 0обработчик возвращаетfalseи не вызываетpreventDefault/setCreateView.
14-15: LGTM!Also applies to: 120-167, 199-214
packages/app/src/web/app-ready-create.ts (1)
9-10: LGTM!Also applies to: 113-122
packages/app/src/web/panel-create-select.tsx (1)
6-6: LGTM!Also applies to: 115-120, 166-167
packages/app/src/web/app-ready-url.ts (1)
91-91: LGTM!packages/app/src/web/actions-projects.ts (1)
451-451: LGTM!
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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/program-auth.ts`:
- Around line 50-52: The generic type parameter E on withControllerReady is
redundant; change its signature to remove E and accept Effect.Effect<void,
CliError, R> (i.e. withControllerReady<R>(effect: Effect.Effect<void, CliError,
R>): Effect.Effect<void, CliError, ControllerRuntime | R>), keep the documented
return union ControllerRuntime | R, and ensure usage sites passing effects typed
with CliError still compile; update the declaration of withControllerReady and
any type annotations that referenced the removed generic while keeping the call
to ensureControllerReady() and the Effect.zipRight composition.
- Around line 112-121: Add comprehensive TSDoc to the new
attachGrokAuthTerminalSession function: document that it lives in the SHELL
layer and performs effects, mark `@pure` false, list required services under
`@effect` (e.g., any Env/clients used by attachTerminalSession or logging),
include `@complexity` (time/space), `@param` for session, `@returns` describing
Effect.Effect<void, CliError>, and `@throws` Never (errors are encoded in the
Effect); also add `@precondition/`@postcondition/@invariant as appropriate and
mention the failure branch that calls Effect.fail with
missingAuthTerminalSessionError and the success branch that delegates to
attachTerminalSession so reviewers can quickly find the behavior.
In `@packages/app/tests/docker-git/app-ready-create-fixture.ts`:
- Around line 39-42: The current githubSegmentArbitrary uses .filter(...) which
can hurt fast-check performance; change it to directly generate valid strings by
producing a tuple of (firstCharWithoutDash, middleChars, lastCharWithoutDash)
using githubNameCharArbitrary for middle chars and a generator that picks from
githubNameChars excluding '-' for first and last, then map the tuple into the
final string (joining middle and concatenating first+middle+last, handling the
single-char case). Update the generator referenced as githubSegmentArbitrary and
reuse githubNameCharArbitrary and githubNameChars to create the constant-from
style generators for the first/last positions so no post-generation filter is
needed.
- Around line 29-259: Add comprehensive TSDoc blocks to every exported constant
and function in this file (e.g. validGithubStatus,
repositoryCreateInputArbitrary, createSetCreateViewSpy, requireCreateViewValue,
submitCreateBuffer, requireSubmittedCreateInputs, expectQuickCreateInputs,
expectCreateViewReset, createSubmitCreateBuffer, expectedOutDirForRepoUrl,
createKeyEvent, createSettingsFlowView, createSettingsFlowViewAtStep,
expectCreateArrowHandling, expectCreateSideArrowBufferHandling,
expectEmptyRepoInlineError and any others exported) describing purpose,
parameters and return values; include required metadata tags from the coding
guidelines: `@pure` (use false for test helpers with side effects), `@effect`
(services used), `@invariant`, `@precondition`, `@postcondition`, `@complexity` (time
and space), and `@throws` Never, and for each function add `@param` entries for each
parameter and `@returns` description — place each TSDoc immediately above the
corresponding export.
In `@packages/app/tests/docker-git/menu-create-display-settings.test.ts`:
- Around line 16-45: В тестах дублируются helpers expectContinueResult,
expectCompleteResult и viewForStep — вынеси их из menu-create-shared.test.ts и
menu-create-display-settings.test.ts в общий экспорт в
app-ready-create-fixture.ts и импортируй в оба теста; оставь реализацию функций
такой же (они используют advanceCreateFlow, resolveCreateDisplaySteps и тип
CreateStep), убедись что экспорты/импорты корректно названы и обновь импорты в
файлах menu-create-shared.test.ts и menu-create-display-settings.test.ts.
🪄 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: c2385943-50e5-49ef-a4d5-b327c38032b5
📒 Files selected for processing (8)
packages/app/src/docker-git/program-auth.tspackages/app/src/web/app-ready-terminal-screen.tsxpackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-display-settings.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 (Clone auto-open SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Runtime volumes + SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/src/web/app-ready-terminal-screen.tsxpackages/app/src/docker-git/program-auth.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create-fixture.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-terminal-screen.tsxpackages/app/src/docker-git/program-auth.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create-fixture.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-terminal-screen.tsxpackages/app/src/docker-git/program-auth.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create-fixture.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-terminal-screen.tsxpackages/app/src/docker-git/program-auth.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create-fixture.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-terminal-screen.tsxpackages/app/src/docker-git/program-auth.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create-fixture.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-terminal-screen.tsxpackages/app/src/docker-git/program-auth.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/app-ready-create-fixture.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-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.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-display-settings.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.ts
🔇 Additional comments (24)
packages/app/tests/docker-git/create-flow-render.test.ts (1)
1-257: LGTM!packages/app/src/docker-git/program-auth.ts (1)
28-28: LGTM!Also applies to: 160-160
packages/app/src/web/app-ready-terminal-screen.tsx (1)
12-12: LGTM!Also applies to: 524-524
packages/app/tests/docker-git/app-ready-create.test.ts (5)
23-32: LGTM!
64-79: LGTM!
81-117: LGTM!
119-155: LGTM!
171-171: LGTM!Also applies to: 186-186
packages/app/tests/docker-git/app-ready-create-settings.test.ts (11)
1-32: LGTM!
39-45: LGTM!
47-67: LGTM!
69-101: LGTM!
103-133: LGTM!
135-164: LGTM!
166-185: LGTM!
187-203: LGTM!
205-221: LGTM!
223-240: LGTM!
242-270: LGTM!packages/app/tests/docker-git/menu-create-shared.test.ts (3)
194-211: LGTM!
217-224: LGTM!
226-240: LGTM!packages/app/tests/docker-git/menu-create-display-settings.test.ts (2)
50-69: LGTM!Also applies to: 71-83, 85-101
130-158: LGTM!
| const withControllerReady = <E extends CliError, R>( | ||
| effect: Effect.Effect<void, E, R> | ||
| ): Effect.Effect<void, CliError, ControllerRuntime | R> => pipe(ensureControllerReady(), Effect.zipRight(effect)) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Упростите сигнатуру withControllerReady, убрав избыточный параметр типа.
Параметр типа E extends CliError не добавляет ценности, поскольку возвращаемый тип сразу расширяет ошибку до CliError. Все вызывающие функции уже передают эффекты с типом ошибки CliError, а композиция с ensureControllerReady() в любом случае приводит к CliError в результате.
♻️ Предлагаемое упрощение
-const withControllerReady = <E extends CliError, R>(
- effect: Effect.Effect<void, E, R>
+const withControllerReady = <R>(
+ effect: Effect.Effect<void, CliError, R>
): Effect.Effect<void, CliError, ControllerRuntime | R> => pipe(ensureControllerReady(), Effect.zipRight(effect))Явная аннотация возвращаемого типа с ControllerRuntime | R сохраняется для документирования объединения требований.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/app/src/docker-git/program-auth.ts` around lines 50 - 52, The
generic type parameter E on withControllerReady is redundant; change its
signature to remove E and accept Effect.Effect<void, CliError, R> (i.e.
withControllerReady<R>(effect: Effect.Effect<void, CliError, R>):
Effect.Effect<void, CliError, ControllerRuntime | R>), keep the documented
return union ControllerRuntime | R, and ensure usage sites passing effects typed
with CliError still compile; update the declaration of withControllerReady and
any type annotations that referenced the removed generic while keeping the call
to ensureControllerReady() and the Effect.zipRight composition.
| const attachGrokAuthTerminalSession = ( | ||
| session: ApiTerminalSession | null | ||
| ): Effect.Effect<void, CliError> => | ||
| session === null | ||
| ? Effect.fail(missingAuthTerminalSessionError("GrokOauth")) | ||
| : attachTerminalSession({ | ||
| header: terminalAuthTitle("GrokOauth"), | ||
| session, | ||
| websocketPath: `/auth/terminal-sessions/${encodeURIComponent(session.id)}/ws` | ||
| }) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Добавьте TSDoc-документацию для новой функции.
Согласно coding guidelines, все функции в TypeScript должны иметь комплексную TSDoc-документацию, включая @pure (true/false), @effect (требуемые сервисы), @complexity и описание параметров. Функция attachGrokAuthTerminalSession представляет SHELL-слой (выполняет эффекты) и должна быть документирована.
📝 Предлагаемая документация
+/**
+ * Attaches a Grok OAuth terminal session for interactive authentication.
+ *
+ * `@param` session - Terminal session created by the controller, or null if creation failed
+ * `@returns` Effect that attaches the terminal session or fails with ApiRequestError
+ *
+ * `@pure` false
+ * `@effect` Requires terminal session attachment capability
+ * `@complexity` O(1) time, O(1) space
+ */
const attachGrokAuthTerminalSession = (
session: ApiTerminalSession | null
): Effect.Effect<void, CliError> =>As per coding guidelines: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect)."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const attachGrokAuthTerminalSession = ( | |
| session: ApiTerminalSession | null | |
| ): Effect.Effect<void, CliError> => | |
| session === null | |
| ? Effect.fail(missingAuthTerminalSessionError("GrokOauth")) | |
| : attachTerminalSession({ | |
| header: terminalAuthTitle("GrokOauth"), | |
| session, | |
| websocketPath: `/auth/terminal-sessions/${encodeURIComponent(session.id)}/ws` | |
| }) | |
| /** | |
| * Attaches a Grok OAuth terminal session for interactive authentication. | |
| * | |
| * `@param` session - Terminal session created by the controller, or null if creation failed | |
| * `@returns` Effect that attaches the terminal session or fails with ApiRequestError | |
| * | |
| * `@pure` false | |
| * `@effect` Requires terminal session attachment capability | |
| * `@complexity` O(1) time, O(1) space | |
| */ | |
| const attachGrokAuthTerminalSession = ( | |
| session: ApiTerminalSession | null | |
| ): Effect.Effect<void, CliError> => | |
| session === null | |
| ? Effect.fail(missingAuthTerminalSessionError("GrokOauth")) | |
| : attachTerminalSession({ | |
| header: terminalAuthTitle("GrokOauth"), | |
| session, | |
| websocketPath: `/auth/terminal-sessions/${encodeURIComponent(session.id)}/ws` | |
| }) |
🤖 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/program-auth.ts` around lines 112 - 121, Add
comprehensive TSDoc to the new attachGrokAuthTerminalSession function: document
that it lives in the SHELL layer and performs effects, mark `@pure` false, list
required services under `@effect` (e.g., any Env/clients used by
attachTerminalSession or logging), include `@complexity` (time/space), `@param` for
session, `@returns` describing Effect.Effect<void, CliError>, and `@throws` Never
(errors are encoded in the Effect); also add
`@precondition/`@postcondition/@invariant as appropriate and mention the failure
branch that calls Effect.fail with missingAuthTerminalSessionError and the
success branch that delegates to attachTerminalSession so reviewers can quickly
find the behavior.
| export const validGithubStatus: GithubAuthStatus = { | ||
| summary: "valid", | ||
| tokens: [{ key: "default", label: "default", login: "octocat", status: "valid" }] | ||
| } | ||
|
|
||
| const githubNameChars = "abcdefghijklmnopqrstuvwxyz0123456789-" | ||
| const githubNameCharArbitrary = fc | ||
| .integer({ min: 0, max: githubNameChars.length - 1 }) | ||
| .map((index) => githubNameChars[index] ?? "a") | ||
|
|
||
| const githubSegmentArbitrary = fc | ||
| .array(githubNameCharArbitrary, { minLength: 1, maxLength: 12 }) | ||
| .map((chars) => chars.join("")) | ||
| .filter((value) => !value.startsWith("-") && !value.endsWith("-")) | ||
|
|
||
| export const repositoryCreateInputArbitrary = fc.record({ | ||
| branch: fc.option(githubSegmentArbitrary, { nil: null }), | ||
| owner: githubSegmentArbitrary, | ||
| repo: githubSegmentArbitrary | ||
| }).map(({ branch, owner, repo }) => ({ | ||
| expectedRepoRef: branch ?? "main", | ||
| repoUrl: branch === null | ||
| ? `https://github.com/${owner}/${repo}` | ||
| : `https://github.com/${owner}/${repo}/tree/${branch}` | ||
| })) | ||
|
|
||
| const defaultQuickCreateInputs = { | ||
| cpuLimit: "", | ||
| enableMcpPlaywright: false, | ||
| force: false, | ||
| forceEnv: false, | ||
| gpu: "none", | ||
| ramLimit: "", | ||
| runUp: true | ||
| } satisfies Omit<CreateInputs, "outDir" | "repoRef" | "repoUrl"> | ||
|
|
||
| export const createSetCreateViewSpy = () => { | ||
| const spy = vi.fn<(value: SetStateAction<CreateFlowView>) => void>() | ||
| const setCreateView: Dispatch<SetStateAction<CreateFlowView>> = spy | ||
| return { setCreateView, spy } | ||
| } | ||
|
|
||
| type SetCreateViewSpy = ReturnType<typeof createSetCreateViewSpy>["spy"] | ||
|
|
||
| export const requireCreateViewValue = ( | ||
| value: SetStateAction<CreateFlowView> | undefined | ||
| ): CreateFlowView => { | ||
| if (value === undefined || typeof value === "function") { | ||
| throw new Error("Expected CreateFlowView value.") | ||
| } | ||
| return value | ||
| } | ||
|
|
||
| export const submitCreateBuffer = ( | ||
| submitCreateView: SubmitCreateView, | ||
| buffer: string, | ||
| options: { readonly quickCreate?: boolean } = {} | ||
| ) => { | ||
| const { context } = makeBrowserActionContext({ githubStatus: validGithubStatus }) | ||
| const { setCreateView, spy: setCreateViewSpy } = createSetCreateViewSpy() | ||
| const quickCreate = options.quickCreate === undefined ? {} : { quickCreate: options.quickCreate } | ||
|
|
||
| submitCreateView({ | ||
| context, | ||
| controllerCwd: "/workspace", | ||
| createView: createInitialFlowView(buffer), | ||
| projectsRoot: "/home/dev/.docker-git", | ||
| ...quickCreate, | ||
| setCreateView | ||
| }) | ||
|
|
||
| return { context, setCreateViewSpy } | ||
| } | ||
|
|
||
| export const requireSubmittedCreateInputs = ( | ||
| submitCreateInputsMock: SubmitCreateInputsMock | ||
| ): CreateInputs => { | ||
| const inputs = submitCreateInputsMock.mock.calls[0]?.[0] | ||
| if (inputs === undefined) { | ||
| throw new Error("Expected submitted CreateInputs.") | ||
| } | ||
| return inputs | ||
| } | ||
|
|
||
| export const expectQuickCreateInputs = ( | ||
| submitCreateInputsMock: SubmitCreateInputsMock, | ||
| expected: Pick<CreateInputs, "outDir" | "repoRef" | "repoUrl"> | ||
| ) => { | ||
| expect(requireSubmittedCreateInputs(submitCreateInputsMock)).toEqual( | ||
| { | ||
| ...defaultQuickCreateInputs, | ||
| ...expected | ||
| } satisfies CreateInputs | ||
| ) | ||
| } | ||
|
|
||
| export const expectCreateViewReset = ( | ||
| setCreateViewSpy: SetCreateViewSpy | ||
| ) => { | ||
| expect(requireCreateViewValue(setCreateViewSpy.mock.calls[0]?.[0])).toEqual(createInitialFlowView()) | ||
| } | ||
|
|
||
| export const createSubmitCreateBuffer = (submitCreateView: SubmitCreateView) => | ||
| ( | ||
| buffer: string, | ||
| options: { readonly quickCreate?: boolean } = {} | ||
| ) => submitCreateBuffer(submitCreateView, buffer, options) | ||
|
|
||
| export const expectedOutDirForRepoUrl = (repoUrl: string): string => | ||
| `/home/dev/.docker-git/${deriveRepoPathParts(resolveRepoInput(repoUrl).repoUrl).pathParts.join("/")}` | ||
|
|
||
| export const createKeyEvent = ( | ||
| key: string, | ||
| shiftKey = false | ||
| ): Parameters<HandleCreateKey>[0] => { | ||
| const event = { | ||
| key, | ||
| shiftKey, | ||
| preventDefault: vi.fn() | ||
| } | ||
| return event | ||
| } | ||
|
|
||
| export const createSettingsFlowView = (): CreateFlowView => ({ | ||
| step: 1, | ||
| buffer: "30%", | ||
| inputError: null, | ||
| values: { | ||
| outDir: "/home/dev/.docker-git/org/repo", | ||
| repoRef: "feature-x", | ||
| repoUrl: "https://github.com/org/repo/tree/feature-x" | ||
| } | ||
| }) | ||
|
|
||
| export const createSettingsFlowViewAtStep = ( | ||
| stepName: CreateStep, | ||
| buffer = "draft" | ||
| ): CreateFlowView => { | ||
| const view = createSettingsFlowView() | ||
| const step = resolveCreateDisplaySteps().indexOf(stepName) | ||
| if (step === -1) { | ||
| throw new TypeError(`expected Create step: ${stepName}`) | ||
| } | ||
| return { ...view, step, buffer } | ||
| } | ||
|
|
||
| export const expectCreateArrowHandling = ( | ||
| handleCreateKey: HandleCreateKey, | ||
| key: "ArrowDown" | "ArrowUp", | ||
| expectedStep: (view: CreateFlowView) => number | ||
| ) => { | ||
| const { context } = makeBrowserActionContext({ githubStatus: validGithubStatus }) | ||
| const { setCreateView, spy: setCreateViewSpy } = createSetCreateViewSpy() | ||
| const event = createKeyEvent(key) | ||
| const createView = createSettingsFlowView() | ||
|
|
||
| const handled = handleCreateKey(event, { | ||
| context, | ||
| controllerCwd: "/workspace", | ||
| createView, | ||
| projectsRoot: "/home/dev/.docker-git", | ||
| setCreateView | ||
| }) | ||
|
|
||
| expect(handled).toBe(true) | ||
| expect(event.preventDefault).toHaveBeenCalledTimes(1) | ||
| expect(requireCreateViewValue(setCreateViewSpy.mock.calls[0]?.[0])).toEqual({ | ||
| ...createView, | ||
| step: expectedStep(createView), | ||
| buffer: "" | ||
| }) | ||
| expect(context.setMessage).toHaveBeenCalledWith(null) | ||
| } | ||
|
|
||
| export const expectCreateSideArrowBufferHandling = ( | ||
| handleCreateKey: HandleCreateKey, | ||
| submitCreateInputsMock: SubmitCreateInputsMock, | ||
| key: "ArrowLeft" | "ArrowRight", | ||
| stepName: CreateStep, | ||
| expectedBuffer: string | ||
| ) => { | ||
| const { context } = makeBrowserActionContext({ githubStatus: validGithubStatus }) | ||
| const { setCreateView, spy: setCreateViewSpy } = createSetCreateViewSpy() | ||
| const event = createKeyEvent(key) | ||
| const createView = createSettingsFlowViewAtStep(stepName, "typed") | ||
|
|
||
| const handled = handleCreateKey(event, { | ||
| context, | ||
| controllerCwd: "/workspace", | ||
| createView, | ||
| projectsRoot: "/home/dev/.docker-git", | ||
| setCreateView | ||
| }) | ||
|
|
||
| expect(handled).toBe(true) | ||
| expect(event.preventDefault).toHaveBeenCalledTimes(1) | ||
| expect(requireCreateViewValue(setCreateViewSpy.mock.calls[0]?.[0])).toEqual({ | ||
| ...createView, | ||
| buffer: expectedBuffer | ||
| }) | ||
| expect(requireCreateViewValue(setCreateViewSpy.mock.calls[0]?.[0]).values).toEqual(createView.values) | ||
| expect(submitCreateInputsMock).not.toHaveBeenCalled() | ||
| expect(context.setMessage).toHaveBeenCalledWith(null) | ||
| } | ||
|
|
||
| export const expectEmptyRepoInlineError = ( | ||
| submitCreateView: SubmitCreateView, | ||
| submitCreateInputsMock: SubmitCreateInputsMock, | ||
| quickCreate?: boolean | ||
| ) => { | ||
| const { context } = makeBrowserActionContext({ githubStatus: validGithubStatus }) | ||
| const { setCreateView, spy: setCreateViewSpy } = createSetCreateViewSpy() | ||
| const createView = createInitialFlowView(" ") | ||
|
|
||
| submitCreateView({ | ||
| context, | ||
| controllerCwd: "/workspace", | ||
| createView, | ||
| projectsRoot: "/home/dev/.docker-git", | ||
| quickCreate, | ||
| setCreateView | ||
| }) | ||
|
|
||
| expect(submitCreateInputsMock).not.toHaveBeenCalled() | ||
| expect(setCreateViewSpy).toHaveBeenCalledTimes(1) | ||
| expect(requireCreateViewValue(setCreateViewSpy.mock.calls[0]?.[0])).toEqual({ | ||
| ...createView, | ||
| inputError: "Insert URL first" | ||
| }) | ||
| expect(context.setMessage).not.toHaveBeenCalled() | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Добавьте TSDoc для всех экспортируемых функций и констант.
Все экспортируемые сущности (validGithubStatus, repositoryCreateInputArbitrary, createSetCreateViewSpy, requireCreateViewValue, submitCreateBuffer, и остальные 11 функций) не имеют TSDoc-документации. Согласно coding guidelines, необходимо документировать публичные функции с указанием параметров, возвращаемых типов, @pure маркера, и других метаданных.
Как минимум для каждой экспортируемой функции добавьте:
- Краткое описание назначения
@paramдля каждого параметра@returnsописание возвращаемого значения@pureмаркер (false для test helpers с side effects)
Пример документации для одной из функций
/**
* Создаёт Vitest spy для React setState handler в create flow тестах.
* `@pure` false
* `@returns` Объект с typed dispatch и spy для проверки вызовов
*/
export const createSetCreateViewSpy = () => {
const spy = vi.fn<(value: SetStateAction<CreateFlowView>) => void>()
const setCreateView: Dispatch<SetStateAction<CreateFlowView>> = spy
return { setCreateView, spy }
}As per coding guidelines: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect)."
🤖 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/app-ready-create-fixture.ts` around lines 29 -
259, Add comprehensive TSDoc blocks to every exported constant and function in
this file (e.g. validGithubStatus, repositoryCreateInputArbitrary,
createSetCreateViewSpy, requireCreateViewValue, submitCreateBuffer,
requireSubmittedCreateInputs, expectQuickCreateInputs, expectCreateViewReset,
createSubmitCreateBuffer, expectedOutDirForRepoUrl, createKeyEvent,
createSettingsFlowView, createSettingsFlowViewAtStep, expectCreateArrowHandling,
expectCreateSideArrowBufferHandling, expectEmptyRepoInlineError and any others
exported) describing purpose, parameters and return values; include required
metadata tags from the coding guidelines: `@pure` (use false for test helpers with
side effects), `@effect` (services used), `@invariant`, `@precondition`,
`@postcondition`, `@complexity` (time and space), and `@throws` Never, and for each
function add `@param` entries for each parameter and `@returns` description — place
each TSDoc immediately above the corresponding export.
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/tests/docker-git/menu-create-display-settings.test.ts`:
- Around line 19-116: Add property-based tests (using fast-check) that assert
core invariants for display-settings: use arbitrary sequences of step moves and
buffer inputs to verify (1) in-place apply via applyCreateDisplaySettingsStep +
createFlowViewAtStep keeps the current step stable, (2)
moveCreateDisplaySettingsStep wraparound behavior is predictable (down from last
wraps to first and up from first wraps to last) by comparing against
resolveCreateDisplaySteps ordering, and (3) preview actions (calls to
renderCreateStepLabelWithBufferPreview and resolveCreateSettingsChoiceBuffer)
never mutate the committed values returned by resolveCreateInputs or the
view.values object (check structural equality before/after). Integrate these as
fast-check properties in the existing test file, using the project’s Effect test
utilities (not async/await) and helper functions like expectCreateContinueView /
expectCreateCompleteInputs to validate outcomes.
🪄 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: b6f7465c-a870-4e12-90ad-1bf5ea964f36
📒 Files selected for processing (7)
packages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.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). (8)
- GitHub Check: Final build (windows-latest)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone cache)
- GitHub Check: Lint
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/app/tests/docker-git/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.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/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.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/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.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/tests/docker-git/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.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/tests/docker-git/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.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/tests/docker-git/create-flow-test-helpers.tspackages/app/tests/docker-git/menu-create-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-fixture.tspackages/app/tests/docker-git/app-ready-create-settings.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-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-settings.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-display-settings.test.tspackages/app/tests/docker-git/app-ready-create.test.tspackages/app/tests/docker-git/create-flow-render.test.tspackages/app/tests/docker-git/menu-create-shared.test.tspackages/app/tests/docker-git/app-ready-create-settings.test.ts
🔇 Additional comments (6)
packages/app/tests/docker-git/app-ready-create.test.ts (1)
4-21: LGTM!Also applies to: 28-29, 60-122, 137-137, 152-152
packages/app/tests/docker-git/app-ready-create-settings.test.ts (1)
1-175: LGTM!packages/app/tests/docker-git/create-flow-render.test.ts (1)
1-245: LGTM!packages/app/tests/docker-git/app-ready-create-fixture.ts (1)
1-290: LGTM!packages/app/tests/docker-git/menu-create-shared.test.ts (1)
1-249: LGTM!packages/app/tests/docker-git/create-flow-test-helpers.ts (1)
1-83: LGTM!
| describe("menu-create-shared display settings", () => { | ||
| const cwd = process.cwd() | ||
|
|
||
| it("keeps every browser display row after settings are applied", () => { | ||
| const appliedValues = { | ||
| cpuLimit: "40%", | ||
| enableMcpPlaywright: true, | ||
| force: true, | ||
| gpu: "all", | ||
| ramLimit: "8g", | ||
| runUp: false | ||
| } satisfies Partial<ReturnType<typeof resolveCreateInputs>> | ||
|
|
||
| expect(resolveCreateDisplaySteps(appliedValues)).toEqual([ | ||
| "repoUrl", | ||
| "cpuLimit", | ||
| "ramLimit", | ||
| "gpu", | ||
| "runUp", | ||
| "mcpPlaywright", | ||
| "force" | ||
| ]) | ||
| }) | ||
|
|
||
| it("applies a browser display setting in place", () => { | ||
| const mcpView = createFlowViewAtStep(createFeatureRepoSettingsView(cwd), "mcpPlaywright") | ||
| const next = expectCreateContinueView(applyCreateDisplaySettingsStep(cwd, { ...mcpView, buffer: "y" })) | ||
|
|
||
| expect(next.step).toBe(mcpView.step) | ||
| expect(next.buffer).toBe("") | ||
| expect(next.values.enableMcpPlaywright).toBe(true) | ||
| expect(resolveCreateDisplaySteps()[next.step]).toBe("mcpPlaywright") | ||
| }) | ||
|
|
||
| it("navigates browser display settings without skipping applied rows", () => { | ||
| const view = createFeatureRepoSettingsView(cwd) | ||
| const applied = expectCreateContinueView(applyCreateDisplaySettingsStep( | ||
| cwd, | ||
| { ...createFlowViewAtStep(view, "mcpPlaywright"), buffer: "y" } | ||
| )) | ||
| const down = moveCreateDisplaySettingsStep(applied, "down") | ||
| const up = moveCreateDisplaySettingsStep(applied, "up") | ||
|
|
||
| expect(down?.step).toBe(resolveCreateDisplaySteps().indexOf("force")) | ||
| expect(up?.step).toBe(resolveCreateDisplaySteps().indexOf("runUp")) | ||
| expect(down?.buffer).toBe("") | ||
| expect(up?.values.enableMcpPlaywright).toBe(true) | ||
| }) | ||
|
|
||
| it("resolves horizontal choices against applied browser display rows", () => { | ||
| const applied = expectCreateContinueView(applyCreateDisplaySettingsStep( | ||
| cwd, | ||
| { ...createFlowViewAtStep(createFeatureRepoSettingsView(cwd), "mcpPlaywright"), buffer: "y" } | ||
| )) | ||
|
|
||
| expect(resolveCreateSettingsChoiceBuffer(applied, "left")).toBe("n") | ||
| expect(resolveCreateSettingsChoiceBuffer(applied, "right")).toBe("y") | ||
| }) | ||
|
|
||
| it("completes browser display settings with a valid active buffer", () => { | ||
| const complete = expectCreateCompleteInputs(completeCreateDisplaySettingsFlow( | ||
| cwd, | ||
| { ...createFlowViewAtStep(createFeatureRepoSettingsView(cwd), "mcpPlaywright"), buffer: "y" } | ||
| )) | ||
|
|
||
| expect(complete.enableMcpPlaywright).toBe(true) | ||
| }) | ||
|
|
||
| it("renders unapplied buffer previews for discrete settings labels", () => { | ||
| const defaults = resolveCreateInputs(cwd, {}) | ||
|
|
||
| expect(renderCreateStepLabelWithBufferPreview("gpu", defaults, "all")).toBe("GPU access [all]") | ||
| expect(renderCreateStepLabelWithBufferPreview("gpu", defaults, "none")).toBe("GPU access [none]") | ||
| expect(renderCreateStepLabelWithBufferPreview("gpu", defaults, "y")).toBe("GPU access [all]") | ||
| expect(renderCreateStepLabelWithBufferPreview("runUp", defaults, "n")).toBe( | ||
| "Run docker compose up now? [N]" | ||
| ) | ||
| expect(renderCreateStepLabelWithBufferPreview("mcpPlaywright", defaults, "y")).toBe( | ||
| "Enable Playwright MCP (nested Chromium browser)? [Y]" | ||
| ) | ||
| expect(renderCreateStepLabelWithBufferPreview("force", defaults, "y")).toBe( | ||
| "Force recreate (overwrite files + wipe volumes)? [Y]" | ||
| ) | ||
| }) | ||
|
|
||
| it("preserves committed/default labels for empty, invalid, and free-text preview buffers", () => { | ||
| const defaults = resolveCreateInputs(cwd, {}) | ||
|
|
||
| expect(renderCreateStepLabelWithBufferPreview("mcpPlaywright", defaults, "")).toBe( | ||
| "Enable Playwright MCP (nested Chromium browser)? [N]" | ||
| ) | ||
| expect(renderCreateStepLabelWithBufferPreview("mcpPlaywright", defaults, "maybe")).toBe( | ||
| "Enable Playwright MCP (nested Chromium browser)? [N]" | ||
| ) | ||
| expect(renderCreateStepLabelWithBufferPreview("cpuLimit", defaults, "80%")).toBe("CPU limit [30%]") | ||
| expect(renderCreateStepLabelWithBufferPreview("ramLimit", defaults, "8g")).toBe("RAM limit [30%]") | ||
| }) | ||
| }) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Добавьте property-based проверки инвариантов display-settings.
Сейчас покрытие в этом наборе в основном примерное; стоит добавить fast-check-инварианты для навигации/preview (например, стабильность шага при in-place apply, предсказуемость wraparound, и отсутствие мутации values при буферных preview-действиях), чтобы снизить риск регрессий при расширении списка шагов.
As per coding guidelines "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/menu-create-display-settings.test.ts` around
lines 19 - 116, Add property-based tests (using fast-check) that assert core
invariants for display-settings: use arbitrary sequences of step moves and
buffer inputs to verify (1) in-place apply via applyCreateDisplaySettingsStep +
createFlowViewAtStep keeps the current step stable, (2)
moveCreateDisplaySettingsStep wraparound behavior is predictable (down from last
wraps to first and up from first wraps to last) by comparing against
resolveCreateDisplaySteps ordering, and (3) preview actions (calls to
renderCreateStepLabelWithBufferPreview and resolveCreateSettingsChoiceBuffer)
never mutate the committed values returned by resolveCreateInputs or the
view.values object (check structural equality before/after). Integrate these as
fast-check properties in the existing test file, using the project’s Effect test
utilities (not async/await) and helper functions like expectCreateContinueView /
expectCreateCompleteInputs to validate outcomes.
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/app-ready-create.ts`:
- Around line 33-35: CreateSubmitArgs currently encodes three distinct behaviors
via quickCreate?: boolean which is ambiguous; change the API to a discriminated
union or explicit string-mode field (e.g. mode: "advance" | "quick-create" |
"complete-settings") and update submitCreateView(),
completeCreateDisplaySettingsFlow(), and all callers to switch on that mode
instead of treating undefined/false/true differently; ensure the new type
replaces CreateSubmitArgs's quickCreate property, update any places mentioned
around submitCreateView (and the block covering the logic at lines ~65-78) to
use explicit mode checks and preserve existing behavior for each named mode.
🪄 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: 58f1fae4-fdb8-4647-909f-239a03f08bfc
📒 Files selected for processing (3)
packages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.tspackages/lib/src/usecases/auth-grok-oauth.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 (Clone auto-open SSH)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (OpenCode)
- GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never useany,unknown,eslint-disable,ts-ignore, orastype assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through.exhaustive()pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects:Effect<Success, Error, Requirements>. Compose effects throughpipe()andEffect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example:Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including:@pure(true/false),@effect(required services),@invariant(mathematical invariants),@precondition,@postcondition,@complexity(time and space),@throwsNever (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...
Files:
packages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code:any,eslint-disable,ts-ignore,async/await, raw Promise chains (then/catch),Promise.all,try/catchfor logic control,console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects:Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.
Files:
packages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input
Files:
packages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files introduce path traversal or writes outside intended project/container state directories
Files:
packages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}
📄 CodeRabbit inference engine (Custom checks)
Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output
Files:
packages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.ts
**/*
⚙️ CodeRabbit configuration file
**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.
Files:
packages/lib/src/usecases/auth-grok-oauth.tspackages/app/src/ui/primitives-web.tsxpackages/app/src/web/app-ready-create.ts
🔇 Additional comments (5)
packages/lib/src/usecases/auth-grok-oauth.ts (2)
9-10: LGTM!Also applies to: 44-53, 112-113
76-76: LGTM!packages/app/src/ui/primitives-web.tsx (3)
116-163: LGTM!
165-187: LGTM!
202-239: LGTM!
| type CreateSubmitArgs = CreateKeyArgs & { | ||
| readonly quickCreate?: boolean | ||
| readonly quickCreate?: boolean | undefined | ||
| } |
There was a problem hiding this comment.
Не кодируйте три разных действия через quickCreate?: boolean.
Сейчас у submitCreateView() скрытый трёхзначный контракт: на settings-шаге только undefined означает обычный apply, а и false, и true ведут в completeCreateDisplaySettingsFlow(). Для экспортируемого API это опасно: новый вызов с quickCreate: false на step > 0 тихо отправит форму вместо применения текущей строки. Лучше заменить этот параметр на явный режим ("advance" | "quick-create" | "complete-settings"), чтобы типы отражали реальное поведение.
💡 Возможный вариант
+type CreateSubmitMode = "advance" | "quick-create" | "complete-settings"
+
type CreateSubmitArgs = CreateKeyArgs & {
- readonly quickCreate?: boolean | undefined
+ readonly mode: CreateSubmitMode
}
const resolveCreateSubmitResult = (
createContext: { readonly cwd: string; readonly projectsRoot: string },
createView: CreateFlowView,
- quickCreate: boolean | undefined
+ mode: CreateSubmitMode
): ReturnType<typeof advanceCreateFlow> => {
if (createView.step > 0) {
- return quickCreate === undefined
- ? applyCreateDisplaySettingsStep(createContext, createView)
- : completeCreateDisplaySettingsFlow(createContext, createView)
+ return mode === "complete-settings"
+ ? completeCreateDisplaySettingsFlow(createContext, createView)
+ : applyCreateDisplaySettingsStep(createContext, createView)
}
- return quickCreate === undefined
- ? advanceCreateFlow(createContext, createView)
- : advanceCreateFlow(createContext, createView, { quickCreate })
+ return mode === "quick-create"
+ ? advanceCreateFlow(createContext, createView, { quickCreate: true })
+ : advanceCreateFlow(createContext, createView)
}Also applies to: 65-78
🤖 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-create.ts` around lines 33 - 35,
CreateSubmitArgs currently encodes three distinct behaviors via quickCreate?:
boolean which is ambiguous; change the API to a discriminated union or explicit
string-mode field (e.g. mode: "advance" | "quick-create" | "complete-settings")
and update submitCreateView(), completeCreateDisplaySettingsFlow(), and all
callers to switch on that mode instead of treating undefined/false/true
differently; ensure the new type replaces CreateSubmitArgs's quickCreate
property, update any places mentioned around submitCreateView (and the block
covering the logic at lines ~65-78) to use explicit mode checks and preserve
existing behavior for each named mode.
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/docker-git/menu-create-shared.ts`:
- Around line 703-723: Add regression tests that assert the new Settings-mode
invariants in the Create flow: write tests that exercise
moveCreateDisplaySettingsStep, applyCreateDisplaySettingsStep and
completeCreateDisplaySettingsFlow (and use
moveCreateSettingsWithin/resolveCreateDisplaySteps helpers to construct
scenarios) to ensure (1) applied rows remain present after navigation, (2)
moving the selected row clears the preview buffer, and (3) pressing Done applies
a valid preview and returns an Error when the preview is invalid; each test
should use CreateFlowView snapshots and check that values are unchanged except
the intended effects and that step/index invariants hold.
- Around line 25-30: CreateFlowView currently uses a single numeric step that
conflates two different step-scales (resolveCreateFlowSteps(view.values) vs
resolveCreateDisplaySteps()), which allows accidental mixing; change
CreateFlowView into a tagged union (e.g., { mode: "create", step:
CreateStepIndex, buffer, inputError, values } | { mode: "display", step:
DisplayStepIndex, buffer, inputError, values }) or add a discriminant field
"mode" and distinct step types so the compiler enforces narrowing; update all
usages that call resolveCreateFlowSteps, resolveCreateDisplaySteps or inspect
step to narrow by mode (use the new types or guards) and adjust function
signatures that accept CreateFlowView accordingly (reference CreateFlowView,
resolveCreateFlowSteps, resolveCreateDisplaySteps, and CreateInputs).
🪄 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: 5fb6c285-23da-4900-a01f-cc9738884ba4
📒 Files selected for processing (1)
packages/app/src/docker-git/menu-create-shared.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: E2E (Clone auto-open SSH)
- GitHub Check: E2E (Browser command)
- GitHub Check: E2E (Runtime volumes + SSH)
- GitHub Check: E2E (Clone cache)
- GitHub Check: E2E (Login context)
- GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{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-shared.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-shared.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-shared.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-shared.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-shared.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-shared.ts
🔇 Additional comments (1)
packages/app/src/docker-git/menu-create-shared.ts (1)
47-81: LGTM!Also applies to: 164-208, 489-689
| export type CreateFlowView = { | ||
| readonly step: number | ||
| readonly buffer: string | ||
| readonly inputError: string | null | ||
| readonly values: Partial<CreateInputs> | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift
Разведите типы шага для unresolved/display режимов.
Сейчас CreateFlowView.step индексирует две разные шкалы: resolveCreateFlowSteps(view.values) и resolveCreateDisplaySteps(). Пока это один number, компилятор не защищает от случайного смешивания terminal/browser helper'ов, а это ровно тот класс ошибки, который описан в root cause PR. Лучше ввести tagged union/отдельные view-типы для двух режимов либо спрятать step за mode-aware API.
As per coding guidelines "Оцени решение с точки зрения формальной верификации: какие инварианты, предусловия и постусловия можно доказать математически, а где доказуемость слабая."
Also applies to: 703-723, 725-861
🤖 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-shared.ts` around lines 25 - 30,
CreateFlowView currently uses a single numeric step that conflates two different
step-scales (resolveCreateFlowSteps(view.values) vs
resolveCreateDisplaySteps()), which allows accidental mixing; change
CreateFlowView into a tagged union (e.g., { mode: "create", step:
CreateStepIndex, buffer, inputError, values } | { mode: "display", step:
DisplayStepIndex, buffer, inputError, values }) or add a discriminant field
"mode" and distinct step types so the compiler enforces narrowing; update all
usages that call resolveCreateFlowSteps, resolveCreateDisplaySteps or inspect
step to narrow by mode (use the new types or guards) and adjust function
signatures that accept CreateFlowView accordingly (reference CreateFlowView,
resolveCreateFlowSteps, resolveCreateDisplaySteps, and CreateInputs).
| export const moveCreateSettingsStep = ( | ||
| view: CreateFlowView, | ||
| direction: CreateSettingsNavigationDirection | ||
| ): CreateFlowView | null => moveCreateSettingsWithin(view, resolveCreateFlowSteps(view.values).length - 1, direction) | ||
|
|
||
| /** | ||
| * Moves the selected browser Create settings row over the full display list. | ||
| * | ||
| * @pure true | ||
| * @effect none | ||
| * @invariant applied rows do not affect navigation order | ||
| * @invariant view.step = 0 -> result = null | ||
| * @invariant result != null -> 1 <= result.step < |resolveCreateDisplaySteps()| | ||
| * @precondition view is a CreateFlowView snapshot | ||
| * @postcondition result values are identical to input values | ||
| * @complexity O(1) | ||
| */ | ||
| export const moveCreateDisplaySettingsStep = ( | ||
| view: CreateFlowView, | ||
| direction: CreateSettingsNavigationDirection | ||
| ): CreateFlowView | null => moveCreateSettingsWithin(view, resolveCreateDisplaySteps().length - 1, direction) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Добавьте regression-тесты на новые инварианты Settings mode.
В PR заявлены тонкие контракты: applied rows не исчезают, переход на другую строку очищает preview buffer, а Done сначала применяет валидный preview и возвращает Error на невалидный. Сейчас эта спецификация живет только в логике moveCreateDisplaySettingsStep / applyCreateDisplaySettingsStep / completeCreateDisplaySettingsFlow; в текущем diff нет тестов, которые зафиксируют это поведение и защитят от регресса обратно к unresolved-flow.
As per coding guidelines "Флагай любой уход от спеки, недокументированное изменение поведения, отсутствие тестов для заявленного поведения и security-риск."
Also applies to: 787-825
🤖 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-shared.ts` around lines 703 - 723,
Add regression tests that assert the new Settings-mode invariants in the Create
flow: write tests that exercise moveCreateDisplaySettingsStep,
applyCreateDisplaySettingsStep and completeCreateDisplaySettingsFlow (and use
moveCreateSettingsWithin/resolveCreateDisplaySteps helpers to construct
scenarios) to ensure (1) applied rows remain present after navigation, (2)
moving the selected row clears the preview buffer, and (3) pressing Done applies
a valid preview and returns an Error when the preview is invalid; each test
should use CreateFlowView snapshots and check that values are unchanged except
the intended effects and that step/index invariants hold.
Closes #315
What changed
Enterapplies the active row, clears the buffer, and keeps the selected row in place.Donebutton.Quick Createremains the repo-step fast path.Doneapplies a valid active preview before submit and preserves the existing parse-error path for invalid buffers.Root cause
The browser Settings UI was sharing the unresolved-step flow used by the terminal wizard. Once a setting was applied, that row became “resolved” and disappeared from the web settings list, so navigation and side-arrow previews operated against a shrinking list.
Mathematical guarantees
resolveCreateFlowSteps(values)keeps terminal/TUI unresolved-step semantics unchanged.resolveCreateDisplaySteps(values)is independent of applied values, so every web Settings row remains visible.CreateFlowView.buffer; it does not mutateCreateFlowView.values.EnterreturnsContinuewithstepunchanged andbuffer = "".DonesubmitsresolveCreateInputs(context, updatedValues)only after applying a valid active buffer, otherwise it reports the existing parse error and does not submit.Verification
bun run --cwd packages/app vitest run tests/docker-git/menu-create-shared.test.ts tests/docker-git/app-ready-create.test.ts tests/docker-git/create-flow-render.test.tsbun run --cwd packages/app typecheckgit diff --check390x844: repo step showsQuick Create/Settings; Settings showsDone;ArrowRightpreviews Playwright MCP[Y];Enterconfirms[y]without hiding the row;ArrowDownkeeps applied rows visible;Donesubmits payload withenableMcpPlaywright: true.