feat: implement complete plugin store repository synchronization system

• Fix repository sync implementation in admin API (was TODO placeholder)
- Add full fetch/parse logic for repository.json and plugin index -
Implement robot matching by name/manufacturer patterns - Handle plugin
creation/updates with proper error handling - Add comprehensive
TypeScript typing throughout

• Fix plugin store installation state detection - Add getStudyPlugins
API integration to check installed plugins - Update PluginCard component
with isInstalled prop and correct button states - Fix repository name
display using metadata.repositoryId mapping - Show "Installed"
(disabled) vs "Install" (enabled) based on actual state

• Resolve admin access and authentication issues - Add missing
administrator role to user system roles table - Fix admin route access
for repository management - Enable repository sync functionality in
admin dashboard

• Add repository metadata integration - Update plugin records with
proper repositoryId references - Add metadata field to
robots.plugins.list API response - Enable repository name display for
all plugins from metadata

• Fix TypeScript compliance across plugin system - Replace unsafe 'any'
types with proper interfaces - Add type definitions for repository and
plugin data structures - Use nullish coalescing operators for safer null
handling - Remove unnecessary type assertions

• Integrate live repository at https://repo.hristudio.com - Successfully
loads 3 robot plugins (TurtleBot3 Burger/Waffle, NAO) - Complete ROS2
action definitions with parameter schemas - Trust level categorization
(official, verified, community) - Platform and documentation metadata
preservation

• Update documentation and development workflow - Document plugin
repository system in work_in_progress.md - Update quick-reference.md
with repository sync examples - Add plugin installation and management
guidance - Remove problematic test script with TypeScript errors

BREAKING CHANGE: Plugin store now requires repository sync for robot
plugins. Run repository sync in admin dashboard after deployment to
populate plugin store.

Closes: Plugin store repository integration Resolves: Installation state
detection and repository name display Fixes: Admin authentication and
TypeScript compliance issues
This commit is contained in:
2025-08-07 10:47:29 -04:00
parent b1f4eedb53
commit 18f709f879
33 changed files with 5146 additions and 2273 deletions

View File

