Skip to content

feat: add spell check setting for input areas#729

Open
pedramamini wants to merge 3 commits intomainfrom
253-add-spell-check-setting
Open

feat: add spell check setting for input areas#729
pedramamini wants to merge 3 commits intomainfrom
253-add-spell-check-setting

Conversation

@pedramamini
Copy link
Copy Markdown
Collaborator

@pedramamini pedramamini commented Apr 5, 2026

Summary

  • Adds a new spellCheck boolean setting (default: off) under Settings > General > Spell Check
  • Wires browser-native spell checking into all text input areas:
    • Main prompt input (InputArea.tsx)
    • Group chat input (GroupChatInput.tsx)
    • File editor (FilePreview.tsx)
    • Mobile command input bar (CommandInputBar.tsx)
  • Full settings infrastructure: metadata, store state/actions, persistence, loading

Closes #253

Test plan

  • Toggle spell check ON in Settings > General > Spell Check
  • Verify red squiggly underlines appear for misspelled words in the main AI prompt input
  • Verify spell check works in group chat input
  • Verify spell check works in file editor (markdown edit mode)
  • Toggle spell check OFF and verify underlines disappear
  • Verify setting persists across app restarts

Summary by CodeRabbit

  • New Features
    • Added spell check toggle in the General settings tab to enable or disable spell checking in the prompt input, group chat, and file editor.

- Standardized multi-phase auto-run docs into one flat, dated subdirectory 📁
- Explicitly banned nested project/feature folder structures for phase outputs 🚫
- Improved guidance for clean lexicographic sorting with zero-padded phases 🔢
- Made it easier to add entire effort folders to auto-run at once ➕
- Clarified organization rules so related phase documents stay tightly grouped 🧭
Add a new `spellCheck` boolean setting (default: off) that enables
browser-native spell checking across all text input areas including
the main prompt input, group chat input, file editor, and mobile
command input bar.

Closes #253
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

📝 Walkthrough

Walkthrough

Added a spell check feature allowing users to toggle spell checking in input areas. Extended settings type definitions with a new spellCheck boolean setting, implemented store state and actions, added metadata, integrated the setting into multiple input components, and created a UI control in the General settings tab.

Changes

Cohort / File(s) Summary
Settings Type Definitions
src/main/stores/types.ts, src/main/stores/defaults.ts
Extended MaestroSettings interface and default settings object with new spellCheck: boolean property initialized to false.
Settings Store & Hooks
src/renderer/stores/settingsStore.ts, src/renderer/hooks/settings/useSettings.ts, src/shared/settingsMetadata.ts
Implemented spellCheck state and setter in settings store with persistence; extended UseSettingsReturn interface; added setting metadata entry with category 'editor' and description.
Settings UI
src/renderer/components/Settings/tabs/GeneralTab.tsx
Added "Spell Check" toggle control using SettingCheckbox component with icon and descriptive labels in the General settings tab.
Input Components
src/renderer/components/FilePreview.tsx, src/renderer/components/GroupChatInput.tsx, src/renderer/components/InputArea.tsx, src/web/mobile/CommandInputBar.tsx
Connected spellCheck setting from store to textarea spellCheck props across multiple input areas; added optional spellCheck prop to CommandInputBar.
Documentation
docs/releases.md, src/prompts/maestro-system-prompt.md
Normalized line endings and formatting in releases file; clarified multi-phase auto-run directory structure rules in system prompt.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A toggle so fine, for words to align!
Spell-check now flows through each input line.
From store to component, the setting takes flight,
Making typos much easier to fight! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add spell check setting for input areas' clearly and concisely describes the main change—adding a spell check setting that applies to input areas throughout the application.
Linked Issues check ✅ Passed The PR fully implements the objectives from issue #253: adds a spellCheck boolean setting (default off), creates Settings > General > Spell Check UI option, applies browser-native spell checking to prompt input, group chat, file editor, and mobile command input.
Out of Scope Changes check ✅ Passed Changes are on-scope: spell check feature implementation and documentation formatting. The docs/releases.md formatting normalizes whitespace only without altering content, and the maestro-system-prompt.md adjustment to auto-run phase placement rules appears necessary for context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 253-add-spell-check-setting

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
docs/releases.md (1)

439-448: Use consistent Markdown bullets for reliable rendering.

These sections use while the rest of the file uses -. Prefer a single bullet style across release notes.

Proposed fix pattern
-• Enhanced mobile web interface with session sync and history panel 📱
+- Enhanced mobile web interface with session sync and history panel 📱

