feat: setup wizard UX -- template filters, card metadata, provider form reuse#910
feat: setup wizard UX -- template filters, card metadata, provider form reuse#910
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughDocumentation, backend, and frontend were changed to add structural template metadata ( Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches. Re-running this action after a short time may resolve the issue. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
There was a problem hiding this comment.
Code Review
This pull request enhances the setup wizard by introducing structural metadata for templates—including agent counts, department counts, autonomy levels, and workflow types—and displaying this information in the UI. The template selection step now features a searchable grid with category and size filters. Additionally, the provider setup has been refactored to use a unified form drawer, supporting both preset-based and custom provider configurations. Review feedback focuses on preventing race conditions where refreshing the provider list could inadvertently clear error messages from failed model discovery, reducing code duplication in the template loading logic, and improving the search implementation to support multi-keyword matching.
| await createProviderFromPreset(presetName, presetName, undefined, detectedUrl) | ||
| // Refresh provider list to get updated model counts | ||
| await fetchProviders() |
There was a problem hiding this comment.
There's a potential race condition here. If createProviderFromPreset succeeds in creating the provider but fails during the subsequent model discovery, it will set an error in the store but won't throw. This handleAddPreset function will then immediately call fetchProviders(), which clears the error state, preventing the user from seeing the discovery error message.
To fix this, you should check for an error in the store before refreshing the provider list.
await createProviderFromPreset(presetName, presetName, undefined, detectedUrl)
// Refresh provider list only if no error occurred during creation/discovery.
if (!useSetupWizardStore.getState().providersError) {
await fetchProviders()
}
| onCreateFromPreset: async (data) => { | ||
| const result = await createProviderFromPresetFull(data) | ||
| if (result) await fetchProviders() | ||
| return result | ||
| }, | ||
| [createProviderFromPreset, fetchProviders], | ||
| ) | ||
| onCreateProvider: async (data) => { | ||
| const result = await createProviderCustom(data) | ||
| if (result) await fetchProviders() | ||
| return result | ||
| }, |
There was a problem hiding this comment.
Similar to the issue in handleAddPreset, there's a race condition here. If createProviderFromPresetFull or createProviderCustom succeeds but a subsequent operation within them (like model discovery) fails and sets an error, fetchProviders() is still called, which will immediately clear the error message from the UI.
You should check for an error in the store before calling fetchProviders to ensure discovery errors are displayed to the user.
onCreateFromPreset: async (data) => {
const result = await createProviderFromPresetFull(data)
if (result && !useSetupWizardStore.getState().providersError) {
await fetchProviders()
}
return result
},
onCreateProvider: async (data) => {
const result = await createProviderCustom(data)
if (result && !useSetupWizardStore.getState().providersError) {
await fetchProviders()
}
return result
},
src/synthorg/templates/loader.py
Outdated
| seen[name] = TemplateInfo( | ||
| name=name, | ||
| display_name=meta.name, | ||
| description=meta.description, | ||
| source="builtin", | ||
| tags=meta.tags, | ||
| skill_patterns=meta.skill_patterns, | ||
| variables=loaded.template.variables, | ||
| variables=tmpl.variables, | ||
| agent_count=len(tmpl.agents), | ||
| department_count=len(tmpl.departments), | ||
| autonomy_level=tmpl.autonomy.get("level", "semi"), | ||
| workflow=tmpl.workflow, | ||
| ) |
There was a problem hiding this comment.
To improve maintainability and reduce code duplication, you could extract the logic for creating a TemplateInfo instance into a helper function. This logic is repeated in _collect_user_templates on lines 167-179.
A helper function could look like this:
def _create_template_info_from_loaded(
name: str, loaded: LoadedTemplate, source: Literal["builtin", "user"]
) -> TemplateInfo:
meta = loaded.template.metadata
tmpl = loaded.template
return TemplateInfo(
name=name,
display_name=meta.name,
description=meta.description,
source=source,
tags=meta.tags,
skill_patterns=meta.skill_patterns,
variables=tmpl.variables,
agent_count=len(tmpl.agents),
department_count=len(tmpl.departments),
autonomy_level=tmpl.autonomy.get("level", "semi"),
workflow=tmpl.workflow,
)Then you can call it here and in _collect_user_templates.
| if (query) { | ||
| const haystack = `${t.display_name} ${t.description} ${t.tags.join(' ')}`.toLowerCase() | ||
| if (!haystack.includes(query)) return false | ||
| } |
There was a problem hiding this comment.
The current search implementation performs a simple substring match. To enhance the user experience, you could improve it to support multiple keywords. For example, a search for "dev shop" should match templates that contain both "dev" and "shop".
You can achieve this by splitting the search query into keywords and checking if all of them are present in the template's searchable content.
| if (query) { | |
| const haystack = `${t.display_name} ${t.description} ${t.tags.join(' ')}`.toLowerCase() | |
| if (!haystack.includes(query)) return false | |
| } | |
| const keywords = query.split(' ').filter(Boolean); | |
| if (keywords.length > 0) { | |
| const haystack = `${t.display_name} ${t.description} ${t.tags.join(' ')}`.toLowerCase() | |
| if (!keywords.every(kw => haystack.includes(kw))) return false | |
| } |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #910 +/- ##
==========================================
- Coverage 92.16% 92.15% -0.02%
==========================================
Files 596 596
Lines 31401 31438 +37
Branches 3040 3043 +3
==========================================
+ Hits 28942 28971 +29
- Misses 1939 1945 +6
- Partials 520 522 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/src/pages/setup/ProvidersStep.tsx (1)
88-95:⚠️ Potential issue | 🟠 MajorStop re-fetching immediately after preset-based creation.
createProviderFromPreset()/createProviderFromPresetFull()already updatestate.providersand may setprovidersErrorwhen discovery fails or still returns zero models. The immediatefetchProviders()here clears that error first, so the warning disappears before the user can see it.✂️ Proposed fix
const handleAddPreset = useCallback( async (presetName: string, detectedUrl?: string) => { await createProviderFromPreset(presetName, presetName, undefined, detectedUrl) - // Refresh provider list to get updated model counts - await fetchProviders() }, - [createProviderFromPreset, fetchProviders], + [createProviderFromPreset], ) const drawerOverrides: ProviderFormOverrides = useMemo(() => ({ presets, presetsLoading, presetsError, onFetchPresets: fetchPresets, - onCreateFromPreset: async (data) => { - const result = await createProviderFromPresetFull(data) - if (result) await fetchProviders() - return result - }, + onCreateFromPreset: createProviderFromPresetFull, onCreateProvider: async (data) => { const result = await createProviderCustom(data) if (result) await fetchProviders() return result }, }), [presets, presetsLoading, presetsError, fetchPresets, createProviderFromPresetFull, createProviderCustom, fetchProviders])Also applies to: 103-112
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/pages/setup/ProvidersStep.tsx` around lines 88 - 95, The code re-fetches providers immediately after calling createProviderFromPreset/createProviderFromPresetFull which already update state.providers and set providersError; this immediate await fetchProviders() clears providersError prematurely. Remove the immediate await fetchProviders() calls from handleAddPreset and the analogous handler (lines ~103-112) so creation relies on the state updates returned by createProviderFromPreset/createProviderFromPresetFull; if a forced refresh is still required, call fetchProviders() only conditionally after those calls succeed and providersError is falsy (e.g., based on the returned result or state), not unconditionally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/design/organization.md`:
- Around line 342-344: Update the "Providers" paragraph to explicitly state that
provider configuration supports both probe-detected (auto-detection) base URLs
and manually entered custom base URLs in addition to API key / subscription /
custom provider options; mention where this deviates from prior spec and briefly
note the rationale (e.g., support local instances and manual endpoints) so
readers know implementation details and expected behavior when auto-detection
fails or is overridden in the Providers section (refer to the existing
"Providers" text that lists auto-detection and full provider form).
In `@web/src/__tests__/stores/setup-wizard.test.ts`:
- Around line 353-396: Add a new test for the zero-model discovery path in
createProviderFromPresetFull: mock createFromPreset to resolve to a provider
object with models: [], then mock discoverModels to resolve (or resolve to a
discovered model list) and mock getProvider to return the refreshed provider
with models populated; call
useSetupWizardStore.getState().createProviderFromPresetFull(...) and assert that
discoverModels and getProvider were invoked, the function returns the refreshed
provider, useSetupWizardStore.getState().providers stores that provider under
the given name, and providersError remains null (or appropriate). Ensure you
reference createProviderFromPresetFull, createFromPreset, discoverModels,
getProvider and useSetupWizardStore.getState().providers in the test.
In `@web/src/pages/providers/ProviderFormDrawer.tsx`:
- Around line 73-81: The effect in ProviderFormDrawer re-runs whenever the
entire overrides object changes, causing duplicate preset fetches; extract the
fetch handler and depend only on that instead of the whole overrides object:
inside the component get a stable reference like const fetchPresets =
overrides?.onFetchPresets ?? useProvidersStore.getState().fetchPresets, then
update the useEffect to call fetchPresets when open && mode === 'create' and
list fetchPresets (and open, mode) in the dependency array; ensure you reference
the symbols useEffect, open, mode, overrides, onFetchPresets, and
useProvidersStore.getState().fetchPresets so the drawer open triggers only a
single presets request.
In `@web/src/stores/setup-wizard.ts`:
- Around line 634-654: After creating a provider and auto-discovering models in
the full-form path, ensure we preserve the "no models discovered" warning by
checking the refreshed provider returned by getProvider() for zero models and
setting providersError (same message as createProviderFromPreset) instead of
treating it as a clean success; refactor the post-create discovery+warning logic
used around discoverModels, getProvider and set into a shared helper (e.g.,
postCreateProviderCheck or handleProviderDiscovery) and call it from both the
full-form branch and createProviderFromPreset so the zero-model warning cannot
drift.
---
Outside diff comments:
In `@web/src/pages/setup/ProvidersStep.tsx`:
- Around line 88-95: The code re-fetches providers immediately after calling
createProviderFromPreset/createProviderFromPresetFull which already update
state.providers and set providersError; this immediate await fetchProviders()
clears providersError prematurely. Remove the immediate await fetchProviders()
calls from handleAddPreset and the analogous handler (lines ~103-112) so
creation relies on the state updates returned by
createProviderFromPreset/createProviderFromPresetFull; if a forced refresh is
still required, call fetchProviders() only conditionally after those calls
succeed and providersError is falsy (e.g., based on the returned result or
state), not unconditionally.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4bed3cb7-d9e4-4d7f-b68e-e6104ae2ecea
📒 Files selected for processing (18)
docs/design/organization.mdsrc/synthorg/api/controllers/setup.pysrc/synthorg/api/controllers/setup_agents.pysrc/synthorg/api/controllers/setup_models.pysrc/synthorg/templates/loader.pytests/unit/api/controllers/test_setup.pytests/unit/templates/test_loader.pyweb/src/__tests__/stores/setup-wizard.test.tsweb/src/__tests__/utils/template-categories.test.tsweb/src/api/types.tsweb/src/pages/providers/ProviderFormDrawer.tsxweb/src/pages/setup/ProviderAddForm.tsxweb/src/pages/setup/ProviderProbeResults.tsxweb/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/SetupAgentCard.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/stores/setup-wizard.ts
💤 Files with no reviewable changes (1)
- web/src/pages/setup/ProviderAddForm.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Build Web
- GitHub Check: Test (Python 3.14)
- GitHub Check: Dashboard Test
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. Do not recreate status dots inline, build card-with-header layouts from scratch, create metric displays manually, render initials circles manually, create complex (>8 line) JSX inside.map()blocks, or usergba()with hardcoded values instead of design token variables.
Files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/__tests__/utils/template-categories.test.tsweb/src/pages/setup/TemplateCard.tsxweb/src/api/types.tsweb/src/pages/setup/ProviderProbeResults.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/__tests__/stores/setup-wizard.test.tsweb/src/stores/setup-wizard.tsweb/src/pages/providers/ProviderFormDrawer.tsxweb/src/pages/setup/ProvidersStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use design token rules: colors via Tailwind semantic classes (
text-foreground,bg-card,text-accent,text-success,bg-danger) or CSS variables (var(--so-accent)), typography viafont-sansorfont-mono, spacing via density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind, shadows/borders via token variables (var(--so-shadow-card-hover),border-border,border-bright). Never hardcode hex values, set fontFamily directly, or hardcode pixel values for layout spacing.
Files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/__tests__/utils/template-categories.test.tsweb/src/pages/setup/TemplateCard.tsxweb/src/api/types.tsweb/src/pages/setup/ProviderProbeResults.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/__tests__/stores/setup-wizard.test.tsweb/src/stores/setup-wizard.tsweb/src/pages/providers/ProviderFormDrawer.tsxweb/src/pages/setup/ProvidersStep.tsx
web/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use property-based testing with fast-check (
fc.assert+fc.property). Run tests withnpm --prefix web run testfor Vitest with--detect-async-leaksflag.
Files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/__tests__/utils/template-categories.test.tsweb/src/pages/setup/TemplateCard.tsxweb/src/api/types.tsweb/src/pages/setup/ProviderProbeResults.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/__tests__/stores/setup-wizard.test.tsweb/src/stores/setup-wizard.tsweb/src/pages/providers/ProviderFormDrawer.tsxweb/src/pages/setup/ProvidersStep.tsx
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Nofrom __future__ import annotations-- Python 3.14+ has PEP 649 native lazy annotations. Useexcept A, B:(no parentheses) per PEP 758 except syntax as enforced by ruff.
All public functions and classes require type hints and Google-style docstrings (enforced by ruff D rules). Use mypy strict mode.
Functions must be less than 50 lines, files less than 800 lines. Handle errors explicitly, never silently swallow. Validate at system boundaries (user input, external APIs, config files).
Files:
src/synthorg/api/controllers/setup_agents.pytests/unit/templates/test_loader.pytests/unit/api/controllers/test_setup.pysrc/synthorg/api/controllers/setup.pysrc/synthorg/templates/loader.pysrc/synthorg/api/controllers/setup_models.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Every module with business logic must have:from synthorg.observability import get_loggerthenlogger = get_logger(__name__). Use event name constants fromsynthorg.observability.events.<domain>modules (e.g.,API_REQUEST_STARTED,TOOL_INVOKE_START). Always use structured kwargs:logger.info(EVENT, key=value). Log all error paths at WARNING or ERROR with context before raising, all state transitions at INFO, and DEBUG for object creation and key function flow. Pure data models, enums, and re-exports do not need logging.
Use immutability patterns: create new objects instead of mutating existing ones. For non-Pydantic internal collections (registries,BaseTool), usecopy.deepcopy()at construction plusMappingProxyTypewrapping for read-only enforcement. Fordict/listfields in frozen Pydantic models, usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Use Pydantic v2 models (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields (e.g.,TokenUsage.total_tokens). UseNotBlankStrfromcore.typesfor all identifier/name fields (including optionalNotBlankStr | Noneand tuple variants) instead of manual whitespace validators.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations (e.g., multiple tool invocations, parallel agent calls) in new code instead of barecreate_task. Favor structured concurrency.
Separate frozen Pydantic models for config/identity from mutable-via-copy models for runtime state that evolves (e.g., agent execution state, task progress). Never mix static config fields with mutable runtime fields in one model.
Never useimport loggingorlogging.getLogger()in application code. Exception:observability/setup.pyandobservability/sinks.pymay use stdlibloggingandprint(..., file=sys.stderr)for bootst...
Files:
src/synthorg/api/controllers/setup_agents.pysrc/synthorg/api/controllers/setup.pysrc/synthorg/templates/loader.pysrc/synthorg/api/controllers/setup_models.py
src/synthorg/api/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Use RFC 9457 errors in the REST API. Implement role-based access control (RBAC) guards in the API layer.
Files:
src/synthorg/api/controllers/setup_agents.pysrc/synthorg/api/controllers/setup.pysrc/synthorg/api/controllers/setup_models.py
src/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Line length: 88 characters (ruff enforces).
Files:
src/synthorg/api/controllers/setup_agents.pysrc/synthorg/api/controllers/setup.pysrc/synthorg/templates/loader.pysrc/synthorg/api/controllers/setup_models.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use pytest markers:@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow. Maintain 80% minimum coverage. Useasyncio_mode = 'auto'(no manual@pytest.mark.asyncio). Set 30-second global timeout per test. Run tests with-n autofor parallelism via pytest-xdist; never run sequentially. Use Hypothesis for property-based testing with@givenand@settings,HYPOTHESIS_PROFILEenv var (ci=50 examples, dev=1000 examples). Never skip flaky tests -- fix them fundamentally by mockingtime.monotonic(),asyncio.sleep(), or usingasyncio.Event().wait()for blocking operations.
Use vendor-agnostic names in tests:test-provider,test-small-001,large/medium/smallaliases instead of real vendor names (Anthropic, OpenAI, Claude, GPT, etc.). Vendor names appear only in operations design page,.claude/files, third-party imports, and provider presets.
Files:
tests/unit/templates/test_loader.pytests/unit/api/controllers/test_setup.py
**/*.{md,mdx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always read the relevant
docs/design/page before implementing any feature or planning any issue. The design spec is the starting point for architecture, data models, and behavior. If implementation deviates from spec, alert the user and explain why -- user decides whether to proceed or update the spec. Never silently diverge. When approved deviations occur, update the relevantdocs/design/page to reflect the new reality.
Files:
docs/design/organization.md
docs/design/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Design spec pages are mandatory reading before implementing features. Design specs pages are the starting point for architecture, data models, and behavior. When implementation deviates from spec, alert the user with reasoning. Update the relevant design page when approved deviations occur.
Files:
docs/design/organization.md
🧠 Learnings (32)
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : For dict/list fields in frozen Pydantic models, rely on frozen=True for field reassignment prevention and copy.deepcopy() at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, serializing for persistence).
Applied to files:
src/synthorg/api/controllers/setup_agents.py
📚 Learning: 2026-03-28T18:10:43.542Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.542Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. Do not recreate status dots inline, build card-with-header layouts from scratch, create metric displays manually, render initials circles manually, create complex (>8 line) JSX inside `.map()` blocks, or use `rgba()` with hardcoded values instead of design token variables.
Applied to files:
web/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/ProvidersStep.tsx
📚 Learning: 2026-03-28T18:10:43.543Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.543Z
Learning: Applies to web/src/components/ui/*.{ts,tsx} : New shared components in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty), exported props as a TypeScript interface, design tokens exclusively (no hardcoded colors, fonts, or spacing), and use `cn()` from `@/lib/utils` for conditional class merging.
Applied to files:
web/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/ProvidersStep.tsx
📚 Learning: 2026-03-28T18:10:43.543Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.543Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use design token rules: colors via Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, `text-success`, `bg-danger`) or CSS variables (`var(--so-accent)`), typography via `font-sans` or `font-mono`, spacing via density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind, shadows/borders via token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`). Never hardcode hex values, set fontFamily directly, or hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateCard.tsx
📚 Learning: 2026-03-28T18:10:43.543Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.543Z
Learning: Applies to tests/**/*.py : Use vendor-agnostic names in tests: `test-provider`, `test-small-001`, `large`/`medium`/`small` aliases instead of real vendor names (Anthropic, OpenAI, Claude, GPT, etc.). Vendor names appear only in operations design page, `.claude/` files, third-party imports, and provider presets.
Applied to files:
tests/unit/api/controllers/test_setup.pyweb/src/__tests__/stores/setup-wizard.test.ts
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
src/synthorg/api/controllers/setup.pysrc/synthorg/templates/loader.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/**/*.py : Package structure: src/synthorg/ organized as: api/ (REST+WebSocket, Litestar), auth/ (auth subpackage), backup/ (scheduled/manual backups), budget/ (cost tracking, CFO), cli/ (superseded by Go CLI), communication/ (message bus, meetings), config/ (YAML loading), core/ (domain models, resilience config), engine/ (orchestration, task state, coordination, approval gates, stagnation detection, context budget, compaction), hr/ (hiring, performance, promotion), memory/ (pluggable backend, Mem0, retrieval, consolidation), persistence/ (operational data, SQLite, settings), observability/ (logging, correlation, sinks), providers/ (LLM abstraction, LiteLLM, auth types, presets, runtime CRUD), settings/ (runtime-editable, typed definitions, encryption, config bridge), security/ (SecOps, rule engine, output scanning, progressive trust, autonomy levels), templates/ (company templates, personalities), tools/ (registry, built-in tools, git, sandbox, code_runner, MCP...
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Applies to src/synthorg/hr/**/*.py : HR package (hr/): hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, LLM calibration, collaboration overrides, trend detection), promotion/demotion (criteria evaluation, approval strategies, model mapping)
Applied to files:
src/synthorg/api/controllers/setup.pyweb/src/__tests__/stores/setup-wizard.test.ts
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/hr/**/*.py : HR engine must provide: hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, trend detection), promotion/demotion
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-26T15:18:16.848Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-26T15:18:16.848Z
Learning: Applies to src/synthorg/api/**/*.py : Litestar API must include setup wizard, auth/, auto-wiring, and lifecycle management
Applied to files:
src/synthorg/api/controllers/setup.pydocs/design/organization.md
📚 Learning: 2026-03-28T18:10:43.543Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.543Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must have: `from synthorg.observability import get_logger` then `logger = get_logger(__name__)`. Use event name constants from `synthorg.observability.events.<domain>` modules (e.g., `API_REQUEST_STARTED`, `TOOL_INVOKE_START`). Always use structured kwargs: `logger.info(EVENT, key=value)`. Log all error paths at WARNING or ERROR with context before raising, all state transitions at INFO, and DEBUG for object creation and key function flow. Pure data models, enums, and re-exports do not need logging.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-17T06:30:14.180Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:30:14.180Z
Learning: Applies to src/synthorg/security/**/*.py : Security module includes SecOps agent, rule engine (soft-allow/hard-deny), audit log, output scanner, risk classifier, autonomy levels (4 strategies), timeout policies.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-17T06:43:14.114Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions. Pure data models, enums, and re-exports do NOT need logging.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic must import `from synthorg.observability import get_logger` and define `logger = get_logger(__name__)`
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-20T11:18:48.128Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T11:18:48.128Z
Learning: Applies to src/synthorg/**/*.py : Every module with business logic MUST have `from synthorg.observability import get_logger` followed by `logger = get_logger(__name__)`.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-28T18:10:43.543Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.543Z
Learning: Applies to src/synthorg/api/**/*.py : Use RFC 9457 errors in the REST API. Implement role-based access control (RBAC) guards in the API layer.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/api/**/*.py : REST API: Litestar framework, controllers with guards, channels for WebSocket, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint. RFC 9457 structured errors (ErrorCategory, ErrorCode, ErrorDetail, ProblemDetail, CATEGORY_TITLES, category_title, category_type_uri, content negotiation).
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-18T21:23:23.586Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T21:23:23.586Z
Learning: Applies to src/synthorg/**/*.py : Event names: always use constants from the domain-specific module under synthorg.observability.events (e.g., API_REQUEST_STARTED from events.api, TOOL_INVOKE_START from events.tool). Import directly from synthorg.observability.events.<domain>.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-28T18:10:43.543Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T18:10:43.543Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 models (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing redundant fields (e.g., `TokenUsage.total_tokens`). Use `NotBlankStr` from `core.types` for all identifier/name fields (including optional `NotBlankStr | None` and tuple variants) instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T18:42:17.990Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:42:17.990Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-17T11:41:02.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T11:41:02.964Z
Learning: Applies to src/**/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing + validating redundant fields. Use `NotBlankStr` for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to **/*.py : Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use computed_field for derived values instead of storing + validating redundant fields. Use NotBlankStr (from core.types) for all identifier/name fields — including optional (NotBlankStr | None) and tuple (tuple[NotBlankStr, ...]) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-26T15:18:16.848Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-26T15:18:16.848Z
Learning: Applies to src/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. Use `computed_field` for derived values instead of storing redundant fields. Use `NotBlankStr` for all identifier/name fields.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 with adopted conventions: use computed_field for derived values instead of storing + validating redundant fields; use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/core/**/*.py : Core module must contain shared domain models, base classes, resilience config (RetryConfig, RateLimiterConfig)
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/providers/**/*.py : Providers: LLM provider abstraction (LiteLLM adapter), auth types (api_key/oauth/custom_header/none), presets (PROVIDER_PRESETS), runtime CRUD (ProviderManagementService with asyncio.Lock serialization), hot-reload via AppState swap.
Applied to files:
web/src/stores/setup-wizard.ts
🔇 Additional comments (15)
web/src/pages/setup/SetupAgentCard.tsx (1)
66-66: LGTM!The conditional rendering of the Level pill when
agent.levelis truthy and the defensive nullish coalescing to empty strings formodel_providerandmodel_idcorrectly handle the newly nullable fields. TheAgentModelPickercomponent already treats empty strings as "no selection" (perAgentModelPicker.tsxline 34), so this integration is sound.Also applies to: 80-81
src/synthorg/api/controllers/setup_agents.py (2)
453-455: LGTM!The normalization logic correctly converts empty/whitespace-only values to
None, aligning with the nullable field types inSetupAgentSummary. This ensures the API returnsnullrather than empty strings, which the frontend now handles appropriately.
282-282: No action required — PEP 758 except syntax is correct for this project.The
except MemoryError, RecursionError:syntax (without parentheses) is valid for this codebase, which targets Python 3.14+ perrequires-python = ">=3.14"in pyproject.toml. This syntax follows PEP 758 and is enforced by ruff (target-version = "py314").tests/unit/templates/test_loader.py (1)
124-131: LGTM!The test comprehensively validates the new structural metadata fields. The autonomy level values match the
AutonomyLevelenum definition, and the assertions appropriately check type and range constraints.tests/unit/api/controllers/test_setup.py (1)
56-70: LGTM!The test assertions correctly validate the new template metadata fields returned by the API, ensuring the contract between the backend and frontend is properly enforced. The allowed
autonomy_levelvalues align with theAutonomyLevelenum.web/src/__tests__/utils/template-categories.test.ts (1)
18-21: LGTM!The test helper correctly includes the new structural metadata fields with sensible defaults that match the backend (
autonomy_level: 'semi',workflow: 'agile_kanban'). The...overridesplacement allows tests to override these values as needed.web/src/pages/setup/TemplateCard.tsx (2)
80-98: LGTM!The structural metadata grid is well-implemented:
- Uses design tokens (
text-muted-foreground,text-accent,grid-cols-2)- Provides accessible
titleattributes for icons- Gracefully falls back to raw values for unknown autonomy/workflow types
- Correct pluralization logic for counts
8-20: WORKFLOW_LABELS has complete coverage of all template values.The
AUTONOMY_LABELSkeys correctly match theAutonomyLevelenum values. Verification confirms thatWORKFLOW_LABELScovers all workflow values used in builtin templates (agile_kanbanandkanban). The object also includesevent_drivenandwaterfallfor extensibility, and the fallback|| template.workflow_typehandles any future values gracefully.web/src/api/types.ts (2)
1226-1229: LGTM!The new template metadata fields are correctly typed. Using
stringforautonomy_levelandworkflow(rather than union types) is pragmatic since the backend returns these as strings and the frontend uses lookup maps with fallback behavior.
1253-1255: LGTM!Making
level,model_provider, andmodel_idnullable correctly reflects the backend change where these fields can beNonewhen values are missing or empty.src/synthorg/templates/loader.py (4)
79-96: LGTM!The
TemplateInfodataclass extension is well-documented and uses sensible defaults that match the schema defaults (autonomy_level="semi",workflow="agile_kanban"). The field descriptions in the docstring are clear and helpful.
133-145: LGTM!The template metadata extraction is clean and correctly accesses the new fields. Using
tmpl.autonomy.get("level", "semi")is safe sinceCompanyTemplate.autonomyis guaranteed to be a dict viadefault_factory(perschema.pyline 351-354).
166-178: LGTM!User template collection mirrors the builtin template logic correctly, ensuring consistent metadata extraction across both template sources.
514-514: PEP 758 except syntax is compatible. Theexcept TypeError, ValueError:syntax is correct for Python 3.14+, andpyproject.tomlexplicitly requires Python 3.14+. No changes needed.src/synthorg/api/controllers/setup_models.py (1)
182-184: Nice API contract cleanup.Using
NotBlankStr | Nonehere is much cleaner than sentinel empty strings and lines up with the setup UI's conditional rendering.
…vider form reuse Template step: add search/category/size filter bar, split into Recommended and Other Templates sections, show agent count, department count, autonomy level, and workflow on each card. Backend TemplateInfoResponse now exposes these structural fields from the template YAML. Provider step: fix 0 models bug by passing the probe-detected base URL when creating from auto-detected presets (was falling back to preset default URL which fails from Docker). Replace simplified ProviderAddForm with the full ProviderFormDrawer from Settings, decoupled via an overrides prop -- now supports subscription auth (Claude Max), custom base URLs (remote Ollama), and custom providers in the wizard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, a11y Pre-reviewed by 7 agents, 16 findings addressed: - Use AutonomyLevel enum for autonomy_level field (was bare str) - Use NotBlankStr for workflow field in TemplateInfoResponse - Fix SetupAgentSummary: level -> SeniorityLevel|None, model_provider/model_id -> NotBlankStr|None - Delete dead ProviderAddForm.tsx (replaced by ProviderFormDrawer) - Add locked to AUTONOMY_LABELS in TemplateCard - Log discovery errors in createProviderFromPresetFull (was silently swallowed) - Add aria-label and focus:ring to template filter inputs for a11y - Update design spec to describe new template step UX - Add tests for createProviderFromPresetFull and createProviderCustom - Add assertions for new template structural fields in Python and TS tests - Add createProvider to setup-wizard test mock - Condense create_company function to stay under 50-line limit Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical: AutonomyLevel enum conversion in loader.py with fallback for invalid user template values. Major: fix empty catch blocks, add try/catch to probe methods, prevent fetchProviders from clearing discovery errors, fix useEffect overrides dependency, add no-models warning to createProviderFromPresetFull, replace raw HTML inputs with shared InputField/SelectField, multi-keyword template search, stale docstrings, TemplateInfo strong types, extract _template_info_from_loaded helper, base_url scheme validation on provider DTOs, fix clear_api_key edit logic. Docs: update user_guide and organization.md. Tests: add SetupAgentSummary nullable/blank validation, agent_dict_to_summary empty-to-None, zero-model discovery path. Split test_setup.py (1800 lines) into 5 files under 800 lines each. Accessibility: aria-hidden on decorative Lucide icons. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ff33fa8 to
ee6b6b4
Compare
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/unit/api/controllers/conftest.py`:
- Around line 23-26: The test mock for the management service is too permissive;
replace mock_mgmt = MagicMock() with a spec-constrained mock of
ProviderManagementService (e.g., MagicMock(spec=ProviderManagementService) or
use unittest.mock.create_autospec(ProviderManagementService, instance=True)) so
only real methods exist, then set mock_mgmt.list_providers =
AsyncMock(return_value={"test-provider": mock_provider_config}) as before;
ensure ProviderManagementService is imported in the test file so the spec is
applied.
In `@tests/unit/api/controllers/test_setup_dtos.py`:
- Around line 18-26: The test currently passes a lowercase personality_preset so
it doesn't confirm normalization; update the SetupAgentRequest instantiation to
use a mixed-case preset (e.g., "Visionary_Leader" or "Visionary_Leader") and
then assert that req.personality_preset equals the lowercase normalized value
"visionary_leader" to lock in the normalization behavior for the
SetupAgentRequest validator.
In `@tests/unit/templates/test_loader.py`:
- Around line 124-131: In test_structural_metadata_populated, replace the
string-literal check of autonomy_level with comparisons against the
AutonomyLevel enum to match TemplateInfo.autonomy_level typing: import
AutonomyLevel and assert t.autonomy_level in (AutonomyLevel.FULL,
AutonomyLevel.SEMI, AutonomyLevel.SUPERVISED, AutonomyLevel.LOCKED) (or use a
membership check against set(AutonomyLevel)); keep other assertions the same so
the test verifies enum-backed values, referencing the test function name
test_structural_metadata_populated and the TemplateInfo.autonomy_level field.
In `@web/src/pages/setup/TemplateCard.tsx`:
- Around line 94-96: The displayed workflow fallback is showing raw storage keys
(template.workflow) instead of a human-friendly label; update the rendering in
TemplateCard to format the fallback via a small helper (e.g., humanizeWorkflow)
rather than echoing template.workflow directly. Implement
humanizeWorkflow(template.workflow) to replace underscores/hyphens with spaces,
trim, and Title Case or capitalize each word, then use
WORKFLOW_LABELS[template.workflow] ?? humanizeWorkflow(template.workflow) in the
span so unknown workflows are shown prettified.
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 290-296: The onChange handler for InputField is using an
unnecessary type assertion "(e.target as HTMLInputElement).value", indicating a
mismatch between InputField's declared onChange type and the actual event;
update InputField's props to type its onChange as (e:
React.ChangeEvent<HTMLInputElement>) => void (or provide a separate
onValueChange: (value: string) => void) so callers like the one using
setSearchQuery can simply do onChange={e => setSearchQuery(e.target.value)}
without casting; locate the InputField component/props definition and adjust the
event signature (or add the value callback) and update usages including this
TemplateStep onChange to remove the cast.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e7cd2dd1-3c5c-48bd-9f82-13af3d8bb7cf
📒 Files selected for processing (25)
docs/design/organization.mddocs/user_guide.mdsrc/synthorg/api/controllers/setup.pysrc/synthorg/api/controllers/setup_agents.pysrc/synthorg/api/controllers/setup_models.pysrc/synthorg/api/dto.pysrc/synthorg/templates/loader.pytests/unit/api/controllers/conftest.pytests/unit/api/controllers/test_setup.pytests/unit/api/controllers/test_setup_agent_ops.pytests/unit/api/controllers/test_setup_dtos.pytests/unit/api/controllers/test_setup_locales.pytests/unit/api/controllers/test_setup_personality.pytests/unit/templates/test_loader.pyweb/src/__tests__/stores/setup-wizard.test.tsweb/src/__tests__/utils/template-categories.test.tsweb/src/api/types.tsweb/src/pages/providers/ProviderFormDrawer.tsxweb/src/pages/setup/ProviderAddForm.tsxweb/src/pages/setup/ProviderProbeResults.tsxweb/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/SetupAgentCard.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/stores/setup-wizard.ts
💤 Files with no reviewable changes (1)
- web/src/pages/setup/ProviderAddForm.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build Backend
- GitHub Check: Build Web
- GitHub Check: Test (Python 3.14)
- GitHub Check: Dashboard Test
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/__tests__/utils/template-categories.test.tsweb/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/api/types.tsweb/src/pages/setup/ProviderProbeResults.tsxweb/src/__tests__/stores/setup-wizard.test.tsweb/src/stores/setup-wizard.tsweb/src/pages/providers/ProviderFormDrawer.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/__tests__/utils/template-categories.test.tsweb/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/api/types.tsweb/src/pages/setup/ProviderProbeResults.tsxweb/src/__tests__/stores/setup-wizard.test.tsweb/src/stores/setup-wizard.tsweb/src/pages/providers/ProviderFormDrawer.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/ProviderProbeResults.tsxweb/src/pages/providers/ProviderFormDrawer.tsx
**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Documentation must follow Markdown conventions: use consistent heading levels, link to relevant sections, include code examples where appropriate, and keep content up-to-date with implementation changes.
Files:
docs/user_guide.mddocs/design/organization.md
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Use PEP 758 except syntax:except A, B:(no parentheses) on Python 3.14. Do NOT usefrom __future__ import annotations—Python 3.14 has PEP 649 native lazy annotations.
All public functions and classes must have type hints. Use mypy strict mode. Google-style docstrings are required on all public classes and functions (enforced by ruff D rules).
Every module with business logic must include:from synthorg.observability import get_loggerthenlogger = get_logger(__name__). Always use constants from domain-specific modules undersynthorg.observability.events(e.g.,API_REQUEST_STARTEDfromevents.api). Use structured kwargs:logger.info(EVENT, key=value)— neverlogger.info("msg %s", val). Never useimport loggingorprint()in application code.
Use Pydantic v2 (BaseModel,model_validator,computed_field,ConfigDict). Use@computed_fieldfor derived values instead of storing redundant fields. UseNotBlankStrfromcore.typesfor all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Create new objects rather than mutating existing ones. For non-Pydantic internal collections (registries,BaseTool), usecopy.deepcopy()at construction and wrap withMappingProxyTypefor read-only enforcement. Fordict/listfields in frozen Pydantic models, usecopy.deepcopy()at system boundaries (tool execution, LLM provider serialization, inter-agent delegation, persistence serialization).
Use frozen Pydantic models for config/identity. Use separate mutable-via-copy models (viamodel_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model.
Preferasyncio.TaskGroupfor fan-out/fan-in parallel operations in new code (e.g., multiple tool invocations, parallel agent calls). Prefer structured concurrency over barecreate_task.
Keep functions under 50 lines and files under 800 lines. Handle errors exp...
Files:
src/synthorg/api/controllers/setup_agents.pysrc/synthorg/api/dto.pysrc/synthorg/api/controllers/setup.pysrc/synthorg/api/controllers/setup_models.pysrc/synthorg/templates/loader.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow. Maintain 80% minimum code coverage (enforced in CI). Always run pytest with-n autofor parallel execution. Use@pytest.mark.parametrizefor testing similar cases. Useasyncio_mode = "auto"(no manual@pytest.mark.asyncioneeded).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in tests or project code—use generic names liketest-provider,test-small-001,example-provider,example-large-001,large/medium/small. Vendor names may only appear in: (1) Operations design page, (2).claude/files, (3) third-party import paths, (4) provider presets.
Never skip, dismiss, or ignore flaky tests—always fix them fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()instead of widening margins. For tasks that must block indefinitely until cancelled, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_loader.pytests/unit/api/controllers/conftest.pytests/unit/api/controllers/test_setup_dtos.pytests/unit/api/controllers/test_setup.pytests/unit/api/controllers/test_setup_personality.pytests/unit/api/controllers/test_setup_agent_ops.pytests/unit/api/controllers/test_setup_locales.py
docs/design/**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
Before implementing any feature or planning any issue, always read the relevant
docs/design/page referenced inDESIGN_SPEC.md. The design spec is the starting point for architecture, data models, and behavior. If implementation deviates from the spec, alert the user and explain why—user decides whether to proceed or update the spec. When approved deviations occur, update the relevantdocs/design/page to reflect the new reality.
Files:
docs/design/organization.md
🧠 Learnings (32)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/SetupAgentCard.tsxweb/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/api/dto.pysrc/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing redundant fields. Use `NotBlankStr` from `core.types` for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Applied to files:
src/synthorg/api/dto.pysrc/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.
Applied to files:
src/synthorg/api/dto.pysrc/synthorg/api/controllers/setup_models.pysrc/synthorg/templates/loader.py
📚 Learning: 2026-03-15T18:42:17.990Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:42:17.990Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`
Applied to files:
src/synthorg/api/dto.pysrc/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/providers/**/*.py : Providers: LLM provider abstraction (LiteLLM adapter), auth types (api_key/oauth/custom_header/none), presets (PROVIDER_PRESETS), runtime CRUD (ProviderManagementService with asyncio.Lock serialization), hot-reload via AppState swap.
Applied to files:
tests/unit/api/controllers/conftest.pyweb/src/__tests__/stores/setup-wizard.test.tsweb/src/stores/setup-wizard.ts
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to src/synthorg/api/**/*.py : API package (api/): Litestar REST + WebSocket with controllers, guards, channels, JWT + API key + WS ticket auth, approval gate integration, coordination endpoint, collaboration endpoint, settings endpoint, provider management endpoint (CRUD + test + presets), backup endpoint, RFC 9457 structured errors, AppState hot-reload slots, service auto-wiring (Phase 1 at construction, Phase 2 on startup), lifecycle helpers
Applied to files:
tests/unit/api/controllers/conftest.py
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to src/synthorg/templates/**/*.py : Templates: pre-built company templates, personality presets, and builder.
Applied to files:
src/synthorg/api/controllers/setup.py
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Applies to src/synthorg/hr/**/*.py : HR package (hr/): hiring, firing, onboarding, offboarding, agent registry, performance tracking (task metrics, collaboration scoring, LLM calibration, collaboration overrides, trend detection), promotion/demotion (criteria evaluation, approval strategies, model mapping)
Applied to files:
src/synthorg/api/controllers/setup.pyweb/src/__tests__/stores/setup-wizard.test.ts
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/ProvidersStep.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Property-based testing: Python uses Hypothesis (given + settings). Hypothesis profiles: ci (200 examples, default) and dev (1000 examples), controlled via HYPOTHESIS_PROFILE env var. Run dev profile: HYPOTHESIS_PROFILE=dev uv run python -m pytest tests/ -m unit -n auto -k properties.
Applied to files:
tests/unit/api/controllers/test_setup.py
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateCard.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-17T11:41:02.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T11:41:02.964Z
Learning: Applies to src/**/*.py : Models: Pydantic v2 (`BaseModel`, `model_validator`, `computed_field`, `ConfigDict`). Use `computed_field` for derived values instead of storing + validating redundant fields. Use `NotBlankStr` for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to **/*.py : Models: Pydantic v2 (BaseModel, model_validator, computed_field, ConfigDict). Use computed_field for derived values instead of storing + validating redundant fields. Use NotBlankStr (from core.types) for all identifier/name fields — including optional (NotBlankStr | None) and tuple (tuple[NotBlankStr, ...]) variants — instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-26T15:18:16.848Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-26T15:18:16.848Z
Learning: Applies to src/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. Use `computed_field` for derived values instead of storing redundant fields. Use `NotBlankStr` for all identifier/name fields.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 with adopted conventions: use computed_field for derived values instead of storing + validating redundant fields; use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to src/synthorg/core/**/*.py : Core module must contain shared domain models, base classes, resilience config (RetryConfig, RateLimiterConfig)
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state
Applied to files:
src/synthorg/api/controllers/setup_models.py
📚 Learning: 2026-03-19T07:12:14.508Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:12:14.508Z
Learning: Applies to docs/design/*.md : Design spec pages: 7 pages in `docs/design/` — index, agents, organization, communication, engine, memory, operations
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-16T06:24:56.341Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T06:24:56.341Z
Learning: Applies to docs/design/**/*.md : Design specification pages in `docs/design/` must be consulted before implementing features (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Documentation source in `docs/` (Markdown, built with Zensical). Design spec in `docs/design/` (7 pages: index, agents, organization, communication, engine, memory, operations). Architecture in `docs/architecture/` (overview, tech-stack, decision log). Roadmap in `docs/roadmap/`. Security in `docs/security.md`. Licensing in `docs/licensing.md`. Reference in `docs/reference/`. REST API reference in `docs/rest-api.md`. Library reference in `docs/api/` (auto-generated from docstrings). Custom templates in `docs/overrides/`. Config in `mkdocs.yml`.
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-14T15:43:05.601Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-14T15:43:05.601Z
Learning: Applies to docs/** : Docs source in docs/ (Markdown, built with Zensical); design spec in docs/design/ (7 pages: index, agents, organization, communication, engine, memory, operations)
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-19T07:13:44.964Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-19T07:13:44.964Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue — DESIGN_SPEC.md is a pointer file linking to 7 design pages (Agents, Organization, Communication, Engine, Memory, Operations)
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to docs/design/**/*.md : Before implementing any feature or planning any issue, always read the relevant `docs/design/` page referenced in `DESIGN_SPEC.md`. The design spec is the starting point for architecture, data models, and behavior. If implementation deviates from the spec, alert the user and explain why—user decides whether to proceed or update the spec. When approved deviations occur, update the relevant `docs/design/` page to reflect the new reality.
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-18T08:23:08.912Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-18T08:23:08.912Z
Learning: When approved deviations occur, update the relevant `docs/design/` page to reflect the new reality.
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-21T11:08:01.542Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T11:08:01.542Z
Learning: When implementation deviates from the spec (better approach found, scope evolved, etc.), alert the user and explain why — user decides whether to proceed or update the spec. Do NOT silently diverge — every deviation needs explicit user approval.
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Always read the relevant `docs/design/` page before implementing any feature or planning any issue. DESIGN_SPEC.md is a pointer file linking to the 7 design pages (index, agents, organization, communication, engine, memory, operations).
Applied to files:
docs/design/organization.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Handle errors explicitly, never silently swallow. Validate at system boundaries (user input, external APIs, config files).
Applied to files:
src/synthorg/templates/loader.py
📚 Learning: 2026-03-17T06:43:14.114Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T06:43:14.114Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions. Pure data models, enums, and re-exports do NOT need logging.
Applied to files:
src/synthorg/templates/loader.py
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, entry/exit of key functions.
Applied to files:
src/synthorg/templates/loader.py
📚 Learning: 2026-03-16T07:22:28.134Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-16T07:22:28.134Z
Learning: Applies to src/synthorg/**/*.py : All error paths must log at WARNING or ERROR with context before raising. All state transitions must log at INFO. DEBUG for object creation, internal flow, and key function entry/exit
Applied to files:
src/synthorg/templates/loader.py
🔇 Additional comments (33)
src/synthorg/api/dto.py (2)
532-543: LGTM! Clean base URL validation.The helper correctly validates that
base_urluseshttp/httpsschemes and includes a host. The None-passthrough ensures optional fields work correctly.
584-588: Consistent validator wiring across DTOs.Good use of a shared helper function to avoid duplication. The validator is correctly applied to all three DTOs that accept
base_url.tests/unit/api/controllers/conftest.py (1)
9-31: Helper structure is appropriate for test mocking.The pattern of returning the original for restoration is clean. The docstring could be more descriptive about when to use this helper.
src/synthorg/templates/loader.py (4)
113-138: Well-structured helper for template metadata extraction.The helper properly handles:
- Fallback to
AutonomyLevel.SEMIon invalid values- Centralized construction of
TemplateInfofor both builtin and user templates- Consistent field mapping from
LoadedTemplatetoTemplateInfo
79-95: TemplateInfo fields and defaults align with schema.The defaults (
0,0,AutonomyLevel.SEMI,"agile_kanban") matchCompanyTemplateschema defaults, ensuring consistency when fields are missing.
519-526: LGTM! Correct PEP 758 except syntax.The
except TypeError, ValueError:syntax follows the coding guidelines for Python 3.14.
159-163: Consistent helper usage in template listing.Both
list_templates()and_collect_user_templates()correctly use the helper with appropriate source literals.docs/design/organization.md (1)
339-354: Design spec properly updated to reflect implementation.The Company Builder section now accurately documents:
- Template grid with category/size filters and recommended/others grouping
- Structural metadata cards (agent count, departments, autonomy level, workflow)
- Provider auto-detection with probe-detected base URLs
- Full provider form supporting API key, subscription, custom configurations, and manual base URLs
This addresses the past review comment about documenting custom base URL support.
docs/user_guide.md (1)
77-79: User guide updates align with design spec.The Template and Providers step descriptions now accurately reflect the new UX:
- Searchable grid with filters and grouping
- Structural metadata cards
- Auto-detection with re-scan capability
- Full provider form supporting multiple auth types
web/src/pages/setup/SetupAgentCard.tsx (2)
66-66: Correct nullable handling for level field.Conditionally rendering the Level
StatPillonly whenagent.levelis truthy properly handles the backend change wherelevelis now nullable.
80-81: Proper nullish coalescing for picker props.Using
?? ''correctly converts nullablemodel_providerandmodel_idto empty strings expected byAgentModelPicker.src/synthorg/api/controllers/setup_agents.py (2)
453-457: Nullable field normalization is correct.The pattern
(x or "").strip() or Noneproperly normalizes empty/whitespace values toNone. The# type: ignore[arg-type]on line 453 is acceptable since the expression technically returnsstr | Nonewhile the field expectsNotBlankStr | None, but the logic ensures non-empty strings at runtime.
282-283: Correct PEP 758 syntax and appropriate exception handling.Re-raising
MemoryErrorandRecursionErroris the right approach—these should not be silently handled.web/src/pages/setup/ProvidersStep.tsx (1)
104-124: Nice consolidation onto the shared provider drawer.Reusing
ProviderFormDrawerhere removes the setup-only form divergence and keeps advanced auth/base URL behavior in one path.Also applies to: 201-206
web/src/api/types.ts (1)
1226-1229: ...web/src/pages/setup/TemplateStep.tsx (3)
71-102: LGTM!The
TemplateGridcomponent is well-extracted, avoiding complex JSX inside.map()as per coding guidelines. Props are cleanly typed and the grid layout uses proper semantic Tailwind classes (gap-grid-gap).
27-43: LGTM!The
SIZE_OPTIONSconstant andmatchesSizehelper are clear and correctly implement agent-count bucket filtering with proper boundary handling.
175-206: LGTM!The filtering and recommended/others split logic is correctly memoized with appropriate dependencies. The multi-keyword search implementation using
every()provides intuitive AND-matching behavior.src/synthorg/api/controllers/setup_models.py (2)
127-144: LGTM!The new template metadata fields are well-typed with appropriate constraints (
ge=0for counts), use theAutonomyLevelenum for type safety, andNotBlankStrfor the workflow field as per coding guidelines.
182-184: LGTM!Changing
level,model_provider, andmodel_idto nullable types (SeniorityLevel | None,NotBlankStr | None) correctly models the domain where these values may not be specified. This aligns with the normalization logic inagent_dict_to_summary.web/src/pages/setup/ProviderProbeResults.tsx (2)
77-88: LGTM!Good improvement to error handling - logging errors before they're swallowed prevents silent failures during preset addition. The
detectedUrlparameter is correctly forwarded through the callback chain.
111-124: LGTM!Extracting
probeResultbefore the JSX improves readability and ensures consistent reference within the rendered component.web/src/stores/setup-wizard.ts (3)
626-669: LGTM!The
createProviderFromPresetFullaction correctly implements zero-model detection after auto-discovery (lines 642-650), addressing the prior review concern. The error messaging is consistent withcreateProviderFromPreset.
697-721: LGTM!Wrapping probe operations in
try/catch/finallyensuresprobingis always reset, preventing the UI from getting stuck in a loading state ifrunProbeAllthrows unexpectedly.
671-684: Add model auto-discovery tocreateProviderCustomfor consistency with preset-based creation.
createProviderCustomlacks the auto-discovery logic present increateProviderFromPresetFull. The preset flow explicitly discovers models whenprovider.models.length === 0, with comments noting this is needed for local providers withauth_type: 'none'where discovery can be slow. Custom providers created with similar configurations would have the same issue—they could return 0 models on creation without attempting discovery, leaving users with non-functional providers.Consider adding the same discovery logic (check
provider.models.length === 0, calldiscoverModels, refresh, handle errors) to match the preset flow, or document why custom providers intentionally skip this step.tests/unit/api/controllers/test_setup_personality.py (1)
15-129: LGTM!Comprehensive test coverage for personality preset operations including edge cases (invalid preset, out-of-range, post-completion). The
try/finallypattern properly restores state, and the tests use generic provider names per guidelines.tests/unit/api/controllers/test_setup_locales.py (2)
189-276: LGTM!Thorough unit tests for
check_has_name_localescovering database presence, source verification, and error handling paths. The mock restoration intry/finallyblocks prevents test pollution.
279-463: LGTM!Excellent coverage of
read_name_localesedge cases including JSON decode errors, non-list JSON, invalid locale filtering, and theresolve=True/Falsebehavior. Tests correctly verify the sentinel-to-concrete-locales resolution path.tests/unit/api/controllers/test_setup_agent_ops.py (2)
117-176: LGTM!These unit tests for
agent_dict_to_summarydirectly verify the empty/whitespace-to-None normalization behavior documented in the helper function, ensuring the nullable field contract is maintained.
74-114: LGTM!The happy-path test correctly mocks the provider management layer and verifies all expected response fields. The
try/finallypattern ensures proper cleanup.web/src/pages/providers/ProviderFormDrawer.tsx (3)
53-53: LGTM!Extracting
fetchPresetsFnand depending on it (rather than the entireoverridesobject) correctly fixes the refetch loop identified in the prior review. The dependency array is now minimal and stable.Also applies to: 74-78
18-27: LGTM!The
ProviderFormOverridesinterface is well-designed for dependency injection, with optional callbacks for create/update operations while requiring the preset-related props that are always needed in create mode.
202-214: No issue—the clearing logic is intentional and safe.The backend validator explicitly rejects simultaneous credential set and clear (
api_key and clear_api_key are mutually exclusive). When the auth type switches, the frontend sendsclear_api_key: truewithapi_key: undefined, which passes validation. The backend's_apply_credential_updates()then respects the change: it clears old credentials when the new auth type doesn't support them. This is the intended behavior—stale credentials should not persist across auth type changes.> Likely an incorrect or invalid review comment.
| mock_mgmt = MagicMock() | ||
| mock_mgmt.list_providers = AsyncMock( | ||
| return_value={"test-provider": mock_provider_config}, | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider using spec or spec_set for the mock.
The mock only explicitly implements list_providers(). If any controller method calls other ProviderManagementService methods (e.g., get_provider(), create_provider()), tests will silently pass with MagicMock return values instead of raising AttributeError.
Using spec=ProviderManagementService would make the mock safer by restricting it to actual service methods.
♻️ Proposed improvement
+from synthorg.providers.management.service import ProviderManagementService
+
def setup_mock_providers(
test_client: TestClient[Any],
) -> tuple[Any, Any]:
"""Wire up mock providers on the app state. Returns (app_state, original)."""
# ... model setup ...
- mock_mgmt = MagicMock()
+ mock_mgmt = MagicMock(spec=ProviderManagementService)
mock_mgmt.list_providers = AsyncMock(
return_value={"test-provider": mock_provider_config},
)📝 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.
| mock_mgmt = MagicMock() | |
| mock_mgmt.list_providers = AsyncMock( | |
| return_value={"test-provider": mock_provider_config}, | |
| ) | |
| from synthorg.providers.management.service import ProviderManagementService | |
| def setup_mock_providers( | |
| test_client: TestClient[Any], | |
| ) -> tuple[Any, Any]: | |
| """Wire up mock providers on the app state. Returns (app_state, original).""" | |
| # ... model setup ... | |
| mock_mgmt = MagicMock(spec=ProviderManagementService) | |
| mock_mgmt.list_providers = AsyncMock( | |
| return_value={"test-provider": mock_provider_config}, | |
| ) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/unit/api/controllers/conftest.py` around lines 23 - 26, The test mock
for the management service is too permissive; replace mock_mgmt = MagicMock()
with a spec-constrained mock of ProviderManagementService (e.g.,
MagicMock(spec=ProviderManagementService) or use
unittest.mock.create_autospec(ProviderManagementService, instance=True)) so only
real methods exist, then set mock_mgmt.list_providers =
AsyncMock(return_value={"test-provider": mock_provider_config}) as before;
ensure ProviderManagementService is imported in the test file so the spec is
applied.
| req = SetupAgentRequest( | ||
| name="Alice", | ||
| role="CEO", | ||
| personality_preset="visionary_leader", | ||
| model_provider="test-provider", | ||
| model_id="model-001", | ||
| ) | ||
| # Validator normalizes to lowercase | ||
| assert req.personality_preset == "visionary_leader" |
There was a problem hiding this comment.
This doesn't verify the lowercase normalization.
Line 21 already passes a lowercase preset, so the assertion on Line 26 would still pass if the validator stopped normalizing and only validated membership. Feed a mixed-case value here to lock the behavior down.
🧪 Tighten the normalization assertion
req = SetupAgentRequest(
name="Alice",
role="CEO",
- personality_preset="visionary_leader",
+ personality_preset="Visionary_Leader",
model_provider="test-provider",
model_id="model-001",
)
# Validator normalizes to lowercase
assert req.personality_preset == "visionary_leader"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/unit/api/controllers/test_setup_dtos.py` around lines 18 - 26, The test
currently passes a lowercase personality_preset so it doesn't confirm
normalization; update the SetupAgentRequest instantiation to use a mixed-case
preset (e.g., "Visionary_Leader" or "Visionary_Leader") and then assert that
req.personality_preset equals the lowercase normalized value "visionary_leader"
to lock in the normalization behavior for the SetupAgentRequest validator.
| <InputField | ||
| label="Search" | ||
| value={searchQuery} | ||
| onChange={(e) => setSearchQuery((e.target as HTMLInputElement).value)} | ||
| placeholder="Search templates..." | ||
| className="pl-8 pr-8" | ||
| /> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Type assertion suggests potential type mismatch with InputField onChange.
The cast (e.target as HTMLInputElement).value suggests InputField's onChange may not provide a typed event. If InputField uses a standard React.ChangeEvent<HTMLInputElement>, this cast is unnecessary. If the signature differs, consider updating InputField to expose a properly typed event or a direct value callback.
♻️ Suggested simplification if InputField provides standard events
<InputField
label="Search"
value={searchQuery}
- onChange={(e) => setSearchQuery((e.target as HTMLInputElement).value)}
+ onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search templates..."
className="pl-8 pr-8"
/>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@web/src/pages/setup/TemplateStep.tsx` around lines 290 - 296, The onChange
handler for InputField is using an unnecessary type assertion "(e.target as
HTMLInputElement).value", indicating a mismatch between InputField's declared
onChange type and the actual event; update InputField's props to type its
onChange as (e: React.ChangeEvent<HTMLInputElement>) => void (or provide a
separate onValueChange: (value: string) => void) so callers like the one using
setSearchQuery can simply do onChange={e => setSearchQuery(e.target.value)}
without casting; locate the InputField component/props definition and adjust the
event signature (or add the value callback) and update usages including this
TemplateStep onChange to remove the cast.
…, a11y - Test DTO normalization with mixed-case preset input to verify lowering - Use AutonomyLevel enum in loader test assertion (matches new field type) - Add humanizeWorkflow fallback for unknown workflow display values - Add onValueChange prop to InputField, remove type cast in TemplateStep - Revert spec-constrained mock (ProviderManagementService init is too complex for spec-based mocking, causes xdist worker crashes) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/src/pages/setup/TemplateStep.tsx (1)
129-135:⚠️ Potential issue | 🟠 MajorFiltering can hide the active selection.
selectedTemplatestill marks the step complete even when that card drops out offilteredTemplates, so the wizard can proceed with a template the user can no longer see or review. Please either keep the selected card visible, show a “selected template hidden by filters” notice with a clear-filters action, or clear the selection when filters exclude it.Also applies to: 175-192, 341-393
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@web/src/pages/setup/TemplateStep.tsx` around lines 129 - 135, The effect that marks the template step complete uses selectedTemplate without verifying it is still present in filteredTemplates; update the logic so if selectedTemplate exists but is not included in filteredTemplates you clear the selection (e.g. call setSelectedTemplate(null)) and call markStepIncomplete('template'); otherwise keep the existing behavior (markStepComplete when selectedTemplate is present in filteredTemplates). Apply the same fix to the other places that tie selection to filters (the similar blocks referenced around the other ranges) so selection is cleared whenever filters exclude the selected card.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/unit/templates/test_loader.py`:
- Around line 125-132: The current test_structural_metadata_populated uses
default-valid TemplateInfo values, so change it to assert that each listed
template's structural fields actually match the source template data by loading
the full template and comparing: for each t in list_templates() call
load_template(t.name) and compare t.agent_count, t.department_count,
t.autonomy_level, and t.workflow against the corresponding values on the
loaded_template.template (or the Template object returned by load_template),
ensuring you reference TemplateInfo and the loader path implemented by
_template_info_from_loaded to validate the mapping rather than relying on
defaults.
In `@web/src/pages/setup/TemplateStep.tsx`:
- Line 288: Replace the hardcoded min-w-[200px] on the filter container with a
tokenized/standard Tailwind spacing class: locate the div with className
containing "relative flex-1 min-w-[200px] max-w-xs" and change min-w-[200px] to
a density-aware token or standard Tailwind size (for example use min-w-52 or the
repo's density token like min-w-p-card if available) so the component
(TemplateStep) follows the project's spacing conventions.
---
Outside diff comments:
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 129-135: The effect that marks the template step complete uses
selectedTemplate without verifying it is still present in filteredTemplates;
update the logic so if selectedTemplate exists but is not included in
filteredTemplates you clear the selection (e.g. call setSelectedTemplate(null))
and call markStepIncomplete('template'); otherwise keep the existing behavior
(markStepComplete when selectedTemplate is present in filteredTemplates). Apply
the same fix to the other places that tie selection to filters (the similar
blocks referenced around the other ranges) so selection is cleared whenever
filters exclude the selected card.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d49cbe88-75aa-4812-9074-d70802059a5b
📒 Files selected for processing (5)
tests/unit/api/controllers/test_setup_dtos.pytests/unit/templates/test_loader.pyweb/src/components/ui/input-field.tsxweb/src/pages/setup/TemplateCard.tsxweb/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (5)
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow. Maintain 80% minimum code coverage (enforced in CI). Always run pytest with-n autofor parallel execution. Use@pytest.mark.parametrizefor testing similar cases. Useasyncio_mode = "auto"(no manual@pytest.mark.asyncioneeded).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in tests or project code—use generic names liketest-provider,test-small-001,example-provider,example-large-001,large/medium/small. Vendor names may only appear in: (1) Operations design page, (2).claude/files, (3) third-party import paths, (4) provider presets.
Never skip, dismiss, or ignore flaky tests—always fix them fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()instead of widening margins. For tasks that must block indefinitely until cancelled, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_loader.pytests/unit/api/controllers/test_setup_dtos.py
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/components/ui/input-field.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/TemplateCard.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/components/ui/input-field.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/TemplateCard.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/components/ui/input-field.tsxweb/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/TemplateCard.tsx
web/src/components/ui/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Each new shared component in
web/src/components/ui/must have a corresponding.stories.tsxfile with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Files:
web/src/components/ui/input-field.tsx
🧠 Learnings (5)
📚 Learning: 2026-03-15T18:28:13.207Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:28:13.207Z
Learning: Applies to tests/**/*.py : Tests must use test-provider, test-small-001, etc. for vendor-agnostic test data.
Applied to files:
tests/unit/api/controllers/test_setup_dtos.py
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to tests/**/*.py : Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in tests or project code—use generic names like `test-provider`, `test-small-001`, `example-provider`, `example-large-001`, `large`/`medium`/`small`. Vendor names may only appear in: (1) Operations design page, (2) `.claude/` files, (3) third-party import paths, (4) provider presets.
Applied to files:
tests/unit/api/controllers/test_setup_dtos.py
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/TemplateCard.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsxweb/src/pages/setup/TemplateCard.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateCard.tsx
🔇 Additional comments (3)
web/src/components/ui/input-field.tsx (3)
8-9: Well-documented convenience prop.The JSDoc comment clearly explains the purpose, and the type signature is appropriately simple.
41-49: Handler implementation is correct.The type casts are necessary here due to the discriminated union pattern—TypeScript can't narrow
onChangeto the specific element handler type within these functions. The leading semicolons correctly prevent ASI from treating the expression as a chained call.
65-66: Props spreading correctly excludesonChange.Since
onChangeis destructured separately on line 25, it's already excluded from...propsat runtime. The type casts help TypeScript understand this, and the pattern correctly prevents duplicateonChangeprops on the elements.Also applies to: 76-77
…token spacing - Test structural metadata against loaded template data (not just defaults) - Replace hardcoded min-w-[200px] with standard Tailwind min-w-52 - Track step completion against filteredTemplates so selecting a template then filtering it out correctly marks the step incomplete Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/unit/templates/test_loader.py`:
- Around line 133-141: The test should assert that t.autonomy_level is an actual
AutonomyLevel enum member and that workflow is non-empty: add an isinstance
check (isinstance(t.autonomy_level, AutonomyLevel)) and ensure the workflow
string is not blank (e.g., assert isinstance(t.workflow, str) and
t.workflow.strip() != "") in addition to the existing equality/assertions;
reference the AutonomyLevel type and the attributes t.autonomy_level, t.workflow
and tmpl.workflow when adding these assertions to strengthen contract
validation.
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 187-193: The effect that marks the template step complete is
running while templates are still loading, causing false negatives; update the
useEffect that reads selectedTemplate and filteredTemplates to early-return when
templatesLoading is true and add templatesLoading to the dependency array, so
the existing logic that calls markStepComplete('template') or
markStepIncomplete('template') only runs after templates have finished loading
(referencing useEffect, selectedTemplate, filteredTemplates, templatesLoading,
markStepComplete, markStepIncomplete).
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 69718db0-d5fd-4efd-8e5e-13da3f258e4e
📒 Files selected for processing (2)
tests/unit/templates/test_loader.pyweb/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Sandbox
- GitHub Check: Build Backend
- GitHub Check: Build Web
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow. Maintain 80% minimum code coverage (enforced in CI). Always run pytest with-n autofor parallel execution. Use@pytest.mark.parametrizefor testing similar cases. Useasyncio_mode = "auto"(no manual@pytest.mark.asyncioneeded).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in tests or project code—use generic names liketest-provider,test-small-001,example-provider,example-large-001,large/medium/small. Vendor names may only appear in: (1) Operations design page, (2).claude/files, (3) third-party import paths, (4) provider presets.
Never skip, dismiss, or ignore flaky tests—always fix them fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()instead of widening margins. For tasks that must block indefinitely until cancelled, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_loader.py
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/TemplateStep.tsx
🧠 Learnings (6)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, etc.) or CSS variables (`var(--so-*)`) for colors. Never hardcode hex values or rgba() with hardcoded values in `.tsx`/`.ts` files.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. Never hardcode shadow or border values.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsx
…uring load - Assert autonomy_level is AutonomyLevel instance (not just string member) - Assert workflow is a non-blank string before equality check - Skip step completion effect while templatesLoading to prevent false negatives from empty filteredTemplates during initial fetch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 188-195: The effect that toggles wizard step state uses
filteredTemplates to decide if selectedTemplate is valid, which incorrectly
marks the step incomplete when UI filters hide the selection; update the check
to verify selectedTemplate exists in the full templates array (replace
filteredTemplates.some(...) with templates.some(...)) and adjust the effect
dependencies to include templates (and remove filteredTemplates if no longer
used) while keeping the templatesLoading guard; keep
markStepComplete('template') and markStepIncomplete('template') logic unchanged.
- Around line 122-126: The useEffect currently uses templates.length as the "not
loaded yet" signal which causes repeated refetches when an empty array is a
valid successful response; update the logic in TemplateStep.tsx to track initial
load with a stable flag instead (e.g., import and use React.useRef to add an
"hasFetchedTemplates" ref or use an existing store-level loaded/initialized
boolean) and change the effect to only call fetchTemplates() when
hasFetchedTemplates.current is false and templatesLoading is false and
templatesError is false; after the first fetch, set hasFetchedTemplates.current
= true (or rely on the store flag) so an empty templates array does not trigger
subsequent fetches.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2ee8ad95-d608-46d0-a032-83f9046baf54
📒 Files selected for processing (2)
tests/unit/templates/test_loader.pyweb/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Use markers@pytest.mark.unit,@pytest.mark.integration,@pytest.mark.e2e,@pytest.mark.slow. Maintain 80% minimum code coverage (enforced in CI). Always run pytest with-n autofor parallel execution. Use@pytest.mark.parametrizefor testing similar cases. Useasyncio_mode = "auto"(no manual@pytest.mark.asyncioneeded).
Never use real vendor names (Anthropic, OpenAI, Claude, GPT, etc.) in tests or project code—use generic names liketest-provider,test-small-001,example-provider,example-large-001,large/medium/small. Vendor names may only appear in: (1) Operations design page, (2).claude/files, (3) third-party import paths, (4) provider presets.
Never skip, dismiss, or ignore flaky tests—always fix them fundamentally. For timing-sensitive tests, mocktime.monotonic()andasyncio.sleep()instead of widening margins. For tasks that must block indefinitely until cancelled, useasyncio.Event().wait()instead ofasyncio.sleep(large_number).
Files:
tests/unit/templates/test_loader.py
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/TemplateStep.tsx
🧠 Learnings (6)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, etc.) or CSS variables (`var(--so-*)`) for colors. Never hardcode hex values or rgba() with hardcoded values in `.tsx`/`.ts` files.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. Never hardcode shadow or border values.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsx
🔇 Additional comments (3)
tests/unit/templates/test_loader.py (2)
9-9: Good import addition for enum contract assertions.This import is necessary for the strengthened
autonomy_leveltype/value checks in the new test.
125-143: Strong metadata-mapping test; this now verifies real loader behavior.Great improvement: assertions now validate
agent_count,department_count, enum typing/fallback forautonomy_level, and non-blank/equalworkflowagainst loaded template data.web/src/pages/setup/TemplateStep.tsx (1)
71-102: Nice extraction of the grid item map.Pulling the card body into
TemplateGridItem/TemplateGridkeeps the render tree readable and avoids a long inline JSX block inside.map().As per coding guidelines,
web/src/**/*.tsx: Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
…etch - Step completion checks templates (full list) instead of filteredTemplates so UI filters don't invalidate the selection - Replace templates.length === 0 fetch guard with useRef flag to prevent refetch when the API legitimately returns an empty template list Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 176-180: The keyword haystack in TemplateStep.tsx currently builds
from t.display_name, t.description and t.tags but omits the newly surfaced
metadata (workflow and autonomy_level), so include those fields when composing
haystack (e.g., append t.workflow and t.autonomy_level, converting them to
strings or joining their subfields if they are objects/arrays) before calling
.toLowerCase() so the existing keywords.every((kw) => haystack.includes(kw))
check will match templates by those metadata values as well.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2c1f3c89-2f7d-404b-84cc-27604afb631e
📒 Files selected for processing (1)
web/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Build Web
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/TemplateStep.tsx
🧠 Learnings (6)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, etc.) or CSS variables (`var(--so-*)`) for colors. Never hardcode hex values or rgba() with hardcoded values in `.tsx`/`.ts` files.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. Never hardcode shadow or border values.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsx
🔇 Additional comments (2)
web/src/pages/setup/TemplateStep.tsx (2)
187-197: Nice fix: completion no longer depends on transient filters.Validating
selectedTemplateagainst the fulltemplateslist and skipping the check while loading keeps the wizard state stable when filters hide the selected card.
122-128: Move fetch guard state to store;useRefresets on step remount.
TemplateStepis conditionally mounted viaAnimatedPresenceinWizardShell.tsx(line 120). When the user navigates away and back to the template step, the component remounts andhasFetchedRefresets. An empty-result response will triggerfetchTemplates()again on return, reintroducing the refetch loop.The setup store has no persistent
templatesLoadedflag. Add one toweb/src/stores/setup-wizard.ts(e.g.,templatesInitialized: boolean), set it infetchTemplates()after a successful fetch, and use it in the effect guard instead of the component-local ref.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 322-328: The SelectField in TemplateStep currently passes
options={[...SIZE_OPTIONS]} which allocates a new array every render; fix by
avoiding the spread: either expose a module-level mutable array (e.g.,
SIZE_OPTIONS_MUTABLE) and use options={SIZE_OPTIONS_MUTABLE} or remove the `as
const` on SIZE_OPTIONS so its type matches SelectField and use
options={SIZE_OPTIONS} directly, or memoize the options once (useMemo) and pass
that memoized value to SelectField (identify usages by SIZE_OPTIONS,
SelectField, sizeFilter and setSizeFilter in TemplateStep).
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 3b5d4aeb-782a-4746-ac2d-6d4118c9819b
📒 Files selected for processing (1)
web/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Socket Security: Pull Request Alerts
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/TemplateStep.tsx
🧠 Learnings (6)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, etc.) or CSS variables (`var(--so-*)`) for colors. Never hardcode hex values or rgba() with hardcoded values in `.tsx`/`.ts` files.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. Never hardcode shadow or border values.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsx
🔇 Additional comments (7)
web/src/pages/setup/TemplateStep.tsx (7)
27-43: LGTM — Size filter constants and predicate are well-structured.The
SIZE_OPTIONStuple withas constprovides strong type inference forSizeFilter, andmatchesSizecleanly handles all boundary conditions with explicit range checks.
71-102: LGTM — Good extraction ofTemplateGridas a reusable internal component.The component properly uses the
gap-grid-gapdensity token and responsive breakpoints. ExtractingTemplateGridItemkeeps the.map()body simple, adhering to the guideline against complex JSX inside iteration callbacks.
122-128: LGTM — Fetch-once guard correctly prevents refetch loops.Using
hasFetchedRefinstead oftemplates.length === 0as the trigger condition ensures an empty template array (valid response) doesn't cause repeated fetches.
168-185: LGTM — Filter logic correctly indexes all card metadata.The haystack now includes
workflowandautonomy_levelalongsidedisplay_name,description, andtags, ensuring users can search by any visible metadata. The multi-keyword AND semantics (every()) provide intuitive results.
187-197: LGTM — Step completion validation is now resilient.The effect correctly guards against the loading state and validates
selectedTemplateagainst the fulltemplatesarray rather than the filtered view, preventing filters from incorrectly invalidating the wizard step.
290-312: LGTM — Search input with accessibility and semantic styling.The search wrapper correctly uses
min-w-52(standard Tailwind), semantic color classes, and includes proper accessibility attributes (aria-hiddenon decorative icon,aria-labelon the clear button). TheonValueChangeprop cleanly passes the value without type assertions.
363-398: LGTM — Recommended/Other sections cleanly separated with reusable grid.The split logic efficiently partitions templates, and
TemplateGridis reused for both sections. The conditional "Other Templates" heading (only when recommended exists) provides good UX hierarchy.
Type SIZE_OPTIONS as readonly to match SelectField's props directly, eliminating the [...SIZE_OPTIONS] spread that allocated on every render. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/setup/TemplateStep.tsx`:
- Around line 27-35: Change SIZE_OPTIONS to use the more specific SizeFilter
type for its value property so the constant is self-documenting: replace the
current { value: string; label: string } typing with { value: SizeFilter; label:
string } while keeping the readonly array cast. Note that you should still cast
the SelectField onChange value to SizeFilter at the usage site (the SelectField
component's onChange handler that currently casts e.target.value) because
SelectField's onChange provides a string. Update references to SIZE_OPTIONS and
maintain the existing cast in the SelectField onChange callback.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: c83a2aa4-ac2e-4440-b6d2-9b61c031e388
📒 Files selected for processing (1)
web/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Build Backend
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/TemplateStep.tsx
🧠 Learnings (6)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, etc.) or CSS variables (`var(--so-*)`) for colors. Never hardcode hex values or rgba() with hardcoded values in `.tsx`/`.ts` files.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. Never hardcode shadow or border values.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsx
🔇 Additional comments (7)
web/src/pages/setup/TemplateStep.tsx (7)
1-17: LGTM!Imports are well-organized, reusing existing UI components from
@/components/ui/as per coding guidelines.
71-102: LGTM!
TemplateGridis well-extracted with proper prop typing. The use ofgap-grid-gapfollows density token conventions, and the.map()body correctly delegates toTemplateGridItemper coding guidelines.
122-128: LGTM!The
hasFetchedRefpattern correctly prevents re-fetch loops when the templates array is legitimately empty.
187-197: LGTM!The completion effect correctly validates against the full
templateslist (not filtered), with proper guarding during loading. This ensures UI filters don't inadvertently invalidate the selection.
290-344: LGTM!Filter bar uses semantic color classes (
text-muted-foreground,text-accent), standard Tailwind spacing (min-w-52), and proper accessibility attributes (aria-hidden,aria-label). Previous review concerns about hardcoded pixels and type assertions have been addressed.
363-398: LGTM!Template sections are well-structured with semantic styling (
bg-accent/10,text-accent). The recommended/others split logic is clean and the conditional heading for "Other Templates" correctly appears only when both sections are visible.
346-361: LGTM!Good UX distinction between "no templates match" (filters applied) and "no templates available" (empty data). The action to clear filters is helpful.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/pages/setup/TemplateStep.tsx`:
- Line 294: The Search icon uses vertical centering (className includes "top-1/2
-translate-y-1/2") but the Clear button uses a fixed offset ("bottom-2.5"),
causing misalignment; update the Clear button element in TemplateStep (the
clear/X button rendered next to the input) to use the same centering classes
("top-1/2 -translate-y-1/2") instead of "bottom-2.5" so both icons align
vertically within the input.
- Around line 302-311: The clear button currently uses bottom-2.5 which
misaligns it with the input; update the JSX for the clear button (the button
rendered when searchQuery is truthy, using setSearchQuery and the X icon) to use
vertical centering like the search icon: replace the absolute positioning
classes (bottom-2.5) with top-1/2 and add -translate-y-1/2 so the button
vertically centers relative to the input container; ensure the container remains
position:relative so the absolute centering applies.
🪄 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: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: a0e29a4e-2573-49dc-9415-9c560fe9a98b
📒 Files selected for processing (1)
web/src/pages/setup/TemplateStep.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
- GitHub Check: Dashboard Test
- GitHub Check: Test (Python 3.14)
- GitHub Check: Build Web
- GitHub Check: Build Backend
- GitHub Check: Build Sandbox
- GitHub Check: Dependency Review
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always reuse existing components from
web/src/components/ui/before creating new ones. When a component is needed that is not in the existing inventory, place it inweb/src/components/ui/with a descriptive kebab-case filename, create a.stories.tsxfile with all states, export props as a TypeScript interface, and use design tokens exclusively.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web/src/**/*.{ts,tsx}: Use Tailwind semantic classes (text-foreground,bg-card,text-accent, etc.) or CSS variables (var(--so-*)) for colors. Never hardcode hex values or rgba() with hardcoded values in.tsx/.tsfiles.
Usefont-sansorfont-monoclasses for typography (mapping to Geist tokens). Never setfontFamilydirectly in component code.
Use density-aware tokens (p-card,gap-section-gap,gap-grid-gap) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Use token variables (var(--so-shadow-card-hover),border-border,border-bright) for shadows and borders. Never hardcode shadow or border values.
TypeScript 6.0: remove deprecatedbaseUrlfrom tsconfig;pathsentries are relative to the tsconfig directory. Remove explicit"esModuleInterop": true(always true in TS 6). List needed types explicitly (e.g.,"types": ["vitest/globals"]). DOM.Iterable is merged into DOM. Use"bundler"or"nodenext"formoduleResolution.
Files:
web/src/pages/setup/TemplateStep.tsx
web/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Do NOT recreate status dots inline—use
<StatusBadge>. Do NOT build card-with-header layouts from scratch—use<SectionCard>. Do NOT create metric displays withtext-metric font-bold—use<MetricCard>. Do NOT render initials circles manually—use<Avatar>. Do NOT create complex (>8 line) JSX inside.map()— extract to a shared component.
Files:
web/src/pages/setup/TemplateStep.tsx
🧠 Learnings (6)
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/components/ui/**/*.tsx : Each new shared component in `web/src/components/ui/` must have a corresponding `.stories.tsx` file with all states (default, hover, loading, error, empty). Export props as a TypeScript interface and use design tokens exclusively (no hardcoded colors, fonts, or spacing).
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use density-aware tokens (`p-card`, `gap-section-gap`, `gap-grid-gap`) or standard Tailwind spacing for layout. Never hardcode pixel values for layout spacing.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use Tailwind semantic classes (`text-foreground`, `bg-card`, `text-accent`, etc.) or CSS variables (`var(--so-*)`) for colors. Never hardcode hex values or rgba() with hardcoded values in `.tsx`/`.ts` files.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.{ts,tsx} : Use token variables (`var(--so-shadow-card-hover)`, `border-border`, `border-bright`) for shadows and borders. Never hardcode shadow or border values.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to web/src/**/*.tsx : Do NOT recreate status dots inline—use `<StatusBadge>`. Do NOT build card-with-header layouts from scratch—use `<SectionCard>`. Do NOT create metric displays with `text-metric font-bold`—use `<MetricCard>`. Do NOT render initials circles manually—use `<Avatar>`. Do NOT create complex (>8 line) JSX inside `.map()` — extract to a shared component.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
📚 Learning: 2026-03-28T21:29:12.755Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-28T21:29:12.755Z
Learning: Applies to **/*.{ts,tsx} : Always reuse existing components from `web/src/components/ui/` before creating new ones. When a component is needed that is not in the existing inventory, place it in `web/src/components/ui/` with a descriptive kebab-case filename, create a `.stories.tsx` file with all states, export props as a TypeScript interface, and use design tokens exclusively.
Applied to files:
web/src/pages/setup/TemplateStep.tsx
🔇 Additional comments (11)
web/src/pages/setup/TemplateStep.tsx (11)
1-17: LGTM!Imports are well-organized, appropriately scoped, and correctly reuse existing UI components (
InputField,SelectField) from the shared component library.
27-43: LGTM!The
SizeFiltertype andSIZE_OPTIONSconstant are well-typed, andmatchesSizecorrectly implements the agent-count bucket logic with proper boundary handling.
45-69: LGTM!Clean extraction of card rendering into a dedicated component, following the guideline to avoid complex JSX inside
.map().
71-102: LGTM!The
TemplateGridcomponent correctly uses density-aware tokens (gap-grid-gap) and properly wires selection and compare handlers to child cards.
122-128: LGTM!The
hasFetchedRefguard correctly prevents refetch loops when an empty templates array is a valid response, addressing the prior review concern.
153-166: LGTM!
availableCategoriescorrectly filters to only categories present in templates while maintaining the canonical order fromCATEGORY_ORDER.
187-197: LGTM!The step completion effect correctly validates against the full
templatesarray (notfilteredTemplates) and guards against the loading state, ensuring wizard progress isn't affected by transient filter changes.
213-244: LGTM!Handlers are properly memoized with correct dependencies, and the compare-limit toast provides clear user feedback.
248-279: LGTM!Loading, error, and empty states are handled cleanly, reusing the
EmptyStatecomponent and maintaining consistent grid layout in the skeleton.
363-398: LGTM!The recommended and other templates sections are cleanly structured with appropriate conditional rendering, and the
TemplateGridcomponent is properly reused for both sections.
400-409: LGTM!The
TemplateCompareDraweris correctly wired with proper handlers for selection and removal, opening only when at least 2 templates are being compared.
…ntering Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🤖 I have created a release *beep* *boop* --- #MAJOR CHANGES; We got a somewhat working webui :) ## [0.5.0](v0.4.9...v0.5.0) (2026-03-30) ### Features * add analytics trends and budget forecast API endpoints ([#798](#798)) ([16b61f5](16b61f5)) * add department policies to default templates ([#852](#852)) ([7a41548](7a41548)) * add remaining activity event types (task_started, tool_used, delegation, cost_incurred) ([#832](#832)) ([4252fac](4252fac)) * agent performance, activity, and history API endpoints ([#811](#811)) ([9b75c1d](9b75c1d)) * Agent Profiles and Detail pages (biography, career, performance) ([#874](#874)) ([62d7880](62d7880)) * app shell, Storybook, and CI/CD pipeline ([#819](#819)) ([d4dde90](d4dde90)) * Approvals page with risk grouping, urgency indicators, batch actions ([#889](#889)) ([4e9673d](4e9673d)) * Budget Panel page (P&L dashboard, breakdown charts, forecast) ([#890](#890)) ([b63b0f1](b63b0f1)) * build infrastructure layer (API client, auth, WebSocket) ([#815](#815)) ([9f01d3e](9f01d3e)) * CLI global options infrastructure, UI modes, exit codes, env vars ([#891](#891)) ([fef4fc5](fef4fc5)) * CodeMirror editor and theme preferences toggle ([#905](#905), [#807](#807)) ([#909](#909)) ([41fbedc](41fbedc)) * Company page (department/agent management) ([#888](#888)) ([cfb88b0](cfb88b0)) * comprehensive hint coverage across all CLI commands ([#900](#900)) ([937974e](937974e)) * config system extensions, per-command flags for init/start/stop/status/logs ([#895](#895)) ([32f83fe](32f83fe)) * configurable currency system replacing hardcoded USD ([#854](#854)) ([b372551](b372551)) * Dashboard page (metric cards, activity feed, budget burn) ([#861](#861)) ([7d519d5](7d519d5)) * department health, provider status, and activity feed endpoints ([#818](#818)) ([6d5f196](6d5f196)) * design tokens and core UI components ([#833](#833)) ([ed887f2](ed887f2)) * extend approval, meeting, and budget API responses ([#834](#834)) ([31472bf](31472bf)) * frontend polish -- real-time UX, accessibility, responsive, performance ([#790](#790), [#792](#792), [#791](#791), [#793](#793)) ([#917](#917)) ([f04a537](f04a537)) * implement human roles and access control levels ([#856](#856)) ([d6d8a06](d6d8a06)) * implement semantic conflict detection in workspace merge ([#860](#860)) ([d97283b](d97283b)) * interaction components and animation patterns ([#853](#853)) ([82d4b01](82d4b01)) * Login page + first-run bootstrap + Company page ([#789](#789), [#888](#888)) ([#896](#896)) ([8758e8d](8758e8d)) * Meetings page with timeline viz, token bars, contribution formatting ([#788](#788)) ([#904](#904)) ([b207f46](b207f46)) * Messages page with threading, channel badges, sender indicators ([#787](#787)) ([#903](#903)) ([28293ad](28293ad)) * Org Chart force-directed view and drag-drop reassignment ([#872](#872), [#873](#873)) ([#912](#912)) ([a68a938](a68a938)) * Org Chart page (living nodes, status, CRUD, department health) ([#870](#870)) ([0acbdae](0acbdae)) * per-command flags for remaining commands, auto-behavior wiring, help/discoverability ([#897](#897)) ([3f7afa2](3f7afa2)) * Providers page with backend rework -- health, CRUD, subscription auth ([#893](#893)) ([9f8dd98](9f8dd98)) * scaffold React + Vite + TypeScript + Tailwind project ([#799](#799)) ([bd151aa](bd151aa)) * Settings page with search, dependency indicators, grouped rendering ([#784](#784)) ([#902](#902)) ([a7b9870](a7b9870)) * Setup Wizard rebuild with template comparison, cost estimator, theme customization ([#879](#879)) ([ae8b50b](ae8b50b)) * setup wizard UX -- template filters, card metadata, provider form reuse ([#910](#910)) ([7f04676](7f04676)) * setup wizard UX overhaul -- mode choice, step reorder, provider fixes ([#907](#907)) ([ee964c4](ee964c4)) * structured ModelRequirement in template agent configs ([#795](#795)) ([7433548](7433548)) * Task Board page (rich Kanban, filtering, dependency viz) ([#871](#871)) ([04a19b0](04a19b0)) ### Bug Fixes * align frontend types with backend and debounce WS refetches ([#916](#916)) ([134c11b](134c11b)) * auto-cleanup targets newly pulled images instead of old ones ([#884](#884)) ([50e6591](50e6591)) * correct wipe backup-skip flow and harden error handling ([#808](#808)) ([c05860f](c05860f)) * improve provider setup in wizard, subscription auth, dashboard bugs ([#914](#914)) ([87bf8e6](87bf8e6)) * improve update channel detection and add config get command ([#814](#814)) ([6b137f0](6b137f0)) * resolve all ESLint warnings, add zero-warnings enforcement ([#899](#899)) ([079b46a](079b46a)) * subscription auth uses api_key, base URL optional for cloud providers ([#915](#915)) ([f0098dd](f0098dd)) ### Refactoring * semantic analyzer cleanup -- shared filtering, concurrency, extraction ([#908](#908)) ([81372bf](81372bf)) ### Documentation * brand identity and UX design system from [#765](#765) exploration ([#804](#804)) ([389a9f4](389a9f4)) * page structure and information architecture for v0.5.0 dashboard ([#809](#809)) ([f8d6d4a](f8d6d4a)) * write UX design guidelines with WCAG-verified color system ([#816](#816)) ([4a4594e](4a4594e)) ### Tests * add unit tests for agent hooks and page components ([#875](#875)) ([#901](#901)) ([1d81546](1d81546)) ### CI/CD * bump actions/deploy-pages from 4.0.5 to 5.0.0 in the major group ([#831](#831)) ([01c19de](01c19de)) * bump astral-sh/setup-uv from 7.6.0 to 8.0.0 in /.github/actions/setup-python-uv in the all group ([#920](#920)) ([5f6ba54](5f6ba54)) * bump codecov/codecov-action from 5.5.3 to 6.0.0 in the major group ([#868](#868)) ([f22a181](f22a181)) * bump github/codeql-action from 4.34.1 to 4.35.0 in the all group ([#883](#883)) ([87a4890](87a4890)) * bump sigstore/cosign-installer from 4.1.0 to 4.1.1 in the minor-and-patch group ([#830](#830)) ([7a69050](7a69050)) * bump the all group with 3 updates ([#923](#923)) ([ff27c8e](ff27c8e)) * bump wrangler from 4.76.0 to 4.77.0 in /.github in the minor-and-patch group ([#822](#822)) ([07d43eb](07d43eb)) * bump wrangler from 4.77.0 to 4.78.0 in /.github in the all group ([#882](#882)) ([f84118d](f84118d)) ### Maintenance * add design system enforcement hook and component inventory ([#846](#846)) ([15abc43](15abc43)) * add dev-only auth bypass for frontend testing ([#885](#885)) ([6cdcd8a](6cdcd8a)) * add pre-push rebase check hook ([#855](#855)) ([b637a04](b637a04)) * backend hardening -- eviction/size-caps and model validation ([#911](#911)) ([81253d9](81253d9)) * bump axios from 1.13.6 to 1.14.0 in /web in the all group across 1 directory ([#922](#922)) ([b1b0232](b1b0232)) * bump brace-expansion from 5.0.4 to 5.0.5 in /web ([#862](#862)) ([ba4a565](ba4a565)) * bump eslint-plugin-react-refresh from 0.4.26 to 0.5.2 in /web ([#801](#801)) ([7574bb5](7574bb5)) * bump faker from 40.11.0 to 40.11.1 in the minor-and-patch group ([#803](#803)) ([14d322e](14d322e)) * bump https://github.com/astral-sh/ruff-pre-commit from v0.15.7 to 0.15.8 ([#864](#864)) ([f52901e](f52901e)) * bump nginxinc/nginx-unprivileged from `6582a34` to `f99cc61` in /docker/web in the all group ([#919](#919)) ([df85e4f](df85e4f)) * bump nginxinc/nginx-unprivileged from `ccbac1a` to `6582a34` in /docker/web ([#800](#800)) ([f4e9450](f4e9450)) * bump node from `44bcbf4` to `71be405` in /docker/sandbox ([#827](#827)) ([91bec67](91bec67)) * bump node from `5209bca` to `cf38e1f` in /docker/web ([#863](#863)) ([66d6043](66d6043)) * bump picomatch in /site ([#842](#842)) ([5f20bcc](5f20bcc)) * bump recharts 2->3 and @types/node 22->25 in /web ([#802](#802)) ([a908800](a908800)) * Bump requests from 2.32.5 to 2.33.0 ([#843](#843)) ([41daf69](41daf69)) * bump smol-toml from 1.6.0 to 1.6.1 in /site ([#826](#826)) ([3e5dbe4](3e5dbe4)) * bump the all group with 3 updates ([#921](#921)) ([7bace0b](7bace0b)) * bump the minor-and-patch group across 1 directory with 2 updates ([#829](#829)) ([93e611f](93e611f)) * bump the minor-and-patch group across 1 directory with 3 updates ([#841](#841)) ([7010c8e](7010c8e)) * bump the minor-and-patch group across 1 directory with 3 updates ([#869](#869)) ([548cee5](548cee5)) * bump the minor-and-patch group in /site with 2 updates ([#865](#865)) ([9558101](9558101)) * bump the minor-and-patch group with 2 updates ([#867](#867)) ([4830706](4830706)) * consolidate Dependabot groups to 1 PR per ecosystem ([06d2556](06d2556)) * consolidate Dependabot groups to 1 PR per ecosystem ([#881](#881)) ([06d2556](06d2556)) * improve worktree skill with full dep sync and status enhancements ([#906](#906)) ([772c625](772c625)) * remove Vue remnants and document framework decision ([#851](#851)) ([bf2adf6](bf2adf6)) * update web dependencies and fix brace-expansion CVE ([#880](#880)) ([a7a0ed6](a7a0ed6)) * upgrade to Storybook 10 and TypeScript 6 ([#845](#845)) ([52d95f2](52d95f2)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
TemplateInfoResponsewithagent_count,department_count,autonomy_level(nowAutonomyLevelenum),workflow(nowNotBlankStr); fixSetupAgentSummaryfield types to use proper nullable typesProviderAddForm.tsx, update design spec, add test coverage for new store methodsTest plan
uv run ruff check src/ tests/-- passesuv run mypy src/ tests/-- passes (1232 files)uv run python -m pytest tests/ -m unit -n auto -k "template or setup"-- 490 passednpm --prefix web run type-check-- passesnpm --prefix web run lint-- passes (zero warnings)npm --prefix web run test-- 1930 passed (4 new tests added)Review coverage
Pre-reviewed by 7 agents (docs-consistency, code-reviewer, frontend-reviewer, api-contract-drift, type-design-analyzer, conventions-enforcer, test-quality-reviewer). 16 findings addressed across type safety, dead code removal, a11y, design spec accuracy, and test coverage.
🤖 Generated with Claude Code