@@ -0,0 +1,298 @@
{
"blockSetId": "control-flow",
"name": "Control Flow",
"description": "Logic blocks for conditionals, loops, timing, and experiment flow control",
"version": "1.0.0",
"pluginApiVersion": "1.0",
"hriStudioVersion": ">=0.1.0",
"trustLevel": "official",
"category": "control-flow",
"author": {
"name": "HRIStudio Team",
"email": "support@hristudio.com",
"organization": "HRIStudio"
},
"documentation": {
"mainUrl": "https://docs.hristudio.org/blocks/control-flow",
"description": "Control flow blocks manage the execution sequence of experiments. They provide timing, conditionals, loops, and logical operations to create sophisticated experimental protocols."
},
"blocks": [
{
"id": "wait",
"name": "wait",
"description": "Pause execution for a specified duration",
"category": "control",
"shape": "action",
"icon": "Clock",
"color": "#f97316",
"nestable": false,
"parameters": [
{
"id": "seconds",
"name": "Duration (s)",
"type": "number",
"value": 1,
"min": 0.1,
"max": 300,
"step": 0.1,
"description": "Time to wait in seconds"
},
{
"id": "show_countdown",
"name": "Show Countdown",
"type": "boolean",
"value": false,
"description": "Display countdown timer to wizard"
}
],
"execution": {
"type": "delay",
"blocking": true
}
},
{
"id": "repeat",
"name": "repeat",
"description": "Execute contained blocks multiple times",
"category": "control",
"shape": "control",
"icon": "RotateCcw",
"color": "#f97316",
"nestable": true,
"parameters": [
{
"id": "times",
"name": "Repeat Count",
"type": "number",
"value": 3,
"min": 1,
"max": 100,
"step": 1,
"description": "Number of times to repeat"
},
{
"id": "delay_between",
"name": "Delay Between (s)",
"type": "number",
"value": 0,
"min": 0,
"max": 60,
"step": 0.1,
"description": "Optional delay between repetitions"
}
],
"execution": {
"type": "loop",
"blocking": true
}
},
{
"id": "if_condition",
"name": "if",
"description": "Execute blocks conditionally based on a condition",
"category": "control",
"shape": "control",
"icon": "GitBranch",
"color": "#f97316",
"nestable": true,
"parameters": [
{
"id": "condition_type",
"name": "Condition",
"type": "select",
"value": "participant_speaks",
"options": [
"participant_speaks",
"participant_silent",
"object_detected",
"timer_elapsed",
"wizard_input",
"random_chance",
"custom"
],
"description": "Type of condition to evaluate"
},
{
"id": "condition_value",
"name": "Condition Value",
"type": "text",
"value": "",
"placeholder": "Enter condition details",
"description": "Additional parameters for the condition"
},
{
"id": "probability",
"name": "Probability (%)",
"type": "number",
"value": 50,
"min": 0,
"max": 100,
"step": 1,
"description": "Probability for random chance condition"
}
],
"execution": {
"type": "conditional",
"blocking": true
}
},
{
"id": "parallel",
"name": "run in parallel",
"description": "Execute multiple blocks simultaneously",
"category": "control",
"shape": "control",
"icon": "Zap",
"color": "#f97316",
"nestable": true,
"parameters": [
{
"id": "wait_for_all",
"name": "Wait for All",
"type": "boolean",
"value": true,
"description": "Wait for all parallel blocks to complete"
},
{
"id": "timeout",
"name": "Timeout (s)",
"type": "number",
"value": 60,
"min": 1,
"max": 600,
"step": 1,
"description": "Maximum time to wait for completion"
}
],
"execution": {
"type": "parallel",
"blocking": true
}
},
{
"id": "sequence",
"name": "sequence",
"description": "Execute blocks in strict sequential order",
"category": "control",
"shape": "control",
"icon": "List",
"color": "#f97316",
"nestable": true,
"parameters": [
{
"id": "stop_on_error",
"name": "Stop on Error",
"type": "boolean",
"value": true,
"description": "Stop sequence if any block fails"
},
{
"id": "delay_between",
"name": "Delay Between (s)",
"type": "number",
"value": 0,
"min": 0,
"max": 10,
"step": 0.1,
"description": "Optional delay between blocks"
}
],
"execution": {
"type": "sequence",
"blocking": true
}
},
{
"id": "random_choice",
"name": "random choice",
"description": "Randomly select one path from multiple options",
"category": "control",
"shape": "control",
"icon": "Shuffle",
"color": "#f97316",
"nestable": true,
"parameters": [
{
"id": "seed",
"name": "Random Seed",
"type": "text",
"value": "",
"placeholder": "Optional seed for reproducibility",
"description": "Seed for reproducible randomization"
},
{
"id": "weights",
"name": "Weights",
"type": "text",
"value": "1,1",
"placeholder": "1,1,1 (comma-separated)",
"description": "Relative weights for each choice"
}
],
"execution": {
"type": "random_branch",
"blocking": true
}
},
{
"id": "try_catch",
"name": "try / catch",
"description": "Execute blocks with error handling",
"category": "control",
"shape": "control",
"icon": "Shield",
"color": "#f97316",
"nestable": true,
"parameters": [
{
"id": "retry_count",
"name": "Retry Count",
"type": "number",
"value": 0,
"min": 0,
"max": 5,
"step": 1,
"description": "Number of times to retry on failure"
},
{
"id": "continue_on_error",
"name": "Continue on Error",
"type": "boolean",
"value": false,
"description": "Continue execution even if all retries fail"
}
],
"execution": {
"type": "error_handling",
"blocking": true
}
},
{
"id": "break",
"name": "break",
"description": "Exit from the current loop or sequence",
"category": "control",
"shape": "action",
"icon": "Square",
"color": "#f97316",
"nestable": false,
"parameters": [
{
"id": "break_type",
"name": "Break Type",
"type": "select",
"value": "loop",
"options": ["loop", "sequence", "trial", "experiment"],
"description": "Scope of the break operation"
}
],
"execution": {
"type": "break",
"blocking": false
}
}
]
}

View File