Apply the same replacement for the remaining items in these ranges.

Also applies to: 462-471

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` around lines 439 - 448, Replace the unicode bullet
characters ("•") in docs/releases.md with the standard Markdown dash "-" to
ensure consistent rendering; search for the listed entries (e.g., lines
containing "Enhanced mobile web interface with session sync and history panel",
"Added ThinkingStatusPill showing real-time token counts and elapsed time",
etc.) and replace each leading "•" with "-" and apply the same replacement for
the other affected ranges (notably the section also mentioned around lines
462-471).
🤖 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/releases.md`:
- Line 74: Fix the typos and wording in the release notes: change "FIle" to
"File" in the "🗄️ Document Graphs." line, replace "built in" with "built-in",
correct "will received" to "will receive", and change "Github" to "GitHub";
apply the same corrections to the other occurrences noted (lines referenced as
149, 153, 174) so all instances in docs/releases.md use the proper
capitalization and hyphenation.
- Line 20: Update the heading level for in-section titles like "Major 0.15.x
Additions" in docs/releases.md so they are subsection headings (e.g., convert
leading '#' to '###') rather than top-level H1; ensure all similar headings
mentioned (the ones at the other occurrences in this file) are changed
consistently so the document outline/TOC remains hierarchical and navigation
works correctly.
- Line 80: Update the incorrect heading string "# Smaller Changes in 014.x" to
"# Smaller Changes in 0.14.x" so the version label is correct; locate the
heading line containing "Smaller Changes in 014.x" and replace "014.x" with
"0.14.x" to fix the typo.

In `@src/prompts/maestro-system-prompt.md`:
- Line 48: The scanner currently recurses without limits; update scanDirectory
and checkForMarkdownFiles to enforce a maximum subdirectory depth of 1 under the
AUTORUN_FOLDER for multi-phase efforts: add a depth (or relativeDepth) parameter
to scanDirectory and only recurse when depth < 1, and in checkForMarkdownFiles
compute the path depth relative to AUTORUN_FOLDER and either reject (throw/log
an error) or skip any markdown files found at depth > 1; ensure error messages
reference the offending path and the rule (single-level YYYY-MM-DD-Feature-Name
folder) so callers can surface the validation failure.

---