@@ -0,0 +1,115 @@
{
"blockSetId": "events",
"name": "Event Triggers",
"description": "Blocks that initiate and respond to experiment events",
"version": "1.0.0",
"pluginApiVersion": "1.0",
"hriStudioVersion": ">=0.1.0",
"trustLevel": "official",
"category": "events",
"author": {
"name": "HRIStudio Team",
"email": "support@hristudio.com",
"organization": "HRIStudio"
},
"documentation": {
"mainUrl": "https://docs.hristudio.org/blocks/events",
"description": "Event blocks are the starting points for experiment sequences. They respond to trial states, participant actions, and system events."
},
"blocks": [
{
"id": "when_trial_starts",
"name": "when trial starts",
"description": "Triggered when the trial begins execution",
"category": "event",
"shape": "hat",
"icon": "Play",
"color": "#22c55e",
"nestable": false,
"parameters": [],
"execution": {
"trigger": "trial_start",
"blocking": false
}
},
{
"id": "when_participant_speaks",
"name": "when participant speaks",
"description": "Triggered when participant speech is detected",
"category": "event",
"shape": "hat",
"icon": "Mic",
"color": "#22c55e",
"nestable": false,
"parameters": [
{
"id": "duration_threshold",
"name": "Min Duration (s)",
"type": "number",
"value": 0.5,
"min": 0.1,
"max": 10,
"step": 0.1,
"description": "Minimum speech duration to trigger event"
}
],
"execution": {
"trigger": "speech_detected",
"blocking": false
}
},
{
"id": "when_timer_expires",
"name": "when timer expires",
"description": "Triggered after a specified time delay",
"category": "event",
"shape": "hat",
"icon": "Timer",
"color": "#22c55e",
"nestable": false,
"parameters": [
{
"id": "delay",
"name": "Delay (s)",
"type": "number",
"value": 5,
"min": 0.1,
"max": 300,
"step": 0.1,
"description": "Time delay before triggering"
}
],
"execution": {
"trigger": "timer",
"blocking": false
}
},
{
"id": "when_key_pressed",
"name": "when key pressed",
"description": "Triggered when wizard presses a specific key",
"category": "event",
"shape": "hat",
"icon": "Keyboard",
"color": "#22c55e",
"nestable": false,
"parameters": [
{
"id": "key",
"name": "Key",
"type": "select",
"value": "space",
"options": ["space", "enter", "1", "2", "3", "4", "5", "escape"],
"description": "Key that triggers the event"
}
],
"execution": {
"trigger": "keypress",
"blocking": false
}
}
]
}

View File

@@ -0,0 +1,51 @@
{
"plugins": [
{
"id": "events",
"name": "Event Triggers",
"description": "Blocks that initiate and respond to experiment events",
"version": "1.0.0",
"category": "events",
"file": "events.json",
"blockCount": 4,
"lastUpdated": "2025-02-13T00:00:00Z",
"tags": ["events", "triggers", "trial-start", "participant-interaction"]
},
{
"id": "wizard-actions",
"name": "Wizard Actions",
"description": "Actions performed by the human wizard during experiment execution",
"version": "1.0.0",
"category": "wizard-actions",
"file": "wizard-actions.json",
"blockCount": 6,
"lastUpdated": "2025-02-13T00:00:00Z",
"tags": ["wizard", "human", "speech", "gestures", "observation"]
},
{
"id": "control-flow",
"name": "Control Flow",
"description": "Logic blocks for conditionals, loops, timing, and experiment flow control",
"version": "1.0.0",
"category": "control-flow",
"file": "control-flow.json",
"blockCount": 8,
"lastUpdated": "2025-02-13T00:00:00Z",
"tags": ["logic", "conditionals", "loops", "timing", "flow-control"]
},
{
"id": "observation",
"name": "Observation & Sensing",
"description": "Data collection and behavioral observation blocks for capturing experiment metrics",
"version": "1.0.0",
"category": "sensors",
"file": "observation.json",
"blockCount": 9,
"lastUpdated": "2025-02-13T00:00:00Z",
"tags": ["observation", "data-collection", "sensors", "measurement", "recording"]
}
],
"total": 4,
"version": "1.0.0",
"lastUpdated": "2025-02-13T00:00:00Z"
}

View File

@@ -0,0 +1,477 @@
{
"blockSetId": "observation",
"name": "Observation & Sensing",
"description": "Data collection and behavioral observation blocks for capturing experiment metrics",
"version": "1.0.0",
"pluginApiVersion": "1.0",
"hriStudioVersion": ">=0.1.0",
"trustLevel": "official",
"category": "sensors",
"author": {
"name": "HRIStudio Team",
"email": "support@hristudio.com",
"organization": "HRIStudio"
},
"documentation": {
"mainUrl": "https://docs.hristudio.org/blocks/observation",
"description": "Observation blocks enable systematic data collection during experiments. They capture behavioral observations, sensor readings, and interaction metrics for later analysis."
},
"blocks": [
{
"id": "observe_behavior",
"name": "observe behavior",
"description": "Record behavioral observations during the trial",
"category": "sensor",
"shape": "action",
"icon": "Eye",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "behavior_type",
"name": "Behavior Type",
"type": "select",
"value": "engagement",
"options": [
"engagement",
"attention",
"confusion",
"comfort",
"compliance",
"interaction_quality",
"task_performance",
"emotional_state",
"custom"
],
"description": "Category of behavior being observed"
},
{
"id": "custom_behavior",
"name": "Custom Behavior",
"type": "text",
"value": "",
"placeholder": "Describe custom behavior",
"description": "Description for custom behavior type"
},
{
"id": "duration",
"name": "Observation Duration (s)",
"type": "number",
"value": 5,
"min": 1,
"max": 300,
"step": 1,
"description": "How long to observe the behavior"
},
{
"id": "rating_scale",
"name": "Rating Scale",
"type": "select",
"value": "1-5",
"options": ["1-3", "1-5", "1-7", "1-10", "0-100", "boolean", "notes_only"],
"description": "Scale for quantifying the observation"
}
],
"execution": {
"type": "observation",
"blocking": true,
"data_capture": true
}
},
{
"id": "measure_response_time",
"name": "measure response time",
"description": "Measure time between stimulus and participant response",
"category": "sensor",
"shape": "action",
"icon": "Stopwatch",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "stimulus_type",
"name": "Stimulus",
"type": "select",
"value": "robot_action",
"options": [
"robot_action",
"wizard_speech",
"visual_cue",
"audio_cue",
"touch",
"custom"
],
"description": "Type of stimulus that starts the timer"
},
{
"id": "response_type",
"name": "Response Type",
"type": "select",
"value": "verbal",
"options": [
"verbal",
"gesture",
"movement",
"button_press",
"eye_contact",
"any_action",
"custom"
],
"description": "Type of response that stops the timer"
},
{
"id": "timeout",
"name": "Timeout (s)",
"type": "number",
"value": 30,
"min": 1,
"max": 300,
"step": 1,
"description": "Maximum time to wait for response"
}
],
"execution": {
"type": "timing_measurement",
"blocking": true,
"data_capture": true
}
},
{
"id": "count_events",
"name": "count events",
"description": "Count occurrences of specific events or behaviors",
"category": "sensor",
"shape": "action",
"icon": "Hash",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "event_type",
"name": "Event Type",
"type": "select",
"value": "verbal_utterances",
"options": [
"verbal_utterances",
"gestures",
"eye_contact",
"interruptions",
"questions_asked",
"task_attempts",
"errors",
"custom"
],
"description": "Type of event to count"
},
{
"id": "custom_event",
"name": "Custom Event",
"type": "text",
"value": "",
"placeholder": "Describe custom event",
"description": "Description for custom event type"
},
{
"id": "counting_period",
"name": "Counting Period (s)",
"type": "number",
"value": 60,
"min": 5,
"max": 600,
"step": 5,
"description": "Duration to count events"
},
{
"id": "auto_detect",
"name": "Auto Detection",
"type": "boolean",
"value": false,
"description": "Attempt automatic detection (if supported)"
}
],
"execution": {
"type": "event_counting",
"blocking": true,
"data_capture": true
}
},
{
"id": "record_audio",
"name": "record audio",
"description": "Capture audio recording during interaction",
"category": "sensor",
"shape": "action",
"icon": "Mic",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "duration",
"name": "Duration (s)",
"type": "number",
"value": 30,
"min": 1,
"max": 600,
"step": 1,
"description": "Length of audio recording"
},
{
"id": "quality",
"name": "Quality",
"type": "select",
"value": "standard",
"options": ["low", "standard", "high", "lossless"],
"description": "Audio recording quality"
},
{
"id": "channels",
"name": "Channels",
"type": "select",
"value": "mono",
"options": ["mono", "stereo", "multi"],
"description": "Audio channel configuration"
},
{
"id": "auto_transcribe",
"name": "Auto Transcribe",
"type": "boolean",
"value": false,
"description": "Automatically transcribe speech to text"
}
],
"execution": {
"type": "audio_recording",
"blocking": true,
"data_capture": true
}
},
{
"id": "capture_video",
"name": "capture video",
"description": "Record video of the interaction",
"category": "sensor",
"shape": "action",
"icon": "Video",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "duration",
"name": "Duration (s)",
"type": "number",
"value": 30,
"min": 1,
"max": 600,
"step": 1,
"description": "Length of video recording"
},
{
"id": "camera",
"name": "Camera",
"type": "select",
"value": "primary",
"options": ["primary", "secondary", "overhead", "robot_pov", "all"],
"description": "Which camera(s) to use"
},
{
"id": "resolution",
"name": "Resolution",
"type": "select",
"value": "720p",
"options": ["480p", "720p", "1080p", "4K"],
"description": "Video resolution"
},
{
"id": "framerate",
"name": "Frame Rate",
"type": "select",
"value": "30fps",
"options": ["15fps", "30fps", "60fps", "120fps"],
"description": "Video frame rate"
}
],
"execution": {
"type": "video_recording",
"blocking": true,
"data_capture": true
}
},
{
"id": "log_event",
"name": "log event",
"description": "Record a timestamped event in the trial log",
"category": "sensor",
"shape": "action",
"icon": "FileText",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "event_name",
"name": "Event Name",
"type": "text",
"value": "",
"placeholder": "Name of the event",
"description": "Short identifier for the event"
},
{
"id": "event_data",
"name": "Event Data",
"type": "text",
"value": "",
"placeholder": "Additional data or notes",
"description": "Optional additional information"
},
{
"id": "severity",
"name": "Severity",
"type": "select",
"value": "info",
"options": ["debug", "info", "warning", "error", "critical"],
"description": "Importance level of the event"
},
{
"id": "category",
"name": "Category",
"type": "select",
"value": "experiment",
"options": [
"experiment",
"participant",
"robot",
"wizard",
"technical",
"protocol",
"custom"
],
"description": "Category for organizing events"
}
],
"execution": {
"type": "event_logging",
"blocking": false,
"data_capture": true
}
},
{
"id": "survey_question",
"name": "survey question",
"description": "Present a survey question to the participant",
"category": "sensor",
"shape": "action",
"icon": "HelpCircle",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "question",
"name": "Question",
"type": "text",
"value": "",
"placeholder": "Enter your question",
"description": "The question to ask the participant"
},
{
"id": "response_type",
"name": "Response Type",
"type": "select",
"value": "likert_5",
"options": [
"likert_5",
"likert_7",
"yes_no",
"multiple_choice",
"text_input",
"numeric",
"slider"
],
"description": "Type of response interface"
},
{
"id": "options",
"name": "Options",
"type": "text",
"value": "",
"placeholder": "Option1,Option2,Option3",
"description": "Comma-separated options for multiple choice"
},
{
"id": "required",
"name": "Required",
"type": "boolean",
"value": true,
"description": "Whether a response is required to continue"
}
],
"execution": {
"type": "survey_question",
"blocking": true,
"data_capture": true
}
},
{
"id": "physiological_measure",
"name": "physiological measure",
"description": "Capture physiological data from connected sensors",
"category": "sensor",
"shape": "action",
"icon": "Activity",
"color": "#16a34a",
"nestable": false,
"parameters": [
{
"id": "measure_type",
"name": "Measure Type",
"type": "select",
"value": "heart_rate",
"options": [
"heart_rate",
"skin_conductance",
"eye_tracking",
"eeg",
"emg",
"blood_pressure",
"temperature",
"custom"
],
"description": "Type of physiological measurement"
},
{
"id": "duration",
"name": "Measurement Duration (s)",
"type": "number",
"value": 10,
"min": 1,
"max": 300,
"step": 1,
"description": "How long to collect data"
},
{
"id": "sampling_rate",
"name": "Sampling Rate (Hz)",
"type": "number",
"value": 100,
"min": 1,
"max": 1000,
"step": 1,
"description": "Data collection frequency"
},
{
"id": "baseline",
"name": "Baseline Measurement",
"type": "boolean",
"value": false,
"description": "Mark this as a baseline measurement"
}
],
"execution": {
"type": "physiological_data",
"blocking": true,
"data_capture": true
}
}
]
}