Nitpick comments:
In `@docs/releases.md`:
- Around line 439-448: Replace the unicode bullet characters ("•") in
docs/releases.md with the standard Markdown dash "-" to ensure consistent
rendering; search for the listed entries (e.g., lines containing "Enhanced
mobile web interface with session sync and history panel", "Added
ThinkingStatusPill showing real-time token counts and elapsed time", etc.) and
replace each leading "•" with "-" and apply the same replacement for the other
affected ranges (notably the section also mentioned around lines 462-471).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e32933c8-7708-4aa8-ae7a-2a255470b088

📥 Commits

Reviewing files that changed from the base of the PR and between 3e0e338 and 525c502.

📒 Files selected for processing (12)
  • docs/releases.md
  • src/main/stores/defaults.ts
  • src/main/stores/types.ts
  • src/prompts/maestro-system-prompt.md
  • src/renderer/components/FilePreview.tsx
  • src/renderer/components/GroupChatInput.tsx
  • src/renderer/components/InputArea.tsx
  • src/renderer/components/Settings/tabs/GeneralTab.tsx
  • src/renderer/hooks/settings/useSettings.ts
  • src/renderer/stores/settingsStore.ts
  • src/shared/settingsMetadata.ts
  • src/web/mobile/CommandInputBar.tsx

- **Group chat participant management:** Remove button on participant cards lets you remove stale or unwanted participants from a group chat
- **Batch resume/abort:** New controls in the right panel for resuming or aborting batch operations
- **Default worktree directory:** Worktree configuration now defaults to the parent of the agent's working directory instead of blank
# Major 0.15.x Additions
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix heading hierarchy to avoid broken doc outline.

These headings reset to H1 inside version sections. They should be subsection headings (e.g., ###) so navigation/TOC stays consistent.

Proposed fix
-# Major 0.15.x Additions
+### Major 0.15.x Additions

-# Smaller Changes in 014.x
+### Smaller Changes in 0.14.x

-# Other Changes
+### Other Changes

-# Onboarding, Wizard, and Tours
+### Onboarding, Wizard, and Tours

-# UI / UX Enhancements
+### UI / UX Enhancements

-# Auto Run Workflow Improvements
+### Auto Run Workflow Improvements

-# Application Behavior / Core Fixes
+### Application Behavior / Core Fixes

-# Update System
+### Update System

Also applies to: 80-80, 176-176, 268-268, 276-276, 286-286, 291-291, 297-297

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` at line 20, Update the heading level for in-section titles
like "Major 0.15.x Additions" in docs/releases.md so they are subsection
headings (e.g., convert leading '#' to '###') rather than top-level H1; ensure
all similar headings mentioned (the ones at the other occurrences in this file)
are changed consistently so the document outline/TOC remains hierarchical and
navigation works correctly.


The major contributions to 0.14.x remain:

🗄️ Document Graphs. Launch from file preview or from the FIle tree panel. Explore relationships between Markdown documents that contain links between documents and to URLs.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clean up copy typos in release text.

Minor wording/spelling issues found in changed lines (FIleFile, built inbuilt-in, will receivedwill receive, GithubGitHub).

Also applies to: 149-149, 153-153, 174-174

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` at line 74, Fix the typos and wording in the release notes:
change "FIle" to "File" in the "🗄️ Document Graphs." line, replace "built in"
with "built-in", correct "will received" to "will receive", and change "Github"
to "GitHub"; apply the same corrections to the other occurrences noted (lines
referenced as 149, 153, 174) so all instances in docs/releases.md use the proper
capitalization and hyphenation.


🧙‍♂️ Added an in-tab wizard for generating Auto Run Playbooks via `/wizard` or a new button in the Auto Run panel.

# Smaller Changes in 014.x
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Correct version label typo in heading.

014.x should be 0.14.x.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` at line 80, Update the incorrect heading string "# Smaller
Changes in 014.x" to "# Smaller Changes in 0.14.x" so the version label is
correct; locate the heading line containing "Smaller Changes in 014.x" and
replace "014.x" with "0.14.x" to fix the typo.

When a user wants an auto-run document (or playbook), create a detailed multi-document, multi-point Markdown implementation plan in the `{{AUTORUN_FOLDER}}` folder. Use the format `$PREFIX-XX.md`, where `XX` is the two-digit phase number (01, 02, etc.) and `$PREFIX` is the effort name. Always zero-pad phase numbers to ensure correct lexicographic sorting. Break phases by relevant context; do not mix unrelated task results in the same document. If working within a file, group and fix all type issues in that file together. If working with an MCP, keep all related tasks in the same document. Each task must be written as `- [ ] ...` so auto-run can execute and check them off with comments on completion.

**Multi-phase efforts:** When creating 3 or more phase documents for a single effort, place them in a dedicated subdirectory prefixed with today's date (e.g., `{{AUTORUN_FOLDER}}/YYYY-MM-DD-Feature-Name/FEATURE-NAME-01.md`). This allows users to add the entire folder at once and keeps related documents organized with a clear creation date.
**Multi-phase efforts:** When creating 3 or more phase documents for a single effort, place them in a single flat subdirectory directly under `{{AUTORUN_FOLDER}}`, prefixed with today's date (e.g., `{{AUTORUN_FOLDER}}/YYYY-MM-DD-Feature-Name/FEATURE-NAME-01.md`). Do NOT create nested subdirectories — all phase documents for a given effort go into one folder, never `project/feature/` nesting. This allows users to add the entire folder at once and keeps related documents organized with a clear creation date.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify that autorun scanning functions recurse without depth limits

echo "=== Checking checkForMarkdownFiles recursion ==="
ast-grep --pattern $'async function checkForMarkdownFiles($$$) {
  $$$
  if ($_.isDirectory()) {
    $$$
    checkForMarkdownFiles($$$)
    $$$
  }
  $$$
}'

echo ""
echo "=== Checking scanDirectory recursion ==="
ast-grep --pattern $'async function scanDirectory($$$) {
  $$$
  if ($_.isDirectory()) {
    $$$
    scanDirectory($$$)
    $$$
  }
  $$$
}'

echo ""
echo "=== Searching for depth limit checks ==="
rg -n -C3 'depth|level|nesting' src/main/ipc/handlers/autorun.ts

Repository: RunMaestro/Maestro

Length of output: 450


🏁 Script executed:

#!/bin/bash
# Find and examine the autorun.ts file

# First, locate the file
fd -e ts -e js | grep -i autorun

echo ""
echo "=== Checking file existence and size ==="
wc -l src/main/ipc/handlers/autorun.ts 2>/dev/null || echo "File not found at expected path"

echo ""
echo "=== Looking at lines 90-100 (around claimed scanDirectory) ==="
sed -n '90,100p' src/main/ipc/handlers/autorun.ts

echo ""
echo "=== Looking at lines 225-235 (around claimed checkForMarkdownFiles) ==="
sed -n '225,235p' src/main/ipc/handlers/autorun.ts

echo ""
echo "=== Searching for function definitions ==="
grep -n "function.*scanDirectory\|function.*checkForMarkdownFiles" src/main/ipc/handlers/autorun.ts

Repository: RunMaestro/Maestro

Length of output: 2318


🏁 Script executed:

#!/bin/bash
# Read complete function implementations

echo "=== scanDirectory function (starting at line 78) ==="
sed -n '78,122p' src/main/ipc/handlers/autorun.ts

echo ""
echo "=== checkForMarkdownFiles function (starting at line 213) ==="
sed -n '213,235p' src/main/ipc/handlers/autorun.ts

echo ""
echo "=== Search for depth, maxDepth, or similar limit variables in file ==="
rg -n 'depth|maxDepth|max.*depth|recursion.*limit' src/main/ipc/handlers/autorun.ts

Repository: RunMaestro/Maestro

Length of output: 2385


🏁 Script executed:

#!/bin/bash
# Verify the prompt file and check for any directory structure validation

echo "=== Reading maestro-system-prompt.md around line 48 ==="
sed -n '40,60p' src/prompts/maestro-system-prompt.md

echo ""
echo "=== Searching for directory structure validation in codebase ==="
rg -n 'YYYY-MM-DD|flat.*dir|nested.*dir|subdirectory.*limit|depth.*restriction' --max-count=20

echo ""
echo "=== Looking for tests related to directory structure ==="
fd -e test.ts -e spec.ts | xargs grep -l 'directory\|subdirectory\|nesting' 2>/dev/null | head -5

echo ""
echo "=== Check autorun.ts for any validation of flat structure ==="
rg -n 'validate.*dir|enforce.*dir|flat' src/main/ipc/handlers/autorun.ts

Repository: RunMaestro/Maestro

Length of output: 11103


Add depth validation to enforce the single-level subdirectory rule for multi-phase efforts.

The maestro-system-prompt.md explicitly requires that multi-phase efforts use only one level of nesting ({{AUTORUN_FOLDER}}/YYYY-MM-DD-Feature-Name/) and forbids deeper structures. However, the scanning functions recurse without depth limits:

  • scanDirectory (line 78) recursively scans subdirectories with no maximum depth
  • checkForMarkdownFiles (line 213) recursively checks subdirectories with no maximum depth

This creates an enforcement gap: the documentation forbids nested structures like {{AUTORUN_FOLDER}}/2025-01-15-Feature/subfolder/nested/PHASE-01.md, but the implementation will silently discover and process phase files at any depth.

Add depth validation to reject files deeper than the required flat structure, or update the documentation to clarify that the rule is advisory.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/prompts/maestro-system-prompt.md` at line 48, The scanner currently
recurses without limits; update scanDirectory and checkForMarkdownFiles to
enforce a maximum subdirectory depth of 1 under the AUTORUN_FOLDER for
multi-phase efforts: add a depth (or relativeDepth) parameter to scanDirectory
and only recurse when depth < 1, and in checkForMarkdownFiles compute the path
depth relative to AUTORUN_FOLDER and either reject (throw/log an error) or skip
any markdown files found at depth > 1; ensure error messages reference the
offending path and the rule (single-level YYYY-MM-DD-Feature-Name folder) so
callers can surface the validation failure.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 5, 2026

Greptile Summary

This PR introduces a spellCheck boolean setting (default: false) under Settings > General > Spell Check and wires browser-native spell checking into text input areas across the desktop app. The full settings infrastructure follows existing codebase conventions cleanly.

  • Full settings lifecycle is correctly implemented across settingsMetadata.ts, types.ts, defaults.ts, settingsStore.ts, useSettings.ts, and GeneralTab.tsx
  • The three desktop input areas (InputArea, GroupChatInput, FilePreview) each read spellCheck via an efficient Zustand selector and pass it directly to their <textarea> elements — no issues found
  • CommandInputBar in the mobile web interface gains a spellCheck prop and correctly wires it to all internal textareas, but src/web/mobile/App.tsx never passes the prop — so spell check is always false in the mobile web client regardless of the user's desktop setting

Confidence Score: 4/5

Safe to merge for desktop users; mobile web spell check is silently non-functional but defaults to off so there is no regression.

The desktop implementation is complete, correct, and closely follows existing patterns. One gap: the mobile web CommandInputBar has the prop plumbing but App.tsx never passes the value, making the feature a no-op in that context. Because the default is false (disabled), this introduces no behavioral regression — it is a missing enhancement, not a breakage.

src/web/mobile/App.tsx — the spellCheck prop must be plumbed through to CommandInputBar for the mobile web experience to match the PR description.

Important Files Changed

Filename Overview
src/shared/settingsMetadata.ts Adds spellCheck metadata entry with correct type (boolean), default (false), and editor category.
src/main/stores/types.ts Adds spellCheck: boolean to MaestroSettings interface correctly.
src/main/stores/defaults.ts Adds spellCheck: false to SETTINGS_DEFAULTS correctly.
src/renderer/stores/settingsStore.ts Adds spellCheck state field, setSpellCheck action, and loadAllSettings patch; all follow existing patterns correctly.
src/renderer/hooks/settings/useSettings.ts Correctly exposes spellCheck and setSpellCheck through the UseSettingsReturn interface.
src/renderer/components/Settings/tabs/GeneralTab.tsx Renders a SettingCheckbox with SpellCheck icon and descriptive copy, correctly wired to the store action.
src/renderer/components/InputArea.tsx Reads spellCheck via Zustand selector and passes it to the textarea prop correctly.
src/renderer/components/GroupChatInput.tsx Reads spellCheck via Zustand selector and passes it to the textarea prop correctly.
src/renderer/components/FilePreview.tsx Reads spellCheck via Zustand selector and passes it to the edit-mode textarea correctly.
src/web/mobile/CommandInputBar.tsx Adds spellCheck prop and wires it to all internal textareas, but the parent App.tsx never passes the prop so it is always false in the mobile web interface.
src/prompts/maestro-system-prompt.md Minor unrelated clarification prohibiting nested subdirectories for multi-phase Auto Run efforts.
docs/releases.md Whitespace normalization only; no functional changes.

Sequence Diagram

sequenceDiagram
    participant User
    participant GeneralTab as SettingsModal (GeneralTab)
    participant Store as settingsStore (Zustand)
    participant IPC as window.maestro.settings
    participant ES as electron-store
    participant InputArea
    participant GroupChatInput
    participant FilePreview

    User->>GeneralTab: Toggle Spell Check checkbox
    GeneralTab->>Store: setSpellCheck(value)
    Store->>Store: set({ spellCheck: value })
    Store->>IPC: settings.set('spellCheck', value)
    IPC->>ES: persists value to disk
    ES-->>IPC: confirmed

    Note over Store,ES: On app startup
    Store->>IPC: settings.getAll()
    IPC->>ES: read all settings
    ES-->>Store: { spellCheck: boolean, ... }
    Store->>Store: patch.spellCheck = allSettings['spellCheck']
    Store->>Store: settingsLoaded = true

    Store-->>InputArea: useSettingsStore(s => s.spellCheck)
    Store-->>GroupChatInput: useSettingsStore(s => s.spellCheck)
    Store-->>FilePreview: useSettingsStore(s => s.spellCheck)
    InputArea->>InputArea: textarea spellCheck={spellCheckEnabled}
    GroupChatInput->>GroupChatInput: textarea spellCheck={spellCheckEnabled}
    FilePreview->>FilePreview: textarea spellCheck={spellCheckEnabled}
Loading

Comments Outside Diff (1)

  1. src/web/mobile/App.tsx, line 1292-1316 (link)

    P1 spellCheck prop never passed to CommandInputBar

    The PR wires spellCheck inside CommandInputBar (all three internal textareas), but App.tsx never passes the prop when rendering the component. It will always fall back to its default of false, so spell check is silently disabled in the mobile web interface regardless of the user's desktop setting — directly contradicting the PR description's claim that "Mobile command input bar (CommandInputBar.tsx)" is supported.

    The mobile web app communicates with the desktop over WebSocket and has no access to the Electron settingsStore. A separate sync mechanism (e.g. a dedicated settings message in the WebSocket protocol) would be needed before this can work end-to-end. At minimum the PR description should note this limitation.

Reviews (1): Last reviewed commit: "style: format docs/releases.md with pret..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Spell Check to Input Areas

1 participant