View File

@@ -0,0 +1,240 @@
{
"blockSetId": "wizard-actions",
"name": "Wizard Actions",
"description": "Actions performed by the human wizard during experiment execution",
"version": "1.0.0",
"pluginApiVersion": "1.0",
"hriStudioVersion": ">=0.1.0",
"trustLevel": "official",
"category": "wizard-actions",
"author": {
"name": "HRIStudio Team",
"email": "support@hristudio.com",
"organization": "HRIStudio"
},
"documentation": {
"mainUrl": "https://docs.hristudio.org/blocks/wizard-actions",
"description": "Wizard action blocks define behaviors that the human experimenter performs during trials. These create prompts and interfaces for the wizard to follow the experimental protocol."
},
"blocks": [
{
"id": "wizard_say",
"name": "say",
"description": "Wizard speaks to the participant",
"category": "wizard",
"shape": "action",
"icon": "MessageSquare",
"color": "#a855f7",
"nestable": false,
"parameters": [
{
"id": "message",
"name": "Message",
"type": "text",
"value": "",
"placeholder": "What should the wizard say?",
"description": "Text that the wizard will speak to the participant"
},
{
"id": "tone",
"name": "Tone",
"type": "select",
"value": "neutral",
"options": ["neutral", "friendly", "encouraging", "instructional", "questioning"],
"description": "Suggested tone for delivery"
}
],
"execution": {
"type": "wizard_prompt",
"blocking": true,
"timeout": 30000
}
},
{
"id": "wizard_gesture",
"name": "gesture",
"description": "Wizard performs a physical gesture",
"category": "wizard",
"shape": "action",
"icon": "Hand",
"color": "#a855f7",
"nestable": false,
"parameters": [
{
"id": "type",
"name": "Gesture",
"type": "select",
"value": "wave",
"options": ["wave", "point", "nod", "thumbs_up", "beckon", "stop_hand", "applaud"],
"description": "Type of gesture to perform"
},
{
"id": "direction",
"name": "Direction",
"type": "select",
"value": "forward",
"options": ["forward", "left", "right", "up", "down", "participant", "robot"],
"description": "Direction or target of the gesture"
}
],
"execution": {
"type": "wizard_prompt",
"blocking": true,
"timeout": 15000
}
},
{
"id": "wizard_show_object",
"name": "show object",
"description": "Wizard presents or demonstrates an object",
"category": "wizard",
"shape": "action",
"icon": "Package",
"color": "#a855f7",
"nestable": false,
"parameters": [
{
"id": "object",
"name": "Object",
"type": "text",
"value": "",
"placeholder": "Name of object to show",
"description": "Description of the object to present"
},
{
"id": "action",
"name": "Action",
"type": "select",
"value": "hold_up",
"options": ["hold_up", "demonstrate", "point_to", "place_on_table", "hand_to_participant"],
"description": "How to present the object"
}
],
"execution": {
"type": "wizard_prompt",
"blocking": true,
"timeout": 20000
}
},
{
"id": "wizard_record_note",
"name": "record note",
"description": "Wizard records an observation or note",
"category": "wizard",
"shape": "action",
"icon": "PenTool",
"color": "#a855f7",
"nestable": false,
"parameters": [
{
"id": "note_type",
"name": "Note Type",
"type": "select",
"value": "observation",
"options": ["observation", "participant_response", "technical_issue", "protocol_deviation", "other"],
"description": "Category of note being recorded"
},
{
"id": "prompt",
"name": "Prompt",
"type": "text",
"value": "",
"placeholder": "What should the wizard note?",
"description": "Guidance for what to observe or record"
}
],
"execution": {
"type": "wizard_prompt",
"blocking": true,
"timeout": 60000
}
},
{
"id": "wizard_wait_for_response",
"name": "wait for response",
"description": "Wizard waits for participant to respond",
"category": "wizard",
"shape": "action",
"icon": "Clock",
"color": "#a855f7",
"nestable": false,
"parameters": [
{
"id": "response_type",
"name": "Response Type",
"type": "select",
"value": "verbal",
"options": ["verbal", "gesture", "action", "button_press", "any"],
"description": "Type of response to wait for"
},
{
"id": "timeout",
"name": "Timeout (s)",
"type": "number",
"value": 30,
"min": 1,
"max": 300,
"step": 1,
"description": "Maximum time to wait for response"
},
{
"id": "prompt_text",
"name": "Prompt",
"type": "text",
"value": "",
"placeholder": "Optional prompt for participant",
"description": "Text to display to guide participant response"
}
],
"execution": {
"type": "wizard_prompt",
"blocking": true,
"timeout": 300000
}
},
{
"id": "wizard_rate_interaction",
"name": "rate interaction",
"description": "Wizard provides a subjective rating",
"category": "wizard",
"shape": "action",
"icon": "Star",
"color": "#a855f7",
"nestable": false,
"parameters": [
{
"id": "rating_type",
"name": "Rating Type",
"type": "select",
"value": "engagement",
"options": ["engagement", "comprehension", "comfort", "success", "naturalness", "custom"],
"description": "Aspect being rated"
},
{
"id": "scale",
"name": "Scale",
"type": "select",
"value": "1-5",
"options": ["1-5", "1-7", "1-10", "0-100"],
"description": "Rating scale to use"
},
{
"id": "custom_label",
"name": "Custom Label",
"type": "text",
"value": "",
"placeholder": "Label for custom rating type",
"description": "Description for custom rating (if selected)"
}
],
"execution": {
"type": "wizard_prompt",
"blocking": true,
"timeout": 30000
}
}
]
}

View File

@@ -0,0 +1,66 @@
{
"id": "hristudio-core",
"name": "HRIStudio Core Blocks",
"description": "Essential system blocks for experiment design including control flow, wizard actions, and basic functionality",
"urls": {
"git": "https://github.com/soconnor0919/hristudio-core",
"repository": "https://core.hristudio.com"
},
"official": true,
"trust": "official",
"apiVersion": "1.0",
"pluginApiVersion": "1.0",
"author": {
"name": "HRIStudio Team",
"email": "support@hristudio.com",
"url": "https://hristudio.com",
"organization": "HRIStudio"
},
"maintainers": [
{
"name": "Sean O'Connor",
"url": "https://github.com/soconnor0919"
}
],
"homepage": "https://hristudio.org/core",
"license": "MIT",
"defaultBranch": "main",
"lastUpdated": "2025-02-13T00:00:00Z",
"categories": [
{
"id": "events",
"name": "Event Triggers",
"description": "Blocks that initiate experiment sequences"
},
{
"id": "wizard-actions",
"name": "Wizard Actions",
"description": "Actions performed by the human wizard"
},
{
"id": "control-flow",
"name": "Control Flow",
"description": "Logic blocks for conditionals, loops, and timing"
},
{
"id": "sensors",
"name": "Observation & Sensing",
"description": "Data collection and behavioral observation blocks"
}
],
"compatibility": {
"hristudio": {
"min": "0.1.0",
"recommended": "0.1.0"
}
},
"assets": {
"icon": "assets/core-icon.png",
"logo": "assets/core-logo.png",
"banner": "assets/core-banner.png"
},
"tags": ["official", "core", "essential", "wizard-of-oz"],
"stats": {
"plugins": 4
}
}