mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 22:04:56 +00:00
feat: Add JSON Script Example and Lua Test Framework
- Created a new package for JSON Script Example with comprehensive examples demonstrating the full JSON script specification. - Added permissions for viewing, executing, and modifying examples in the JSON Script Example package. - Implemented functions for various expressions, statements, operators, and control flow in the JSON Script Example. - Developed a Storybook configuration for showcasing JSON Script Examples with interactive components. - Established a styles token file for consistent styling across the JSON Script Example package. - Introduced a new Lua Test Framework package with components for running and displaying test results. - Defined permissions for executing and viewing Lua test results, along with configuration and debugging capabilities. - Implemented a comprehensive set of functions for the Lua testing framework, including assertions and mocks. - Created Storybook stories for the Lua Test Framework to demonstrate the test runner and results display. - Added a styles token file for the Lua Test Framework to ensure a cohesive design.
This commit is contained in:
440
packages/forum_forge/components/ui.json
Normal file
440
packages/forum_forge/components/ui.json
Normal file
@@ -0,0 +1,440 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"package": "forum_forge",
|
||||
"description": "Forum Forge UI components including category lists, thread views, and moderation panels",
|
||||
"components": [
|
||||
{
|
||||
"id": "forum_root",
|
||||
"name": "ForumRoot",
|
||||
"description": "Main forum container with hero section, stats, and navigation",
|
||||
"props": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "Forum Forge",
|
||||
"description": "Forum title"
|
||||
},
|
||||
{
|
||||
"name": "subtitle",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "A modern discussion hub with curated categories, rapid replies, and moderator-ready queues.",
|
||||
"description": "Forum subtitle"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 3,
|
||||
"className": "forum-forge-root",
|
||||
"children": [
|
||||
{
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "forum-hero",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"sx": { "p": 3 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h4",
|
||||
"fontWeight": "bold",
|
||||
"children": "{{title}}"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body1",
|
||||
"color": "secondary",
|
||||
"children": "{{subtitle}}"
|
||||
},
|
||||
{
|
||||
"type": "Flex",
|
||||
"gap": 1,
|
||||
"children": [
|
||||
{
|
||||
"type": "Button",
|
||||
"variant": "contained",
|
||||
"color": "primary",
|
||||
"children": "Start new thread"
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"variant": "outlined",
|
||||
"children": "Browse categories"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "forum_stat_card",
|
||||
"name": "ForumStatCard",
|
||||
"description": "Stat card for forum metrics (active threads, replies, flags)",
|
||||
"props": [
|
||||
{
|
||||
"name": "label",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Stat label"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Stat value"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "forum-stat-card",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 0.5,
|
||||
"sx": { "p": 2 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "{{label}}"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h5",
|
||||
"fontWeight": "semibold",
|
||||
"children": "{{value}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "forum_stats_grid",
|
||||
"name": "ForumStatsGrid",
|
||||
"description": "Grid layout for forum statistics",
|
||||
"props": [
|
||||
{
|
||||
"name": "activeThreads",
|
||||
"type": "string",
|
||||
"default": "246"
|
||||
},
|
||||
{
|
||||
"name": "repliesToday",
|
||||
"type": "string",
|
||||
"default": "1,092"
|
||||
},
|
||||
{
|
||||
"name": "queuedFlags",
|
||||
"type": "string",
|
||||
"default": "8"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Grid",
|
||||
"container": true,
|
||||
"spacing": 2,
|
||||
"className": "forum-stats-grid",
|
||||
"children": [
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"sm": 4,
|
||||
"children": [
|
||||
{
|
||||
"type": "ForumStatCard",
|
||||
"label": "Active threads",
|
||||
"value": "{{activeThreads}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"sm": 4,
|
||||
"children": [
|
||||
{
|
||||
"type": "ForumStatCard",
|
||||
"label": "Replies today",
|
||||
"value": "{{repliesToday}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"sm": 4,
|
||||
"children": [
|
||||
{
|
||||
"type": "ForumStatCard",
|
||||
"label": "Queued flags",
|
||||
"value": "{{queuedFlags}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "category_card",
|
||||
"name": "CategoryCard",
|
||||
"description": "Card displaying a forum category with title and description",
|
||||
"props": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Category title"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Category description"
|
||||
},
|
||||
{
|
||||
"name": "onClick",
|
||||
"type": "function",
|
||||
"required": false,
|
||||
"description": "Click handler"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "forum-category-card",
|
||||
"onClick": "{{onClick}}",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 0.5,
|
||||
"sx": { "p": 2 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h6",
|
||||
"fontWeight": "semibold",
|
||||
"children": "{{title}}"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body2",
|
||||
"color": "secondary",
|
||||
"children": "{{description}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "category_list",
|
||||
"name": "CategoryList",
|
||||
"description": "List of forum categories",
|
||||
"props": [
|
||||
{
|
||||
"name": "categories",
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"default": [],
|
||||
"description": "Array of category objects"
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"type": "string",
|
||||
"default": "Featured categories"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "forum-categories",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"sx": { "p": 3 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h5",
|
||||
"fontWeight": "semibold",
|
||||
"children": "{{title}}"
|
||||
},
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 1.5,
|
||||
"children": {
|
||||
"type": "loop",
|
||||
"items": "{{categories}}",
|
||||
"itemKey": "id",
|
||||
"template": {
|
||||
"type": "CategoryCard",
|
||||
"title": "{{item.title}}",
|
||||
"description": "{{item.description}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "thread_card",
|
||||
"name": "ThreadCard",
|
||||
"description": "Card displaying a forum thread with title and metadata",
|
||||
"props": [
|
||||
{
|
||||
"name": "title",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Thread title"
|
||||
},
|
||||
{
|
||||
"name": "replyCount",
|
||||
"type": "number",
|
||||
"required": false,
|
||||
"default": 0,
|
||||
"description": "Number of replies"
|
||||
},
|
||||
{
|
||||
"name": "lastUpdated",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Last update time"
|
||||
},
|
||||
{
|
||||
"name": "onClick",
|
||||
"type": "function",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "forum-thread-card",
|
||||
"onClick": "{{onClick}}",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 0.5,
|
||||
"sx": { "p": 2 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "subtitle1",
|
||||
"fontWeight": "semibold",
|
||||
"children": "{{title}}"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "{{replyCount}} replies · Updated {{lastUpdated}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "thread_list",
|
||||
"name": "ThreadList",
|
||||
"description": "List of forum threads",
|
||||
"props": [
|
||||
{
|
||||
"name": "threads",
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"default": [],
|
||||
"description": "Array of thread objects"
|
||||
},
|
||||
{
|
||||
"name": "title",
|
||||
"type": "string",
|
||||
"default": "Trending threads"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "forum-threads",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 2,
|
||||
"sx": { "p": 3 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h5",
|
||||
"fontWeight": "semibold",
|
||||
"children": "{{title}}"
|
||||
},
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "column",
|
||||
"gap": 1.5,
|
||||
"children": {
|
||||
"type": "loop",
|
||||
"items": "{{threads}}",
|
||||
"itemKey": "id",
|
||||
"template": {
|
||||
"type": "ThreadCard",
|
||||
"title": "{{item.title}}",
|
||||
"replyCount": "{{item.replyCount}}",
|
||||
"lastUpdated": "{{item.lastUpdated}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
62
packages/forum_forge/package.json
Normal file
62
packages/forum_forge/package.json
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-metadata.schema.json",
|
||||
"packageId": "forum_forge",
|
||||
"name": "Forum Forge",
|
||||
"version": "1.0.0",
|
||||
"description": "Modern forum starter with categories, threads, and moderation lanes",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"category": "social",
|
||||
"minLevel": 2,
|
||||
"primary": true,
|
||||
"icon": "static_content/icon.svg",
|
||||
"keywords": ["forum", "discussion", "threads", "moderation", "community"],
|
||||
"dependencies": {
|
||||
"ui_permissions": "^1.0.0",
|
||||
"data_table": "^1.0.0",
|
||||
"form_builder": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"lua_test": "^1.0.0"
|
||||
},
|
||||
"exports": {
|
||||
"components": [
|
||||
"ForumRoot",
|
||||
"CategoryList",
|
||||
"ThreadList",
|
||||
"ThreadCard",
|
||||
"StatCard"
|
||||
],
|
||||
"scripts": [
|
||||
"create_thread",
|
||||
"view_categories",
|
||||
"thread_list",
|
||||
"init",
|
||||
"permissions",
|
||||
"thread_rank",
|
||||
"moderation"
|
||||
]
|
||||
},
|
||||
"tests": {
|
||||
"scripts": [
|
||||
"tests/metadata.test.lua",
|
||||
"tests/components.test.lua"
|
||||
],
|
||||
"parameterized": [
|
||||
{
|
||||
"parameters": "tests/metadata.cases.json"
|
||||
},
|
||||
{
|
||||
"parameters": "tests/components.cases.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"schema": {
|
||||
"entities": [
|
||||
"ForumCategory",
|
||||
"ForumThread",
|
||||
"ForumPost"
|
||||
],
|
||||
"path": "schema/entities.yaml"
|
||||
}
|
||||
}
|
||||
121
packages/forum_forge/permissions/roles.json
Normal file
121
packages/forum_forge/permissions/roles.json
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/permissions.schema.json",
|
||||
"schemaVersion": "1.0.0",
|
||||
"package": "forum_forge",
|
||||
"description": "Forum Forge access permissions for posting, viewing, and moderation",
|
||||
"permissions": [
|
||||
{
|
||||
"id": "forum.view",
|
||||
"name": "View Forum",
|
||||
"description": "View forum categories and threads",
|
||||
"resource": "forum",
|
||||
"action": "read",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "forum.thread.create",
|
||||
"name": "Create Thread",
|
||||
"description": "Create new forum threads",
|
||||
"resource": "forum.thread",
|
||||
"action": "create",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "forum.post.create",
|
||||
"name": "Create Post",
|
||||
"description": "Create posts/replies in forum threads",
|
||||
"resource": "forum.post",
|
||||
"action": "create",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "forum.moderate",
|
||||
"name": "Moderate Forum",
|
||||
"description": "Moderate forum content including flagging, editing, and removing posts",
|
||||
"resource": "forum",
|
||||
"action": "moderate",
|
||||
"scope": "global",
|
||||
"minLevel": 3
|
||||
},
|
||||
{
|
||||
"id": "forum.category.manage",
|
||||
"name": "Manage Categories",
|
||||
"description": "Create, edit, and delete forum categories",
|
||||
"resource": "forum.category",
|
||||
"action": "manage",
|
||||
"scope": "global",
|
||||
"minLevel": 4
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"id": "forum",
|
||||
"name": "Forum",
|
||||
"type": "content",
|
||||
"description": "Forum resources including categories, threads, and posts",
|
||||
"actions": ["read", "moderate"]
|
||||
},
|
||||
{
|
||||
"id": "forum.thread",
|
||||
"name": "Forum Thread",
|
||||
"type": "content",
|
||||
"description": "Forum thread resources",
|
||||
"actions": ["create", "read", "update", "delete"]
|
||||
},
|
||||
{
|
||||
"id": "forum.post",
|
||||
"name": "Forum Post",
|
||||
"type": "content",
|
||||
"description": "Forum post/reply resources",
|
||||
"actions": ["create", "read", "update", "delete"]
|
||||
},
|
||||
{
|
||||
"id": "forum.category",
|
||||
"name": "Forum Category",
|
||||
"type": "config",
|
||||
"description": "Forum category configuration",
|
||||
"actions": ["manage", "read"]
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"id": "forum.user",
|
||||
"name": "Forum User",
|
||||
"description": "Standard forum user who can view and post",
|
||||
"minLevel": 2,
|
||||
"permissions": [
|
||||
"forum.view",
|
||||
"forum.thread.create",
|
||||
"forum.post.create"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "forum.moderator",
|
||||
"name": "Forum Moderator",
|
||||
"description": "Forum moderator who can manage content",
|
||||
"minLevel": 3,
|
||||
"permissions": [
|
||||
"forum.view",
|
||||
"forum.thread.create",
|
||||
"forum.post.create",
|
||||
"forum.moderate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "forum.admin",
|
||||
"name": "Forum Administrator",
|
||||
"description": "Forum administrator with full access",
|
||||
"minLevel": 4,
|
||||
"permissions": [
|
||||
"forum.view",
|
||||
"forum.thread.create",
|
||||
"forum.post.create",
|
||||
"forum.moderate",
|
||||
"forum.category.manage"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
102
packages/forum_forge/scripts/functions.json
Normal file
102
packages/forum_forge/scripts/functions.json
Normal file
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script.schema.json",
|
||||
"schemaVersion": "2.2.0",
|
||||
"package": "forum_forge",
|
||||
"description": "Forum Forge script functions for thread management, permissions, ranking, and moderation",
|
||||
"functions": [
|
||||
{
|
||||
"id": "forum_init",
|
||||
"name": "init",
|
||||
"exported": true,
|
||||
"description": "Initialize Forum Forge package",
|
||||
"category": "lifecycle",
|
||||
"luaScript": "init.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_on_install",
|
||||
"name": "onInstall",
|
||||
"exported": true,
|
||||
"description": "Package installation hook",
|
||||
"category": "lifecycle",
|
||||
"luaScript": "init.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_on_uninstall",
|
||||
"name": "onUninstall",
|
||||
"exported": true,
|
||||
"description": "Package uninstallation hook",
|
||||
"category": "lifecycle",
|
||||
"luaScript": "init.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_can_post",
|
||||
"name": "canPost",
|
||||
"exported": true,
|
||||
"description": "Check if user has permission to post in forum",
|
||||
"category": "permissions",
|
||||
"luaScript": "permissions.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_can_moderate",
|
||||
"name": "canModerate",
|
||||
"exported": true,
|
||||
"description": "Check if user has permission to moderate forum",
|
||||
"category": "permissions",
|
||||
"luaScript": "permissions.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_rank_thread",
|
||||
"name": "rankThread",
|
||||
"exported": true,
|
||||
"description": "Calculate thread ranking score based on recency and engagement",
|
||||
"category": "ranking",
|
||||
"luaScript": "thread_rank.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_flag_post",
|
||||
"name": "flagPost",
|
||||
"exported": true,
|
||||
"description": "Flag a post for moderation review",
|
||||
"category": "moderation",
|
||||
"luaScript": "moderation.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_create_thread",
|
||||
"name": "createThread",
|
||||
"exported": true,
|
||||
"description": "Create a new forum thread",
|
||||
"category": "threads",
|
||||
"luaScript": "threads.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_view_categories",
|
||||
"name": "viewCategories",
|
||||
"exported": true,
|
||||
"description": "Retrieve and render forum categories",
|
||||
"category": "categories",
|
||||
"luaScript": "categories.lua"
|
||||
},
|
||||
{
|
||||
"id": "forum_thread_list",
|
||||
"name": "threadList",
|
||||
"exported": true,
|
||||
"description": "Retrieve and render thread list",
|
||||
"category": "threads",
|
||||
"luaScript": "threads.lua"
|
||||
}
|
||||
],
|
||||
"exports": {
|
||||
"functions": [
|
||||
"init",
|
||||
"onInstall",
|
||||
"onUninstall",
|
||||
"canPost",
|
||||
"canModerate",
|
||||
"rankThread",
|
||||
"flagPost",
|
||||
"createThread",
|
||||
"viewCategories",
|
||||
"threadList"
|
||||
]
|
||||
}
|
||||
}
|
||||
160
packages/forum_forge/storybook/stories.json
Normal file
160
packages/forum_forge/storybook/stories.json
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json",
|
||||
"featured": true,
|
||||
"title": "Forum Forge Components",
|
||||
"description": "Modern forum UI with categories, threads, and moderation",
|
||||
"stories": [
|
||||
{
|
||||
"name": "CreateThread",
|
||||
"render": "create_thread",
|
||||
"description": "Thread creation form with category selection and rich text editor",
|
||||
"args": {
|
||||
"categoryId": "launch-radar",
|
||||
"title": "",
|
||||
"content": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ViewCategories",
|
||||
"render": "view_categories",
|
||||
"description": "Browse all forum categories",
|
||||
"args": {
|
||||
"categories": [
|
||||
{
|
||||
"id": "launch-radar",
|
||||
"title": "Launch Radar",
|
||||
"description": "Share product launches, traction stories, and founder notes."
|
||||
},
|
||||
{
|
||||
"id": "growth-ops",
|
||||
"title": "Growth Ops",
|
||||
"description": "Tactics for onboarding, retention, and community rituals."
|
||||
},
|
||||
{
|
||||
"id": "dev-lounge",
|
||||
"title": "Dev Lounge",
|
||||
"description": "Deep dives on tooling, architecture, and deployment patterns."
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ThreadList",
|
||||
"render": "thread_list",
|
||||
"description": "View trending threads with engagement metrics",
|
||||
"args": {
|
||||
"threads": [
|
||||
{
|
||||
"id": "thread-1",
|
||||
"title": "What does your onboarding checklist look like in 2025?",
|
||||
"replyCount": 128,
|
||||
"lastUpdated": "2h ago"
|
||||
},
|
||||
{
|
||||
"id": "thread-2",
|
||||
"title": "Best practices for AI-assisted moderation?",
|
||||
"replyCount": 64,
|
||||
"lastUpdated": "30m ago"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ForumStats",
|
||||
"render": "stats",
|
||||
"description": "Forum statistics dashboard",
|
||||
"args": {
|
||||
"activeThreads": "246",
|
||||
"repliesToday": "1,092",
|
||||
"queuedFlags": "8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ModerationQueue",
|
||||
"render": "moderation_queue",
|
||||
"description": "Moderation queue for flagged content",
|
||||
"type": "function",
|
||||
"args": {
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"renders": {
|
||||
"create_thread": {
|
||||
"description": "Thread creation form",
|
||||
"featured": true
|
||||
},
|
||||
"view_categories": {
|
||||
"description": "Category browser",
|
||||
"featured": true
|
||||
},
|
||||
"thread_list": {
|
||||
"description": "Trending threads list",
|
||||
"featured": true
|
||||
},
|
||||
"stats": {
|
||||
"description": "Forum statistics overview"
|
||||
},
|
||||
"moderation_queue": {
|
||||
"description": "Moderation queue for flagged posts"
|
||||
}
|
||||
},
|
||||
"defaultContext": {
|
||||
"user": {
|
||||
"id": "demo-user",
|
||||
"username": "demo_user",
|
||||
"level": 2,
|
||||
"email": "demo@example.com"
|
||||
},
|
||||
"tenant": {
|
||||
"id": "demo-tenant",
|
||||
"name": "Demo Organization"
|
||||
}
|
||||
},
|
||||
"contextVariants": [
|
||||
{
|
||||
"name": "Standard User",
|
||||
"description": "Can view and post in forums",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "user",
|
||||
"level": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Moderator",
|
||||
"description": "Can view, post, and moderate forums",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "moderator",
|
||||
"level": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin",
|
||||
"description": "Full forum access including category management",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "admin",
|
||||
"level": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"renderFunctions": ["create_thread", "view_categories", "thread_list", "stats", "moderation_queue"],
|
||||
"ignoredScripts": ["tests"]
|
||||
},
|
||||
"parameters": {
|
||||
"layout": "padded",
|
||||
"backgrounds": {
|
||||
"default": "light",
|
||||
"values": [
|
||||
{ "name": "light", "value": "#f5f5f5" },
|
||||
{ "name": "dark", "value": "#1a1a1a" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
70
packages/forum_forge/styles/tokens.json
Normal file
70
packages/forum_forge/styles/tokens.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-styles.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"package": "forum_forge",
|
||||
"description": "Design tokens for Forum Forge components",
|
||||
"colors": {
|
||||
"categoryPrimary": "#3b82f6",
|
||||
"categorySecondary": "#8b5cf6",
|
||||
"threadActive": "#22c55e",
|
||||
"threadPinned": "#f59e0b",
|
||||
"flagWarning": "#ef4444",
|
||||
"flagPending": "#f97316",
|
||||
"moderatorBadge": "#6366f1",
|
||||
"replyHighlight": "#dbeafe",
|
||||
"statPositive": "#28a745",
|
||||
"statNegative": "#dc3545",
|
||||
"statNeutral": "#6c757d"
|
||||
},
|
||||
"spacing": {
|
||||
"cardPadding": "16px",
|
||||
"sectionGap": "24px",
|
||||
"listItemGap": "12px",
|
||||
"statsGrid": "16px",
|
||||
"heroSection": "24px"
|
||||
},
|
||||
"shadows": {
|
||||
"card": "0 2px 8px rgba(0, 0, 0, 0.1)",
|
||||
"cardHover": "0 4px 16px rgba(0, 0, 0, 0.15)",
|
||||
"statCard": "0 1px 4px rgba(0, 0, 0, 0.08)",
|
||||
"categoryCard": "0 2px 6px rgba(0, 0, 0, 0.08)"
|
||||
},
|
||||
"borders": {
|
||||
"cardRadius": "8px",
|
||||
"buttonRadius": "6px",
|
||||
"badgeRadius": "4px",
|
||||
"defaultBorder": "1px solid #e5e7eb"
|
||||
},
|
||||
"typography": {
|
||||
"heroTitle": {
|
||||
"fontSize": "1.5rem",
|
||||
"fontWeight": 700,
|
||||
"lineHeight": 1.3
|
||||
},
|
||||
"sectionTitle": {
|
||||
"fontSize": "1.25rem",
|
||||
"fontWeight": 600,
|
||||
"lineHeight": 1.4
|
||||
},
|
||||
"threadTitle": {
|
||||
"fontSize": "1.125rem",
|
||||
"fontWeight": 600,
|
||||
"lineHeight": 1.4
|
||||
},
|
||||
"statValue": {
|
||||
"fontSize": "1.25rem",
|
||||
"fontWeight": 600,
|
||||
"lineHeight": 1.2
|
||||
},
|
||||
"statLabel": {
|
||||
"fontSize": "0.875rem",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": 1.5
|
||||
},
|
||||
"meta": {
|
||||
"fontSize": "0.75rem",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": 1.5
|
||||
}
|
||||
}
|
||||
}
|
||||
527
packages/github_tools/components/ui.json
Normal file
527
packages/github_tools/components/ui.json
Normal file
@@ -0,0 +1,527 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"package": "github_tools",
|
||||
"description": "GitHub Tools components for Actions viewer, run analysis, and workflow management",
|
||||
"components": [
|
||||
{
|
||||
"id": "github_viewer",
|
||||
"name": "GitHubViewer",
|
||||
"description": "Main GitHub Actions viewer component",
|
||||
"props": [
|
||||
{
|
||||
"name": "owner",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Repository owner"
|
||||
},
|
||||
{
|
||||
"name": "repo",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Repository name"
|
||||
},
|
||||
{
|
||||
"name": "workflow",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Workflow file name filter"
|
||||
},
|
||||
{
|
||||
"name": "token",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "GitHub API token"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "github-viewer",
|
||||
"children": [
|
||||
{
|
||||
"type": "CardHeader",
|
||||
"title": "GitHub Actions",
|
||||
"subtitle": "{{owner}}/{{repo}}"
|
||||
},
|
||||
{
|
||||
"type": "CardContent",
|
||||
"children": [
|
||||
{
|
||||
"type": "RunFilters",
|
||||
"props": {}
|
||||
},
|
||||
{
|
||||
"type": "RunList",
|
||||
"props": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"init": "init.initialize",
|
||||
"fetchRuns": "fetch_runs.fetchRuns",
|
||||
"filterRuns": "filter.filterRuns"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "run_list",
|
||||
"name": "RunList",
|
||||
"description": "List of workflow runs with status badges",
|
||||
"props": [
|
||||
{
|
||||
"name": "runs",
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"default": [],
|
||||
"description": "Array of workflow runs"
|
||||
},
|
||||
{
|
||||
"name": "loading",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"default": false,
|
||||
"description": "Loading state indicator"
|
||||
},
|
||||
{
|
||||
"name": "onSelect",
|
||||
"type": "function",
|
||||
"required": false,
|
||||
"description": "Callback when a run is selected"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Stack",
|
||||
"spacing": 2,
|
||||
"className": "run-list",
|
||||
"children": [
|
||||
{
|
||||
"type": "conditional",
|
||||
"condition": "{{loading}}",
|
||||
"then": {
|
||||
"type": "Box",
|
||||
"sx": { "display": "flex", "justifyContent": "center", "p": 4 },
|
||||
"children": [
|
||||
{
|
||||
"type": "CircularProgress"
|
||||
}
|
||||
]
|
||||
},
|
||||
"else": {
|
||||
"type": "iterate",
|
||||
"items": "{{runs}}",
|
||||
"render": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"sx": { "cursor": "pointer" },
|
||||
"onClick": "{{onSelect}}",
|
||||
"children": [
|
||||
{
|
||||
"type": "CardContent",
|
||||
"children": [
|
||||
{
|
||||
"type": "Flex",
|
||||
"justifyContent": "space-between",
|
||||
"alignItems": "center",
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "subtitle1",
|
||||
"children": "{{item.name}}"
|
||||
},
|
||||
{
|
||||
"type": "StatusBadge",
|
||||
"status": "{{item.conclusion || item.status}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "run_details",
|
||||
"name": "RunDetails",
|
||||
"description": "Detailed view of a single workflow run",
|
||||
"props": [
|
||||
{
|
||||
"name": "run",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"description": "Selected workflow run"
|
||||
},
|
||||
{
|
||||
"name": "jobs",
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"default": [],
|
||||
"description": "Array of jobs for the run"
|
||||
},
|
||||
{
|
||||
"name": "logs",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "",
|
||||
"description": "Log content"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "run-details",
|
||||
"children": [
|
||||
{
|
||||
"type": "CardHeader",
|
||||
"title": "Run Details",
|
||||
"subtitle": "{{run.name}}"
|
||||
},
|
||||
{
|
||||
"type": "CardContent",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"spacing": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "StatusBadge",
|
||||
"status": "{{run.conclusion || run.status}}"
|
||||
},
|
||||
{
|
||||
"type": "Divider"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "subtitle2",
|
||||
"children": "Jobs"
|
||||
},
|
||||
{
|
||||
"type": "iterate",
|
||||
"items": "{{jobs}}",
|
||||
"render": {
|
||||
"type": "Flex",
|
||||
"alignItems": "center",
|
||||
"gap": 1,
|
||||
"children": [
|
||||
{
|
||||
"type": "StatusBadge",
|
||||
"status": "{{item.conclusion || item.status}}"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"children": "{{item.name}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "conditional",
|
||||
"condition": "{{logs}}",
|
||||
"then": {
|
||||
"type": "Box",
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "subtitle2",
|
||||
"children": "Logs"
|
||||
},
|
||||
{
|
||||
"type": "Paper",
|
||||
"variant": "outlined",
|
||||
"sx": {
|
||||
"p": 2,
|
||||
"fontFamily": "monospace",
|
||||
"fontSize": "0.875rem",
|
||||
"maxHeight": 400,
|
||||
"overflow": "auto",
|
||||
"backgroundColor": "#1e1e1e",
|
||||
"color": "#d4d4d4"
|
||||
},
|
||||
"children": "{{logs}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "analysis_panel",
|
||||
"name": "AnalysisPanel",
|
||||
"description": "Statistics and analysis of workflow runs",
|
||||
"props": [
|
||||
{
|
||||
"name": "stats",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"default": {},
|
||||
"description": "Statistics object"
|
||||
},
|
||||
{
|
||||
"name": "timeRange",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "7d",
|
||||
"description": "Time range for analysis"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "analysis-panel",
|
||||
"children": [
|
||||
{
|
||||
"type": "CardHeader",
|
||||
"title": "Run Analysis"
|
||||
},
|
||||
{
|
||||
"type": "CardContent",
|
||||
"children": [
|
||||
{
|
||||
"type": "Grid",
|
||||
"container": true,
|
||||
"spacing": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"md": 3,
|
||||
"children": [
|
||||
{
|
||||
"type": "StatCard",
|
||||
"label": "Total Runs",
|
||||
"value": "{{stats.total || 0}}",
|
||||
"icon": "PlayArrow",
|
||||
"color": "primary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"md": 3,
|
||||
"children": [
|
||||
{
|
||||
"type": "StatCard",
|
||||
"label": "Success",
|
||||
"value": "{{stats.success || 0}}",
|
||||
"icon": "CheckCircle",
|
||||
"color": "success"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"md": 3,
|
||||
"children": [
|
||||
{
|
||||
"type": "StatCard",
|
||||
"label": "Failures",
|
||||
"value": "{{stats.failure || 0}}",
|
||||
"icon": "Cancel",
|
||||
"color": "error"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"md": 3,
|
||||
"children": [
|
||||
{
|
||||
"type": "StatCard",
|
||||
"label": "Success Rate",
|
||||
"value": "{{stats.success_rate || 0}}%",
|
||||
"icon": "TrendingUp",
|
||||
"color": "info"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"calculate": "analyze.calculateStats"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "run_filters",
|
||||
"name": "RunFilters",
|
||||
"description": "Filter controls for workflow runs",
|
||||
"props": [
|
||||
{
|
||||
"name": "status",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "all",
|
||||
"description": "Status filter value"
|
||||
},
|
||||
{
|
||||
"name": "branch",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "",
|
||||
"description": "Branch filter value"
|
||||
},
|
||||
{
|
||||
"name": "dateRange",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "7d",
|
||||
"description": "Date range filter value"
|
||||
},
|
||||
{
|
||||
"name": "onChange",
|
||||
"type": "function",
|
||||
"required": false,
|
||||
"description": "Callback when filters change"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Stack",
|
||||
"direction": "row",
|
||||
"spacing": 2,
|
||||
"className": "run-filters",
|
||||
"sx": { "mb": 2 },
|
||||
"children": [
|
||||
{
|
||||
"type": "FormControl",
|
||||
"size": "small",
|
||||
"sx": { "minWidth": 120 },
|
||||
"children": [
|
||||
{
|
||||
"type": "InputLabel",
|
||||
"children": "Status"
|
||||
},
|
||||
{
|
||||
"type": "Select",
|
||||
"label": "Status",
|
||||
"name": "status",
|
||||
"value": "{{status}}",
|
||||
"onChange": "{{onChange}}",
|
||||
"options": [
|
||||
{ "value": "all", "label": "All" },
|
||||
{ "value": "success", "label": "Success" },
|
||||
{ "value": "failure", "label": "Failure" },
|
||||
{ "value": "pending", "label": "Pending" }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "TextField",
|
||||
"label": "Branch",
|
||||
"name": "branch",
|
||||
"size": "small",
|
||||
"value": "{{branch}}",
|
||||
"onChange": "{{onChange}}",
|
||||
"placeholder": "main"
|
||||
},
|
||||
{
|
||||
"type": "FormControl",
|
||||
"size": "small",
|
||||
"sx": { "minWidth": 140 },
|
||||
"children": [
|
||||
{
|
||||
"type": "InputLabel",
|
||||
"children": "Time Range"
|
||||
},
|
||||
{
|
||||
"type": "Select",
|
||||
"label": "Time Range",
|
||||
"name": "dateRange",
|
||||
"value": "{{dateRange}}",
|
||||
"onChange": "{{onChange}}",
|
||||
"options": [
|
||||
{ "value": "1d", "label": "Last 24 hours" },
|
||||
{ "value": "7d", "label": "Last 7 days" },
|
||||
{ "value": "30d", "label": "Last 30 days" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"onChange": "filter.applyFilters"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "status_badge",
|
||||
"name": "StatusBadge",
|
||||
"description": "Status badge showing run conclusion with appropriate color and icon",
|
||||
"props": [
|
||||
{
|
||||
"name": "status",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Run status (success, failure, pending, in_progress, cancelled, skipped)"
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "small",
|
||||
"description": "Badge size"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Chip",
|
||||
"label": "{{status | statusLabel}}",
|
||||
"color": "{{status | statusColor}}",
|
||||
"size": "{{size}}",
|
||||
"icon": "{{status | statusIcon}}"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"statusLabel": "status.getStatusLabel",
|
||||
"statusColor": "status.getStatusColor",
|
||||
"statusIcon": "status.getStatusIcon"
|
||||
}
|
||||
}
|
||||
],
|
||||
"exports": {
|
||||
"components": [
|
||||
"GitHubViewer",
|
||||
"RunList",
|
||||
"RunDetails",
|
||||
"AnalysisPanel",
|
||||
"RunFilters",
|
||||
"StatusBadge"
|
||||
]
|
||||
}
|
||||
}
|
||||
47
packages/github_tools/package.json
Normal file
47
packages/github_tools/package.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-metadata.schema.json",
|
||||
"packageId": "github_tools",
|
||||
"name": "GitHub Tools",
|
||||
"version": "1.0.0",
|
||||
"description": "GitHub integration tools including Actions viewer, run analysis, and workflow management",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"category": "development",
|
||||
"minLevel": 2,
|
||||
"primary": true,
|
||||
"tags": [
|
||||
"github",
|
||||
"ci-cd",
|
||||
"workflow",
|
||||
"actions"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"lua_test": "*"
|
||||
},
|
||||
"exports": {
|
||||
"components": [
|
||||
"GitHubViewer",
|
||||
"RunList",
|
||||
"RunDetails",
|
||||
"AnalysisPanel",
|
||||
"RunFilters"
|
||||
],
|
||||
"scripts": [
|
||||
"fetch_runs",
|
||||
"analyze",
|
||||
"filter",
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"tests": {
|
||||
"scripts": [
|
||||
"tests/metadata.test.lua"
|
||||
],
|
||||
"parameterized": [
|
||||
{
|
||||
"parameters": "tests/metadata.cases.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
83
packages/github_tools/permissions/roles.json
Normal file
83
packages/github_tools/permissions/roles.json
Normal file
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/permissions.schema.json",
|
||||
"schemaVersion": "1.0.0",
|
||||
"package": "github_tools",
|
||||
"description": "GitHub Tools access permissions",
|
||||
"permissions": [
|
||||
{
|
||||
"id": "github.runs.view",
|
||||
"name": "View GitHub Actions Runs",
|
||||
"description": "View GitHub Actions workflow runs",
|
||||
"resource": "github_runs",
|
||||
"action": "read",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "github.runs.analyze",
|
||||
"name": "Analyze GitHub Actions Runs",
|
||||
"description": "Analyze GitHub Actions run statistics",
|
||||
"resource": "github_runs",
|
||||
"action": "analyze",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "github.workflow.trigger",
|
||||
"name": "Trigger Workflow Runs",
|
||||
"description": "Trigger new GitHub Actions workflow runs",
|
||||
"resource": "github_workflow",
|
||||
"action": "execute",
|
||||
"scope": "global",
|
||||
"minLevel": 3
|
||||
},
|
||||
{
|
||||
"id": "github.logs.view",
|
||||
"name": "View Workflow Logs",
|
||||
"description": "View job logs from workflow runs",
|
||||
"resource": "github_logs",
|
||||
"action": "read",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "github.config.manage",
|
||||
"name": "Manage GitHub Configuration",
|
||||
"description": "Configure GitHub repository settings and tokens",
|
||||
"resource": "github_config",
|
||||
"action": "write",
|
||||
"scope": "global",
|
||||
"minLevel": 3
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"id": "github_runs",
|
||||
"name": "GitHub Workflow Runs",
|
||||
"type": "external",
|
||||
"description": "GitHub Actions workflow runs",
|
||||
"actions": ["read", "analyze"]
|
||||
},
|
||||
{
|
||||
"id": "github_workflow",
|
||||
"name": "GitHub Workflows",
|
||||
"type": "external",
|
||||
"description": "GitHub Actions workflow definitions",
|
||||
"actions": ["read", "execute"]
|
||||
},
|
||||
{
|
||||
"id": "github_logs",
|
||||
"name": "GitHub Job Logs",
|
||||
"type": "external",
|
||||
"description": "GitHub Actions job logs",
|
||||
"actions": ["read"]
|
||||
},
|
||||
{
|
||||
"id": "github_config",
|
||||
"name": "GitHub Configuration",
|
||||
"type": "config",
|
||||
"description": "GitHub integration configuration",
|
||||
"actions": ["read", "write"]
|
||||
}
|
||||
]
|
||||
}
|
||||
156
packages/github_tools/scripts/functions.json
Normal file
156
packages/github_tools/scripts/functions.json
Normal file
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script.schema.json",
|
||||
"schemaVersion": "2.2.0",
|
||||
"package": "github_tools",
|
||||
"description": "GitHub Tools functions for fetching runs, analyzing data, and filtering results",
|
||||
"functions": [
|
||||
{
|
||||
"id": "init_initialize",
|
||||
"name": "initialize",
|
||||
"exported": true,
|
||||
"description": "Initialize the GitHub Tools package with configuration",
|
||||
"category": "initialization",
|
||||
"luaScript": "init.lua"
|
||||
},
|
||||
{
|
||||
"id": "fetch_runs_fetchRuns",
|
||||
"name": "fetchRuns",
|
||||
"exported": true,
|
||||
"description": "Fetch workflow runs from GitHub API",
|
||||
"category": "api",
|
||||
"luaScript": "fetch_runs.lua"
|
||||
},
|
||||
{
|
||||
"id": "fetch_runs_fetchJobs",
|
||||
"name": "fetchJobs",
|
||||
"exported": true,
|
||||
"description": "Fetch jobs for a specific workflow run",
|
||||
"category": "api",
|
||||
"luaScript": "fetch_runs.lua"
|
||||
},
|
||||
{
|
||||
"id": "fetch_runs_fetchLogs",
|
||||
"name": "fetchLogs",
|
||||
"exported": true,
|
||||
"description": "Fetch logs for a specific job",
|
||||
"category": "api",
|
||||
"luaScript": "fetch_runs.lua"
|
||||
},
|
||||
{
|
||||
"id": "analyze_calculateStats",
|
||||
"name": "calculateStats",
|
||||
"exported": true,
|
||||
"description": "Calculate statistics from workflow runs",
|
||||
"category": "analytics",
|
||||
"luaScript": "analyze.lua"
|
||||
},
|
||||
{
|
||||
"id": "analyze_getSuccessTrend",
|
||||
"name": "getSuccessTrend",
|
||||
"exported": true,
|
||||
"description": "Get trend data for success rate over time",
|
||||
"category": "analytics",
|
||||
"luaScript": "analyze.lua"
|
||||
},
|
||||
{
|
||||
"id": "analyze_getFailureBreakdown",
|
||||
"name": "getFailureBreakdown",
|
||||
"exported": true,
|
||||
"description": "Get failure breakdown by type",
|
||||
"category": "analytics",
|
||||
"luaScript": "analyze.lua"
|
||||
},
|
||||
{
|
||||
"id": "filter_filterRuns",
|
||||
"name": "filterRuns",
|
||||
"exported": true,
|
||||
"description": "Apply filters to workflow runs",
|
||||
"category": "filtering",
|
||||
"luaScript": "filter.lua"
|
||||
},
|
||||
{
|
||||
"id": "filter_applyFilters",
|
||||
"name": "applyFilters",
|
||||
"exported": true,
|
||||
"description": "Apply filters from form data",
|
||||
"category": "filtering",
|
||||
"luaScript": "filter.lua"
|
||||
},
|
||||
{
|
||||
"id": "filter_sortRuns",
|
||||
"name": "sortRuns",
|
||||
"exported": true,
|
||||
"description": "Sort runs by field",
|
||||
"category": "filtering",
|
||||
"luaScript": "filter.lua"
|
||||
},
|
||||
{
|
||||
"id": "status_getStatusColor",
|
||||
"name": "getStatusColor",
|
||||
"exported": true,
|
||||
"description": "Get color for run status",
|
||||
"category": "display",
|
||||
"luaScript": "status.lua"
|
||||
},
|
||||
{
|
||||
"id": "status_getStatusIcon",
|
||||
"name": "getStatusIcon",
|
||||
"exported": true,
|
||||
"description": "Get icon name for run status",
|
||||
"category": "display",
|
||||
"luaScript": "status.lua"
|
||||
},
|
||||
{
|
||||
"id": "status_getStatusLabel",
|
||||
"name": "getStatusLabel",
|
||||
"exported": true,
|
||||
"description": "Get human-readable status label",
|
||||
"category": "display",
|
||||
"luaScript": "status.lua"
|
||||
},
|
||||
{
|
||||
"id": "status_renderBadge",
|
||||
"name": "renderBadge",
|
||||
"exported": true,
|
||||
"description": "Render status badge component",
|
||||
"category": "display",
|
||||
"luaScript": "status.lua"
|
||||
},
|
||||
{
|
||||
"id": "status_formatDuration",
|
||||
"name": "formatDuration",
|
||||
"exported": true,
|
||||
"description": "Format duration in human-readable form",
|
||||
"category": "display",
|
||||
"luaScript": "status.lua"
|
||||
},
|
||||
{
|
||||
"id": "status_formatRelativeTime",
|
||||
"name": "formatRelativeTime",
|
||||
"exported": true,
|
||||
"description": "Format timestamp as relative time",
|
||||
"category": "display",
|
||||
"luaScript": "status.lua"
|
||||
}
|
||||
],
|
||||
"exports": {
|
||||
"functions": [
|
||||
"initialize",
|
||||
"fetchRuns",
|
||||
"fetchJobs",
|
||||
"fetchLogs",
|
||||
"calculateStats",
|
||||
"getSuccessTrend",
|
||||
"getFailureBreakdown",
|
||||
"filterRuns",
|
||||
"applyFilters",
|
||||
"sortRuns",
|
||||
"getStatusColor",
|
||||
"getStatusIcon",
|
||||
"getStatusLabel",
|
||||
"renderBadge",
|
||||
"formatDuration",
|
||||
"formatRelativeTime"
|
||||
]
|
||||
}
|
||||
}
|
||||
172
packages/github_tools/storybook/config.json
Normal file
172
packages/github_tools/storybook/config.json
Normal file
@@ -0,0 +1,172 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json",
|
||||
"featured": true,
|
||||
"title": "GitHub Tools",
|
||||
"description": "GitHub Actions viewer, run analysis, and workflow management components",
|
||||
"stories": [
|
||||
{
|
||||
"name": "GitHubViewer",
|
||||
"render": "fetch_runs",
|
||||
"description": "Main GitHub Actions viewer with runs list and filters",
|
||||
"args": {
|
||||
"owner": "metabuilder-dev",
|
||||
"repo": "metabuilder",
|
||||
"workflow": "",
|
||||
"token": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "RunListWithData",
|
||||
"render": "fetch_runs",
|
||||
"description": "Run list populated with sample workflow runs",
|
||||
"args": {
|
||||
"runs": [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "CI Pipeline",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"head_branch": "main",
|
||||
"created_at": "2026-01-02T10:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "CI Pipeline",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"head_branch": "feature/new-ui",
|
||||
"created_at": "2026-01-02T09:30:00Z"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Deploy Preview",
|
||||
"status": "in_progress",
|
||||
"conclusion": null,
|
||||
"head_branch": "main",
|
||||
"created_at": "2026-01-02T10:15:00Z"
|
||||
}
|
||||
],
|
||||
"loading": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AnalysisPanel",
|
||||
"render": "analyze",
|
||||
"description": "Statistics and analysis dashboard",
|
||||
"args": {
|
||||
"stats": {
|
||||
"total": 150,
|
||||
"success": 120,
|
||||
"failure": 25,
|
||||
"pending": 5,
|
||||
"success_rate": 80.0,
|
||||
"avg_duration": 245
|
||||
},
|
||||
"timeRange": "7d"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "RunDetails",
|
||||
"render": "status",
|
||||
"description": "Detailed view of a single workflow run",
|
||||
"args": {
|
||||
"run": {
|
||||
"id": 1,
|
||||
"name": "CI Pipeline",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
"head_branch": "main"
|
||||
},
|
||||
"jobs": [
|
||||
{ "id": 1, "name": "Build", "status": "completed", "conclusion": "success" },
|
||||
{ "id": 2, "name": "Test", "status": "completed", "conclusion": "success" },
|
||||
{ "id": 3, "name": "Deploy", "status": "completed", "conclusion": "success" }
|
||||
],
|
||||
"logs": "Running build...\nBuild completed successfully.\nRunning tests...\nAll tests passed."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "StatusBadges",
|
||||
"render": "status",
|
||||
"description": "All status badge variants",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"renders": {
|
||||
"fetch_runs": {
|
||||
"description": "Main viewer with run fetching functionality",
|
||||
"featured": true
|
||||
},
|
||||
"analyze": {
|
||||
"description": "Analysis panel with statistics"
|
||||
},
|
||||
"filter": {
|
||||
"description": "Filter controls for runs"
|
||||
},
|
||||
"status": {
|
||||
"description": "Status badge and formatting utilities"
|
||||
}
|
||||
},
|
||||
"defaultContext": {
|
||||
"user": {
|
||||
"id": "demo-user",
|
||||
"username": "demo_user",
|
||||
"level": 2,
|
||||
"email": "demo@example.com"
|
||||
},
|
||||
"tenant": {
|
||||
"id": "demo-tenant",
|
||||
"name": "Demo Organization"
|
||||
},
|
||||
"config": {
|
||||
"owner": "metabuilder-dev",
|
||||
"repo": "metabuilder"
|
||||
}
|
||||
},
|
||||
"contextVariants": [
|
||||
{
|
||||
"name": "Standard User",
|
||||
"description": "Can view runs and analyze statistics",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "user",
|
||||
"level": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin",
|
||||
"description": "Can view, analyze, and trigger workflows",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "admin",
|
||||
"level": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Read Only",
|
||||
"description": "Public read-only access",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "guest",
|
||||
"level": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"renderFunctions": ["fetch_runs", "analyze", "filter", "status"],
|
||||
"ignoredScripts": ["tests", "init", "types", "db"]
|
||||
},
|
||||
"parameters": {
|
||||
"layout": "padded",
|
||||
"backgrounds": {
|
||||
"default": "light",
|
||||
"values": [
|
||||
{ "name": "light", "value": "#f5f5f5" },
|
||||
{ "name": "dark", "value": "#1a1a1a" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
40
packages/github_tools/styles/tokens.json
Normal file
40
packages/github_tools/styles/tokens.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-styles.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"colors": {
|
||||
"statusSuccess": "#28a745",
|
||||
"statusFailure": "#dc3545",
|
||||
"statusPending": "#ffc107",
|
||||
"statusInProgress": "#17a2b8",
|
||||
"statusCancelled": "#6c757d",
|
||||
"statusSkipped": "#868e96",
|
||||
"logBackground": "#1e1e1e",
|
||||
"logText": "#d4d4d4",
|
||||
"logError": "#f48771",
|
||||
"logWarning": "#cca700",
|
||||
"logInfo": "#3794ff",
|
||||
"cardBorder": "#dee2e6"
|
||||
},
|
||||
"spacing": {
|
||||
"viewerPadding": "16px",
|
||||
"runListGap": "8px",
|
||||
"filterGap": "16px",
|
||||
"analysisGrid": "24px",
|
||||
"logPadding": "12px"
|
||||
},
|
||||
"shadows": {
|
||||
"card": "0 2px 8px rgba(0, 0, 0, 0.1)",
|
||||
"runItem": "0 1px 4px rgba(0, 0, 0, 0.08)",
|
||||
"logViewer": "inset 0 2px 4px rgba(0, 0, 0, 0.2)"
|
||||
},
|
||||
"typography": {
|
||||
"logFont": "JetBrains Mono, Consolas, Monaco, monospace",
|
||||
"logFontSize": "0.875rem",
|
||||
"logLineHeight": "1.5"
|
||||
},
|
||||
"borderRadius": {
|
||||
"card": "8px",
|
||||
"badge": "16px",
|
||||
"logViewer": "4px"
|
||||
}
|
||||
}
|
||||
388
packages/irc_webchat/components/ui.json
Normal file
388
packages/irc_webchat/components/ui.json
Normal file
@@ -0,0 +1,388 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"package": "irc_webchat",
|
||||
"description": "IRC Webchat components for real-time messaging",
|
||||
"components": [
|
||||
{
|
||||
"id": "irc_webchat",
|
||||
"name": "IRCWebchat",
|
||||
"description": "Main IRC webchat container with channels, messages, and users",
|
||||
"props": [
|
||||
{
|
||||
"name": "channelName",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Initial channel to join"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Current user ID"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Current username"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Box",
|
||||
"className": "irc-webchat",
|
||||
"sx": {
|
||||
"display": "flex",
|
||||
"height": "100%",
|
||||
"minHeight": "500px",
|
||||
"border": "1px solid",
|
||||
"borderColor": "divider",
|
||||
"borderRadius": 1
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "ChannelList",
|
||||
"channels": "{{channels}}",
|
||||
"activeChannel": "{{channelName}}",
|
||||
"onChannelSelect": "{{onChannelSelect}}"
|
||||
},
|
||||
{
|
||||
"type": "Box",
|
||||
"sx": {
|
||||
"flex": 1,
|
||||
"display": "flex",
|
||||
"flexDirection": "column"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "Box",
|
||||
"className": "irc-header",
|
||||
"sx": {
|
||||
"p": 2,
|
||||
"borderBottom": "1px solid",
|
||||
"borderColor": "divider",
|
||||
"bgcolor": "background.paper"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h6",
|
||||
"children": "#{{channelName}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "MessageList",
|
||||
"messages": "{{messages}}",
|
||||
"sx": { "flex": 1 }
|
||||
},
|
||||
{
|
||||
"type": "MessageInput",
|
||||
"onSend": "{{onSendMessage}}",
|
||||
"onCommand": "{{onCommand}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "UserList",
|
||||
"users": "{{onlineUsers}}",
|
||||
"channelName": "{{channelName}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "channel_list",
|
||||
"name": "ChannelList",
|
||||
"description": "Sidebar list of available IRC channels",
|
||||
"props": [
|
||||
{
|
||||
"name": "channels",
|
||||
"type": "array",
|
||||
"required": true,
|
||||
"description": "Array of channel objects"
|
||||
},
|
||||
{
|
||||
"name": "activeChannel",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Currently active channel name"
|
||||
},
|
||||
{
|
||||
"name": "onChannelSelect",
|
||||
"type": "function",
|
||||
"required": false,
|
||||
"description": "Callback when channel is selected"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Box",
|
||||
"className": "irc-channel-list",
|
||||
"sx": {
|
||||
"width": 200,
|
||||
"borderRight": "1px solid",
|
||||
"borderColor": "divider",
|
||||
"bgcolor": "background.default"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "Box",
|
||||
"sx": { "p": 2, "borderBottom": "1px solid", "borderColor": "divider" },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "subtitle2",
|
||||
"color": "text.secondary",
|
||||
"children": "CHANNELS"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"dense": true,
|
||||
"children": {
|
||||
"type": "map",
|
||||
"items": "{{channels}}",
|
||||
"template": {
|
||||
"type": "ListItem",
|
||||
"button": true,
|
||||
"selected": "{{item.name === activeChannel}}",
|
||||
"onClick": "{{() => onChannelSelect(item.name)}}",
|
||||
"children": [
|
||||
{
|
||||
"type": "ListItemText",
|
||||
"primary": "#{{item.name}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "message_list",
|
||||
"name": "MessageList",
|
||||
"description": "Scrollable list of chat messages",
|
||||
"props": [
|
||||
{
|
||||
"name": "messages",
|
||||
"type": "array",
|
||||
"required": true,
|
||||
"description": "Array of message objects"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Box",
|
||||
"className": "irc-message-list",
|
||||
"sx": {
|
||||
"flex": 1,
|
||||
"overflow": "auto",
|
||||
"p": 2,
|
||||
"bgcolor": "background.paper"
|
||||
},
|
||||
"children": {
|
||||
"type": "map",
|
||||
"items": "{{messages}}",
|
||||
"template": {
|
||||
"type": "Box",
|
||||
"className": "irc-message irc-message--{{item.type}}",
|
||||
"sx": { "mb": 1 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Flex",
|
||||
"gap": 1,
|
||||
"alignItems": "baseline",
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "text.secondary",
|
||||
"children": "{{formatTime(item.timestamp)}}"
|
||||
},
|
||||
{
|
||||
"type": "conditional",
|
||||
"condition": "{{item.type === 'message'}}",
|
||||
"then": {
|
||||
"type": "Text",
|
||||
"variant": "body2",
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"component": "span",
|
||||
"fontWeight": "bold",
|
||||
"color": "primary.main",
|
||||
"children": "<{{item.username}}> "
|
||||
},
|
||||
"{{item.message}}"
|
||||
]
|
||||
},
|
||||
"else": {
|
||||
"type": "Text",
|
||||
"variant": "body2",
|
||||
"fontStyle": "italic",
|
||||
"color": "text.secondary",
|
||||
"children": "* {{item.message}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "user_list",
|
||||
"name": "UserList",
|
||||
"description": "Sidebar list of online users in channel",
|
||||
"props": [
|
||||
{
|
||||
"name": "users",
|
||||
"type": "array",
|
||||
"required": true,
|
||||
"description": "Array of online user objects"
|
||||
},
|
||||
{
|
||||
"name": "channelName",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Current channel name"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Box",
|
||||
"className": "irc-user-list",
|
||||
"sx": {
|
||||
"width": 160,
|
||||
"borderLeft": "1px solid",
|
||||
"borderColor": "divider",
|
||||
"bgcolor": "background.default"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "Box",
|
||||
"sx": { "p": 2, "borderBottom": "1px solid", "borderColor": "divider" },
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "subtitle2",
|
||||
"color": "text.secondary",
|
||||
"children": "USERS ({{users.length}})"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"dense": true,
|
||||
"children": {
|
||||
"type": "map",
|
||||
"items": "{{users}}",
|
||||
"template": {
|
||||
"type": "ListItem",
|
||||
"children": [
|
||||
{
|
||||
"type": "ListItemIcon",
|
||||
"sx": { "minWidth": 24 },
|
||||
"children": [
|
||||
{
|
||||
"type": "Box",
|
||||
"component": "span",
|
||||
"sx": {
|
||||
"width": 8,
|
||||
"height": 8,
|
||||
"borderRadius": "50%",
|
||||
"bgcolor": "success.main",
|
||||
"display": "inline-block"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ListItemText",
|
||||
"primary": "{{item.username}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "message_input",
|
||||
"name": "MessageInput",
|
||||
"description": "Input field for sending messages and commands",
|
||||
"props": [
|
||||
{
|
||||
"name": "onSend",
|
||||
"type": "function",
|
||||
"required": true,
|
||||
"description": "Callback when message is sent"
|
||||
},
|
||||
{
|
||||
"name": "onCommand",
|
||||
"type": "function",
|
||||
"required": false,
|
||||
"description": "Callback when command is entered"
|
||||
},
|
||||
{
|
||||
"name": "placeholder",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"default": "Type a message or /help for commands..."
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Box",
|
||||
"className": "irc-message-input",
|
||||
"sx": {
|
||||
"p": 2,
|
||||
"borderTop": "1px solid",
|
||||
"borderColor": "divider",
|
||||
"bgcolor": "background.paper"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "Flex",
|
||||
"gap": 1,
|
||||
"children": [
|
||||
{
|
||||
"type": "TextField",
|
||||
"fullWidth": true,
|
||||
"size": "small",
|
||||
"variant": "outlined",
|
||||
"placeholder": "{{placeholder}}",
|
||||
"value": "{{inputValue}}",
|
||||
"onChange": "{{handleInputChange}}",
|
||||
"onKeyPress": "{{handleKeyPress}}"
|
||||
},
|
||||
{
|
||||
"type": "Button",
|
||||
"variant": "contained",
|
||||
"color": "primary",
|
||||
"onClick": "{{handleSend}}",
|
||||
"children": "Send"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
61
packages/irc_webchat/package.json
Normal file
61
packages/irc_webchat/package.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-metadata.schema.json",
|
||||
"packageId": "irc_webchat",
|
||||
"name": "IRC Webchat",
|
||||
"version": "1.0.0",
|
||||
"description": "Classic IRC-style webchat with channels, commands, online users, and real-time messaging. Perfect for community chat rooms.",
|
||||
"author": "MetaBuilder Team",
|
||||
"license": "MIT",
|
||||
"category": "social",
|
||||
"icon": "💬",
|
||||
"minLevel": 2,
|
||||
"primary": true,
|
||||
"tags": [
|
||||
"chat",
|
||||
"irc",
|
||||
"messaging",
|
||||
"realtime"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"lua_test": "*"
|
||||
},
|
||||
"exports": {
|
||||
"components": [
|
||||
"IRCWebchat",
|
||||
"ChannelList",
|
||||
"MessageList",
|
||||
"UserList",
|
||||
"MessageInput"
|
||||
],
|
||||
"scripts": [
|
||||
"send_message",
|
||||
"handle_command",
|
||||
"format_time",
|
||||
"user_join",
|
||||
"user_leave"
|
||||
]
|
||||
},
|
||||
"tests": {
|
||||
"scripts": [
|
||||
"tests/metadata.test.lua",
|
||||
"tests/components.test.lua"
|
||||
],
|
||||
"parameterized": [
|
||||
{
|
||||
"parameters": "tests/metadata.cases.json"
|
||||
},
|
||||
{
|
||||
"parameters": "tests/components.cases.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"schema": {
|
||||
"entities": [
|
||||
"IRCChannel",
|
||||
"IRCMessage",
|
||||
"IRCMembership"
|
||||
],
|
||||
"path": "schema/entities.yaml"
|
||||
}
|
||||
}
|
||||
85
packages/irc_webchat/permissions/roles.json
Normal file
85
packages/irc_webchat/permissions/roles.json
Normal file
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/permissions.schema.json",
|
||||
"schemaVersion": "1.0.0",
|
||||
"package": "irc_webchat",
|
||||
"description": "IRC Webchat access permissions",
|
||||
"permissions": [
|
||||
{
|
||||
"id": "irc.channel.view",
|
||||
"name": "View IRC Channels",
|
||||
"description": "View IRC channels",
|
||||
"resource": "irc_channel",
|
||||
"action": "read",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "irc.channel.join",
|
||||
"name": "Join IRC Channels",
|
||||
"description": "Join IRC channels",
|
||||
"resource": "irc_channel",
|
||||
"action": "join",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "irc.message.send",
|
||||
"name": "Send IRC Messages",
|
||||
"description": "Send IRC messages",
|
||||
"resource": "irc_message",
|
||||
"action": "create",
|
||||
"scope": "channel",
|
||||
"minLevel": 2
|
||||
},
|
||||
{
|
||||
"id": "irc.channel.create",
|
||||
"name": "Create IRC Channels",
|
||||
"description": "Create IRC channels",
|
||||
"resource": "irc_channel",
|
||||
"action": "create",
|
||||
"scope": "global",
|
||||
"minLevel": 3
|
||||
},
|
||||
{
|
||||
"id": "irc.channel.moderate",
|
||||
"name": "Moderate IRC Channels",
|
||||
"description": "Moderate IRC channels (kick, ban, mute users)",
|
||||
"resource": "irc_channel",
|
||||
"action": "moderate",
|
||||
"scope": "channel",
|
||||
"minLevel": 3
|
||||
},
|
||||
{
|
||||
"id": "irc.channel.delete",
|
||||
"name": "Delete IRC Channels",
|
||||
"description": "Delete IRC channels",
|
||||
"resource": "irc_channel",
|
||||
"action": "delete",
|
||||
"scope": "global",
|
||||
"minLevel": 4
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"id": "irc_channel",
|
||||
"name": "IRC Channel",
|
||||
"type": "entity",
|
||||
"description": "IRC chat channel",
|
||||
"actions": ["read", "join", "create", "moderate", "delete"]
|
||||
},
|
||||
{
|
||||
"id": "irc_message",
|
||||
"name": "IRC Message",
|
||||
"type": "entity",
|
||||
"description": "IRC chat message",
|
||||
"actions": ["read", "create", "delete"]
|
||||
},
|
||||
{
|
||||
"id": "irc_membership",
|
||||
"name": "IRC Membership",
|
||||
"type": "entity",
|
||||
"description": "IRC channel membership",
|
||||
"actions": ["read", "create", "delete"]
|
||||
}
|
||||
]
|
||||
}
|
||||
170
packages/irc_webchat/scripts/functions.json
Normal file
170
packages/irc_webchat/scripts/functions.json
Normal file
@@ -0,0 +1,170 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script.schema.json",
|
||||
"schemaVersion": "2.2.0",
|
||||
"package": "irc_webchat",
|
||||
"description": "IRC Webchat message handling and command processing functions",
|
||||
"functions": [
|
||||
{
|
||||
"id": "irc_send_message",
|
||||
"name": "sendMessage",
|
||||
"exported": true,
|
||||
"description": "Send a chat message to a channel",
|
||||
"category": "commands",
|
||||
"luaScript": "send_message.lua",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "channelId",
|
||||
"type": "string",
|
||||
"description": "Channel identifier"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"description": "Username of the sender"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string",
|
||||
"description": "User identifier"
|
||||
},
|
||||
{
|
||||
"name": "message",
|
||||
"type": "string",
|
||||
"description": "Message content to send"
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "ChatMessage",
|
||||
"description": "Chat message object"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "irc_handle_command",
|
||||
"name": "handleCommand",
|
||||
"exported": true,
|
||||
"description": "Process IRC commands like /help, /users, /clear, /me",
|
||||
"category": "commands",
|
||||
"luaScript": "handle_command.lua",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "command",
|
||||
"type": "string",
|
||||
"description": "IRC command string (e.g., /help, /users, /clear, /me <action>)"
|
||||
},
|
||||
{
|
||||
"name": "channelId",
|
||||
"type": "string",
|
||||
"description": "Channel identifier"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"description": "Current username"
|
||||
},
|
||||
{
|
||||
"name": "onlineUsers",
|
||||
"type": "array",
|
||||
"description": "List of online usernames"
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "IRCMessage",
|
||||
"description": "Response message object"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "irc_format_time",
|
||||
"name": "formatTime",
|
||||
"exported": true,
|
||||
"description": "Format timestamps for display in HH:MM AM/PM format",
|
||||
"category": "formatting",
|
||||
"luaScript": "format_time.lua",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "timestamp",
|
||||
"type": "number",
|
||||
"description": "Unix timestamp in milliseconds"
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "string",
|
||||
"description": "Formatted time string in HH:MM AM/PM format"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "irc_user_join",
|
||||
"name": "userJoin",
|
||||
"exported": true,
|
||||
"description": "Handle user joining a channel",
|
||||
"category": "events",
|
||||
"luaScript": "user_join.lua",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "channelId",
|
||||
"type": "string",
|
||||
"description": "Channel identifier"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"description": "Username of the user joining"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string",
|
||||
"description": "User identifier of the user joining"
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "JoinMessage",
|
||||
"description": "Join notification message object"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "irc_user_leave",
|
||||
"name": "userLeave",
|
||||
"exported": true,
|
||||
"description": "Handle user leaving a channel",
|
||||
"category": "events",
|
||||
"luaScript": "user_leave.lua",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "channelId",
|
||||
"type": "string",
|
||||
"description": "Channel identifier"
|
||||
},
|
||||
{
|
||||
"name": "username",
|
||||
"type": "string",
|
||||
"description": "Username of the user leaving"
|
||||
},
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string",
|
||||
"description": "User identifier of the user leaving"
|
||||
}
|
||||
],
|
||||
"returns": {
|
||||
"type": "LeaveMessage",
|
||||
"description": "Leave notification message object"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "irc_init",
|
||||
"name": "init",
|
||||
"exported": false,
|
||||
"description": "Lifecycle hooks for installation and removal",
|
||||
"category": "lifecycle",
|
||||
"luaScript": "init.lua"
|
||||
}
|
||||
],
|
||||
"exports": {
|
||||
"functions": [
|
||||
"sendMessage",
|
||||
"handleCommand",
|
||||
"formatTime",
|
||||
"userJoin",
|
||||
"userLeave"
|
||||
]
|
||||
}
|
||||
}
|
||||
193
packages/irc_webchat/storybook/stories.json
Normal file
193
packages/irc_webchat/storybook/stories.json
Normal file
@@ -0,0 +1,193 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json",
|
||||
"featured": true,
|
||||
"title": "IRC Webchat Components",
|
||||
"description": "Classic IRC-style webchat with channels, commands, and real-time messaging",
|
||||
"stories": [
|
||||
{
|
||||
"name": "IRCWebchat",
|
||||
"render": "webchat",
|
||||
"description": "Complete IRC webchat interface with channels, messages, and users",
|
||||
"args": {
|
||||
"channelName": "general",
|
||||
"channels": [
|
||||
{ "name": "general", "topic": "General discussion" },
|
||||
{ "name": "help", "topic": "Help and support" },
|
||||
{ "name": "random", "topic": "Off-topic chat" }
|
||||
],
|
||||
"messages": [
|
||||
{
|
||||
"id": "msg_1",
|
||||
"username": "System",
|
||||
"userId": "system",
|
||||
"message": "Welcome to #general!",
|
||||
"type": "system",
|
||||
"timestamp": 1735776000000
|
||||
},
|
||||
{
|
||||
"id": "msg_2",
|
||||
"username": "alice",
|
||||
"userId": "user_alice",
|
||||
"message": "Hey everyone!",
|
||||
"type": "message",
|
||||
"timestamp": 1735776060000
|
||||
},
|
||||
{
|
||||
"id": "msg_3",
|
||||
"username": "bob",
|
||||
"userId": "user_bob",
|
||||
"message": "Hi alice, how's it going?",
|
||||
"type": "message",
|
||||
"timestamp": 1735776120000
|
||||
}
|
||||
],
|
||||
"onlineUsers": [
|
||||
{ "username": "alice", "status": "online" },
|
||||
{ "username": "bob", "status": "online" },
|
||||
{ "username": "charlie", "status": "away" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ChannelList",
|
||||
"render": "channel_list",
|
||||
"description": "Sidebar with list of available channels",
|
||||
"args": {
|
||||
"channels": [
|
||||
{ "name": "general", "topic": "General discussion" },
|
||||
{ "name": "dev", "topic": "Development talk" },
|
||||
{ "name": "help", "topic": "Help and support" }
|
||||
],
|
||||
"activeChannel": "general"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MessageList",
|
||||
"render": "message_list",
|
||||
"description": "Scrollable list of chat messages",
|
||||
"args": {
|
||||
"messages": [
|
||||
{
|
||||
"id": "msg_1",
|
||||
"username": "alice",
|
||||
"message": "Hello world!",
|
||||
"type": "message",
|
||||
"timestamp": 1735776000000
|
||||
},
|
||||
{
|
||||
"id": "msg_2",
|
||||
"username": "System",
|
||||
"message": "bob has joined the channel",
|
||||
"type": "join",
|
||||
"timestamp": 1735776060000
|
||||
},
|
||||
{
|
||||
"id": "msg_3",
|
||||
"username": "bob",
|
||||
"message": "waves hello",
|
||||
"type": "system",
|
||||
"timestamp": 1735776120000
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "UserList",
|
||||
"render": "user_list",
|
||||
"description": "Sidebar with online users",
|
||||
"args": {
|
||||
"channelName": "general",
|
||||
"users": [
|
||||
{ "username": "alice", "status": "online" },
|
||||
{ "username": "bob", "status": "online" },
|
||||
{ "username": "charlie", "status": "away" },
|
||||
{ "username": "david", "status": "online" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "MessageInput",
|
||||
"render": "message_input",
|
||||
"description": "Input field for sending messages",
|
||||
"args": {
|
||||
"placeholder": "Type a message or /help for commands..."
|
||||
}
|
||||
}
|
||||
],
|
||||
"renders": {
|
||||
"webchat": {
|
||||
"description": "Complete IRC webchat interface",
|
||||
"featured": true
|
||||
},
|
||||
"channel_list": {
|
||||
"description": "Channel navigation sidebar"
|
||||
},
|
||||
"message_list": {
|
||||
"description": "Chat message display"
|
||||
},
|
||||
"user_list": {
|
||||
"description": "Online users sidebar"
|
||||
},
|
||||
"message_input": {
|
||||
"description": "Message input with command support"
|
||||
}
|
||||
},
|
||||
"defaultContext": {
|
||||
"user": {
|
||||
"id": "demo-user",
|
||||
"username": "demo_user",
|
||||
"level": 2,
|
||||
"email": "demo@example.com"
|
||||
},
|
||||
"tenant": {
|
||||
"id": "demo-tenant",
|
||||
"name": "Demo Organization"
|
||||
}
|
||||
},
|
||||
"contextVariants": [
|
||||
{
|
||||
"name": "Standard User",
|
||||
"description": "Can view channels and send messages",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "user",
|
||||
"level": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Moderator",
|
||||
"description": "Can moderate channels",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "moderator",
|
||||
"level": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin",
|
||||
"description": "Full IRC management access",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "admin",
|
||||
"level": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"renderFunctions": ["webchat", "channel_list", "message_list", "user_list", "message_input"],
|
||||
"ignoredScripts": ["tests", "init"]
|
||||
},
|
||||
"parameters": {
|
||||
"layout": "fullscreen",
|
||||
"backgrounds": {
|
||||
"default": "light",
|
||||
"values": [
|
||||
{ "name": "light", "value": "#ffffff" },
|
||||
{ "name": "dark", "value": "#1a1a1a" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
44
packages/irc_webchat/styles/tokens.json
Normal file
44
packages/irc_webchat/styles/tokens.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-styles.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"colors": {
|
||||
"channelActive": "#1976d2",
|
||||
"channelInactive": "#666666",
|
||||
"userOnline": "#4caf50",
|
||||
"userAway": "#ff9800",
|
||||
"userOffline": "#9e9e9e",
|
||||
"messageSystem": "#757575",
|
||||
"messageJoin": "#4caf50",
|
||||
"messageLeave": "#f44336",
|
||||
"messageAction": "#9c27b0",
|
||||
"messageMention": "#ff5722",
|
||||
"inputBorder": "#dee2e6",
|
||||
"headerBg": "#f5f5f5",
|
||||
"sidebarBg": "#fafafa"
|
||||
},
|
||||
"spacing": {
|
||||
"chatPadding": "16px",
|
||||
"messagePadding": "8px",
|
||||
"channelListWidth": "200px",
|
||||
"userListWidth": "160px",
|
||||
"inputHeight": "48px",
|
||||
"headerHeight": "56px",
|
||||
"messageGap": "4px"
|
||||
},
|
||||
"shadows": {
|
||||
"chatContainer": "0 2px 8px rgba(0, 0, 0, 0.12)",
|
||||
"header": "0 1px 3px rgba(0, 0, 0, 0.08)",
|
||||
"input": "inset 0 1px 2px rgba(0, 0, 0, 0.05)"
|
||||
},
|
||||
"typography": {
|
||||
"messageFont": "IBM Plex Mono, monospace",
|
||||
"timestampSize": "11px",
|
||||
"usernameWeight": "600",
|
||||
"channelNameSize": "14px"
|
||||
},
|
||||
"borders": {
|
||||
"sidebarDivider": "1px solid #e0e0e0",
|
||||
"messageDivider": "1px solid #f0f0f0",
|
||||
"inputBorder": "1px solid #dee2e6"
|
||||
}
|
||||
}
|
||||
424
packages/json_script_example/components/ui.json
Normal file
424
packages/json_script_example/components/ui.json
Normal file
@@ -0,0 +1,424 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"package": "json_script_example",
|
||||
"description": "UI component examples demonstrating JSON script patterns",
|
||||
"components": [
|
||||
{
|
||||
"id": "expression_demo",
|
||||
"name": "ExpressionDemo",
|
||||
"description": "Interactive expression calculator component that renders a form with two number inputs and displays results of all expression operations",
|
||||
"props": [
|
||||
{
|
||||
"name": "initialA",
|
||||
"type": "number",
|
||||
"required": false,
|
||||
"default": 10,
|
||||
"description": "Initial value for first number"
|
||||
},
|
||||
{
|
||||
"name": "initialB",
|
||||
"type": "number",
|
||||
"required": false,
|
||||
"default": 5,
|
||||
"description": "Initial value for second number"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "expression-demo",
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h5",
|
||||
"fontWeight": "bold",
|
||||
"children": "Expression Calculator"
|
||||
},
|
||||
{
|
||||
"type": "Stack",
|
||||
"direction": "row",
|
||||
"gap": 2,
|
||||
"mt": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "TextField",
|
||||
"label": "First Number",
|
||||
"inputType": "number",
|
||||
"value": "{{state.a}}",
|
||||
"onChange": "{{handlers.setA}}"
|
||||
},
|
||||
{
|
||||
"type": "TextField",
|
||||
"label": "Second Number",
|
||||
"inputType": "number",
|
||||
"value": "{{state.b}}",
|
||||
"onChange": "{{handlers.setB}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Box",
|
||||
"mt": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "component",
|
||||
"name": "ResultDisplay",
|
||||
"props": {
|
||||
"result": "{{computed.result}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"a": "{{props.initialA}}",
|
||||
"b": "{{props.initialB}}"
|
||||
},
|
||||
"handlers": {
|
||||
"setA": {
|
||||
"params": ["value"],
|
||||
"body": [
|
||||
{
|
||||
"type": "setState",
|
||||
"updates": {
|
||||
"a": "{{params.value}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"setB": {
|
||||
"params": ["value"],
|
||||
"body": [
|
||||
{
|
||||
"type": "setState",
|
||||
"updates": {
|
||||
"b": "{{params.value}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"computed": {
|
||||
"result": {
|
||||
"body": [
|
||||
{
|
||||
"type": "return",
|
||||
"value": {
|
||||
"type": "call_expression",
|
||||
"callee": "{{imports.script.all_expressions}}",
|
||||
"args": ["{{state.a}}", "{{state.b}}"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "operator_demo",
|
||||
"name": "OperatorDemo",
|
||||
"description": "Interactive operator demonstration component showing all operator results in a categorized table format",
|
||||
"props": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": "number",
|
||||
"required": false,
|
||||
"default": 10,
|
||||
"description": "First operand"
|
||||
},
|
||||
{
|
||||
"name": "y",
|
||||
"type": "number",
|
||||
"required": false,
|
||||
"default": 5,
|
||||
"description": "Second operand"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "operator-demo",
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h5",
|
||||
"fontWeight": "bold",
|
||||
"children": "Operator Demonstration"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body1",
|
||||
"color": "secondary",
|
||||
"mt": 1,
|
||||
"children": "x = {{props.x}}, y = {{props.y}}"
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"container": true,
|
||||
"spacing": 3,
|
||||
"mt": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"md": 6,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h6",
|
||||
"children": "Arithmetic"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"dense": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x + y = {{computed.operators.arithmetic.add}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x - y = {{computed.operators.arithmetic.subtract}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x * y = {{computed.operators.arithmetic.multiply}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x / y = {{computed.operators.arithmetic.divide}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x % y = {{computed.operators.arithmetic.modulo}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"md": 6,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h6",
|
||||
"children": "Comparison"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"dense": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x == y: {{computed.operators.comparison.equal}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x != y: {{computed.operators.comparison.notEqual}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x > y: {{computed.operators.comparison.greaterThan}}"
|
||||
},
|
||||
{
|
||||
"type": "ListItem",
|
||||
"children": "x < y: {{computed.operators.comparison.lessThan}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"computed": {
|
||||
"operators": {
|
||||
"body": [
|
||||
{
|
||||
"type": "return",
|
||||
"value": {
|
||||
"type": "call_expression",
|
||||
"callee": "{{imports.script.all_operators}}",
|
||||
"args": ["{{props.x}}", "{{props.y}}"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "result_display",
|
||||
"name": "ResultDisplay",
|
||||
"description": "Displays expression results in a formatted card layout",
|
||||
"props": [
|
||||
{
|
||||
"name": "result",
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"description": "Result object from all_expressions function"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "result-display",
|
||||
"sx": {
|
||||
"p": 2
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "h6",
|
||||
"fontWeight": "bold",
|
||||
"children": "Results"
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"container": true,
|
||||
"spacing": 2,
|
||||
"mt": 1,
|
||||
"children": [
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "Sum"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body1",
|
||||
"fontWeight": "medium",
|
||||
"children": "{{props.result.sum}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "Difference"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body1",
|
||||
"fontWeight": "medium",
|
||||
"children": "{{props.result.diff}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "Product"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body1",
|
||||
"fontWeight": "medium",
|
||||
"children": "{{props.result.product}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 6,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "Maximum"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body1",
|
||||
"fontWeight": "medium",
|
||||
"children": "{{props.result.max}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "Both Positive?"
|
||||
},
|
||||
{
|
||||
"type": "Chip",
|
||||
"label": "{{props.result.bothPositive ? 'Yes' : 'No'}}",
|
||||
"color": "{{props.result.bothPositive ? 'success' : 'error'}}",
|
||||
"size": "small"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Grid",
|
||||
"item": true,
|
||||
"xs": 12,
|
||||
"children": [
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "caption",
|
||||
"color": "secondary",
|
||||
"children": "Message"
|
||||
},
|
||||
{
|
||||
"type": "Text",
|
||||
"variant": "body2",
|
||||
"sx": {
|
||||
"fontFamily": "monospace"
|
||||
},
|
||||
"children": "{{props.result.message}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"imports": [
|
||||
{
|
||||
"from": "script",
|
||||
"import": ["all_expressions", "all_operators"]
|
||||
}
|
||||
]
|
||||
}
|
||||
50
packages/json_script_example/package.json
Normal file
50
packages/json_script_example/package.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-metadata.schema.json",
|
||||
"packageId": "json_script_example",
|
||||
"name": "JSON Script Example",
|
||||
"version": "1.0.0",
|
||||
"description": "Comprehensive example demonstrating the full JSON script specification",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"category": "examples",
|
||||
"minLevel": 0,
|
||||
"primary": false,
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"lua_test": "*"
|
||||
},
|
||||
"exports": {
|
||||
"components": [
|
||||
"ExpressionDemo",
|
||||
"OperatorDemo",
|
||||
"ResultDisplay"
|
||||
],
|
||||
"scripts": [
|
||||
"all_expressions",
|
||||
"all_statements",
|
||||
"all_operators",
|
||||
"control_flow",
|
||||
"data_structures"
|
||||
],
|
||||
"types": [
|
||||
"ArithmeticResult",
|
||||
"ComparisonResult",
|
||||
"LogicalResult",
|
||||
"OperatorsDemoResult",
|
||||
"ExpressionsDemoResult",
|
||||
"StatementsDemoResult",
|
||||
"DataStructuresResult",
|
||||
"Classification",
|
||||
"TestResult",
|
||||
"ValidationResult"
|
||||
]
|
||||
},
|
||||
"tests": {
|
||||
"parameterized": [
|
||||
{
|
||||
"logic": "tests/math.test.logic.json",
|
||||
"parameters": "tests/math.test.parameters.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
44
packages/json_script_example/permissions/roles.json
Normal file
44
packages/json_script_example/permissions/roles.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/permissions.schema.json",
|
||||
"schemaVersion": "1.0.0",
|
||||
"package": "json_script_example",
|
||||
"description": "Permission definitions for JSON Script Example package",
|
||||
"permissions": [
|
||||
{
|
||||
"id": "example.view",
|
||||
"name": "View Examples",
|
||||
"description": "View JSON script examples and demos",
|
||||
"resource": "json_script_example",
|
||||
"action": "read",
|
||||
"scope": "global",
|
||||
"minLevel": 0
|
||||
},
|
||||
{
|
||||
"id": "example.execute",
|
||||
"name": "Execute Examples",
|
||||
"description": "Execute JSON script example functions",
|
||||
"resource": "json_script_example",
|
||||
"action": "execute",
|
||||
"scope": "global",
|
||||
"minLevel": 1
|
||||
},
|
||||
{
|
||||
"id": "example.modify",
|
||||
"name": "Modify Examples",
|
||||
"description": "Modify and experiment with JSON script examples",
|
||||
"resource": "json_script_example",
|
||||
"action": "write",
|
||||
"scope": "global",
|
||||
"minLevel": 2
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"id": "json_script_example",
|
||||
"name": "JSON Script Example",
|
||||
"type": "package",
|
||||
"description": "JSON script example and demonstration resources",
|
||||
"actions": ["read", "execute", "write"]
|
||||
}
|
||||
]
|
||||
}
|
||||
136
packages/json_script_example/scripts/functions.json
Normal file
136
packages/json_script_example/scripts/functions.json
Normal file
@@ -0,0 +1,136 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script.schema.json",
|
||||
"schemaVersion": "2.2.0",
|
||||
"package": "json_script_example",
|
||||
"description": "Complete demonstration of JSON script specification with expressions, statements, operators, and control flow",
|
||||
"constants": [
|
||||
{
|
||||
"id": "max_value",
|
||||
"name": "MAX_VALUE",
|
||||
"value": 100,
|
||||
"type": "number",
|
||||
"exported": true,
|
||||
"description": "Maximum allowed value for calculations"
|
||||
},
|
||||
{
|
||||
"id": "app_name",
|
||||
"name": "APP_NAME",
|
||||
"value": "JSON Script Demo",
|
||||
"type": "string",
|
||||
"exported": true,
|
||||
"description": "Application display name"
|
||||
},
|
||||
{
|
||||
"id": "config",
|
||||
"name": "DEFAULT_CONFIG",
|
||||
"type": "object",
|
||||
"value": {
|
||||
"debug": true,
|
||||
"timeout": 5000,
|
||||
"maxRetries": 3
|
||||
},
|
||||
"exported": true,
|
||||
"description": "Default application configuration"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"id": "all_expressions_demo",
|
||||
"name": "all_expressions",
|
||||
"exported": true,
|
||||
"description": "Demonstrates all JSON script expression types including binary, logical, unary, conditional, and template literals",
|
||||
"category": "demo",
|
||||
"params": [
|
||||
{
|
||||
"name": "a",
|
||||
"type": "number",
|
||||
"description": "First number for arithmetic and comparison operations"
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"type": "number",
|
||||
"description": "Second number for arithmetic and comparison operations"
|
||||
}
|
||||
],
|
||||
"returnType": "ExpressionsDemoResult",
|
||||
"luaScript": "expressions.lua"
|
||||
},
|
||||
{
|
||||
"id": "all_statements_demo",
|
||||
"name": "all_statements",
|
||||
"exported": true,
|
||||
"description": "Demonstrates all statement types including declarations, loops, conditionals, and error handling",
|
||||
"category": "demo",
|
||||
"params": [
|
||||
{
|
||||
"name": "items",
|
||||
"type": "array",
|
||||
"description": "Array of numbers to process and calculate statistics on"
|
||||
}
|
||||
],
|
||||
"returnType": "StatementsDemoResult",
|
||||
"luaScript": "statements.lua"
|
||||
},
|
||||
{
|
||||
"id": "all_operators_demo",
|
||||
"name": "all_operators",
|
||||
"exported": true,
|
||||
"description": "Demonstrates all supported operators: arithmetic, comparison, logical, and unary",
|
||||
"category": "demo",
|
||||
"params": [
|
||||
{
|
||||
"name": "x",
|
||||
"type": "number",
|
||||
"description": "First operand"
|
||||
},
|
||||
{
|
||||
"name": "y",
|
||||
"type": "number",
|
||||
"description": "Second operand"
|
||||
}
|
||||
],
|
||||
"returnType": "OperatorsDemoResult",
|
||||
"luaScript": "operators.lua"
|
||||
},
|
||||
{
|
||||
"id": "control_flow_demo",
|
||||
"name": "control_flow",
|
||||
"exported": true,
|
||||
"description": "Demonstrates control flow patterns with nested if/else for classification",
|
||||
"category": "demo",
|
||||
"params": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": "number",
|
||||
"description": "Number to classify"
|
||||
}
|
||||
],
|
||||
"returnType": "Classification",
|
||||
"luaScript": "control_flow.lua"
|
||||
},
|
||||
{
|
||||
"id": "data_structures_demo",
|
||||
"name": "data_structures",
|
||||
"exported": true,
|
||||
"description": "Demonstrates working with objects and arrays including nested structures and member access",
|
||||
"category": "demo",
|
||||
"params": [],
|
||||
"returnType": "DataStructuresResult",
|
||||
"luaScript": "data_structures.lua"
|
||||
}
|
||||
],
|
||||
"exports": {
|
||||
"functions": [
|
||||
"all_expressions",
|
||||
"all_statements",
|
||||
"all_operators",
|
||||
"control_flow",
|
||||
"data_structures"
|
||||
],
|
||||
"constants": [
|
||||
"MAX_VALUE",
|
||||
"APP_NAME",
|
||||
"DEFAULT_CONFIG"
|
||||
]
|
||||
}
|
||||
}
|
||||
251
packages/json_script_example/storybook/stories.json
Normal file
251
packages/json_script_example/storybook/stories.json
Normal file
@@ -0,0 +1,251 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json",
|
||||
"featured": false,
|
||||
"title": "JSON Script Examples",
|
||||
"description": "Comprehensive examples demonstrating the full JSON script specification",
|
||||
"stories": [
|
||||
{
|
||||
"name": "All Expressions",
|
||||
"render": "all_expressions",
|
||||
"description": "Demonstrates all expression types: binary, logical, unary, conditional, template literals",
|
||||
"type": "function",
|
||||
"args": {
|
||||
"a": 10,
|
||||
"b": 5
|
||||
},
|
||||
"argControls": {
|
||||
"a": {
|
||||
"type": "number",
|
||||
"default": 10,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "First number"
|
||||
},
|
||||
"b": {
|
||||
"type": "number",
|
||||
"default": 5,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "Second number"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "All Statements",
|
||||
"render": "all_statements",
|
||||
"description": "Demonstrates all statement types: declarations, loops, conditionals, error handling",
|
||||
"type": "function",
|
||||
"args": {
|
||||
"items": [1, 2, 3, 4, 5]
|
||||
},
|
||||
"argControls": {
|
||||
"items": {
|
||||
"type": "json",
|
||||
"default": [1, 2, 3, 4, 5],
|
||||
"description": "Array of numbers to process"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "All Operators",
|
||||
"render": "all_operators",
|
||||
"description": "Demonstrates all operators: arithmetic, comparison, logical, unary",
|
||||
"type": "function",
|
||||
"args": {
|
||||
"x": 10,
|
||||
"y": 5
|
||||
},
|
||||
"argControls": {
|
||||
"x": {
|
||||
"type": "number",
|
||||
"default": 10,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "First operand"
|
||||
},
|
||||
"y": {
|
||||
"type": "number",
|
||||
"default": 5,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "Second operand"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Control Flow",
|
||||
"render": "control_flow",
|
||||
"description": "Demonstrates control flow patterns with nested if/else classification",
|
||||
"type": "function",
|
||||
"args": {
|
||||
"value": 42
|
||||
},
|
||||
"argControls": {
|
||||
"value": {
|
||||
"type": "number",
|
||||
"default": 42,
|
||||
"min": -100,
|
||||
"max": 200,
|
||||
"step": 1,
|
||||
"description": "Number to classify"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Data Structures",
|
||||
"render": "data_structures",
|
||||
"description": "Demonstrates working with objects and arrays",
|
||||
"type": "function",
|
||||
"args": {}
|
||||
},
|
||||
{
|
||||
"name": "Expression Demo Component",
|
||||
"render": "ExpressionDemo",
|
||||
"description": "Interactive expression calculator component",
|
||||
"type": "component",
|
||||
"args": {
|
||||
"initialA": 10,
|
||||
"initialB": 5
|
||||
},
|
||||
"argControls": {
|
||||
"initialA": {
|
||||
"type": "number",
|
||||
"default": 10,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "Initial value for first number"
|
||||
},
|
||||
"initialB": {
|
||||
"type": "number",
|
||||
"default": 5,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "Initial value for second number"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Operator Demo Component",
|
||||
"render": "OperatorDemo",
|
||||
"description": "Interactive operator demonstration showing all operator results",
|
||||
"type": "component",
|
||||
"args": {
|
||||
"x": 10,
|
||||
"y": 5
|
||||
},
|
||||
"argControls": {
|
||||
"x": {
|
||||
"type": "number",
|
||||
"default": 10,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "First operand"
|
||||
},
|
||||
"y": {
|
||||
"type": "number",
|
||||
"default": 5,
|
||||
"min": -100,
|
||||
"max": 100,
|
||||
"step": 1,
|
||||
"description": "Second operand"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"renders": {
|
||||
"all_expressions": {
|
||||
"description": "All expression types demo",
|
||||
"featured": true
|
||||
},
|
||||
"all_statements": {
|
||||
"description": "All statement types demo"
|
||||
},
|
||||
"all_operators": {
|
||||
"description": "All operators demo",
|
||||
"featured": true
|
||||
},
|
||||
"control_flow": {
|
||||
"description": "Control flow patterns demo"
|
||||
},
|
||||
"data_structures": {
|
||||
"description": "Data structures demo"
|
||||
},
|
||||
"ExpressionDemo": {
|
||||
"description": "Interactive expression calculator"
|
||||
},
|
||||
"OperatorDemo": {
|
||||
"description": "Interactive operator demonstration"
|
||||
}
|
||||
},
|
||||
"defaultContext": {
|
||||
"user": {
|
||||
"id": "demo-user",
|
||||
"username": "demo_user",
|
||||
"level": 1,
|
||||
"email": "demo@example.com"
|
||||
},
|
||||
"tenant": {
|
||||
"id": "demo-tenant",
|
||||
"name": "Demo Organization"
|
||||
}
|
||||
},
|
||||
"contextVariants": [
|
||||
{
|
||||
"name": "Public User",
|
||||
"description": "Can view examples",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "public_user",
|
||||
"level": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Standard User",
|
||||
"description": "Can view and execute examples",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "user",
|
||||
"level": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Moderator",
|
||||
"description": "Can modify examples",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "moderator",
|
||||
"level": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"renderFunctions": [
|
||||
"all_expressions",
|
||||
"all_statements",
|
||||
"all_operators",
|
||||
"control_flow",
|
||||
"data_structures"
|
||||
],
|
||||
"ignoredScripts": ["tests"]
|
||||
},
|
||||
"parameters": {
|
||||
"layout": "padded",
|
||||
"backgrounds": {
|
||||
"default": "light",
|
||||
"values": [
|
||||
{ "name": "light", "value": "#fafafa" },
|
||||
{ "name": "dark", "value": "#212121" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
48
packages/json_script_example/styles/tokens.json
Normal file
48
packages/json_script_example/styles/tokens.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-styles.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"colors": {
|
||||
"primary": "#2196F3",
|
||||
"secondary": "#FFC107",
|
||||
"success": "#4CAF50",
|
||||
"error": "#F44336",
|
||||
"warning": "#FF9800",
|
||||
"info": "#00BCD4",
|
||||
"background": "#FAFAFA",
|
||||
"text": "#212121",
|
||||
"expressionHighlight": "#E3F2FD",
|
||||
"operatorHighlight": "#FFF3E0",
|
||||
"resultPositive": "#C8E6C9",
|
||||
"resultNegative": "#FFCDD2"
|
||||
},
|
||||
"spacing": {
|
||||
"xs": "4px",
|
||||
"sm": "8px",
|
||||
"md": "16px",
|
||||
"lg": "24px",
|
||||
"xl": "32px",
|
||||
"demoCard": "20px",
|
||||
"resultGrid": "12px"
|
||||
},
|
||||
"shadows": {
|
||||
"demoCard": "0 2px 8px rgba(33, 150, 243, 0.15)",
|
||||
"resultCard": "0 1px 4px rgba(0, 0, 0, 0.08)",
|
||||
"operatorTable": "0 1px 3px rgba(0, 0, 0, 0.12)"
|
||||
},
|
||||
"typography": {
|
||||
"fontFamily": "Roboto, sans-serif",
|
||||
"fontSize": {
|
||||
"small": "12px",
|
||||
"medium": "14px",
|
||||
"large": "16px",
|
||||
"xlarge": "20px"
|
||||
},
|
||||
"codeFont": "JetBrains Mono, monospace"
|
||||
},
|
||||
"borderRadius": {
|
||||
"small": "2px",
|
||||
"medium": "4px",
|
||||
"large": "8px",
|
||||
"card": "8px"
|
||||
}
|
||||
}
|
||||
223
packages/lua_test/components/ui.json
Normal file
223
packages/lua_test/components/ui.json
Normal file
@@ -0,0 +1,223 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"package": "lua_test",
|
||||
"description": "Lua testing framework UI components for test execution and results display",
|
||||
"components": [
|
||||
{
|
||||
"id": "test_runner",
|
||||
"name": "TestRunner",
|
||||
"description": "Interactive test runner component for executing Lua tests",
|
||||
"props": [
|
||||
{
|
||||
"name": "packageId",
|
||||
"type": "string",
|
||||
"required": true,
|
||||
"description": "Package ID to test"
|
||||
},
|
||||
{
|
||||
"name": "autoRun",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"default": false,
|
||||
"description": "Automatically run tests on mount"
|
||||
},
|
||||
{
|
||||
"name": "filter",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"description": "Filter tests by name pattern"
|
||||
},
|
||||
{
|
||||
"name": "verbose",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"default": true,
|
||||
"description": "Show verbose output"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "test-runner",
|
||||
"children": [
|
||||
{
|
||||
"type": "CardHeader",
|
||||
"title": "Test Runner",
|
||||
"subheader": "Package: {{packageId}}",
|
||||
"action": {
|
||||
"type": "IconButton",
|
||||
"onClick": "{{onRun}}",
|
||||
"children": [
|
||||
{
|
||||
"type": "Icon",
|
||||
"name": "PlayArrow",
|
||||
"color": "primary"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "CardContent",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"spacing": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "TextField",
|
||||
"label": "Filter",
|
||||
"placeholder": "Filter tests by name...",
|
||||
"value": "{{filter}}",
|
||||
"onChange": "{{onFilterChange}}",
|
||||
"size": "small",
|
||||
"fullWidth": true
|
||||
},
|
||||
{
|
||||
"type": "FormControlLabel",
|
||||
"control": {
|
||||
"type": "Switch",
|
||||
"checked": "{{verbose}}",
|
||||
"onChange": "{{onVerboseChange}}"
|
||||
},
|
||||
"label": "Verbose output"
|
||||
},
|
||||
{
|
||||
"type": "conditional",
|
||||
"condition": "{{isRunning}}",
|
||||
"then": {
|
||||
"type": "LinearProgress",
|
||||
"color": "primary"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "test_results",
|
||||
"name": "TestResults",
|
||||
"description": "Displays test results in a formatted view with pass/fail indicators",
|
||||
"props": [
|
||||
{
|
||||
"name": "results",
|
||||
"type": "object",
|
||||
"required": true,
|
||||
"description": "Test results object from runner"
|
||||
},
|
||||
{
|
||||
"name": "showDuration",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"default": true,
|
||||
"description": "Show test duration"
|
||||
},
|
||||
{
|
||||
"name": "expandErrors",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"default": true,
|
||||
"description": "Expand error details by default"
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"type": "element",
|
||||
"template": {
|
||||
"type": "Card",
|
||||
"variant": "outlined",
|
||||
"className": "test-results",
|
||||
"children": [
|
||||
{
|
||||
"type": "CardHeader",
|
||||
"title": "Test Results",
|
||||
"subheader": "{{results.summary}}"
|
||||
},
|
||||
{
|
||||
"type": "CardContent",
|
||||
"children": [
|
||||
{
|
||||
"type": "Stack",
|
||||
"spacing": 1,
|
||||
"children": [
|
||||
{
|
||||
"type": "Box",
|
||||
"className": "results-summary",
|
||||
"children": [
|
||||
{
|
||||
"type": "Flex",
|
||||
"gap": 2,
|
||||
"children": [
|
||||
{
|
||||
"type": "Chip",
|
||||
"label": "{{results.passed}} passed",
|
||||
"color": "success",
|
||||
"size": "small"
|
||||
},
|
||||
{
|
||||
"type": "Chip",
|
||||
"label": "{{results.failed}} failed",
|
||||
"color": "error",
|
||||
"size": "small"
|
||||
},
|
||||
{
|
||||
"type": "conditional",
|
||||
"condition": "{{showDuration}}",
|
||||
"then": {
|
||||
"type": "Chip",
|
||||
"label": "{{results.duration}}ms",
|
||||
"variant": "outlined",
|
||||
"size": "small"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Divider"
|
||||
},
|
||||
{
|
||||
"type": "List",
|
||||
"dense": true,
|
||||
"children": {
|
||||
"type": "for_each",
|
||||
"items": "{{results.tests}}",
|
||||
"as": "test",
|
||||
"render": {
|
||||
"type": "ListItem",
|
||||
"children": [
|
||||
{
|
||||
"type": "ListItemIcon",
|
||||
"children": [
|
||||
{
|
||||
"type": "Icon",
|
||||
"name": "{{test.status === 'passed' ? 'CheckCircle' : 'Cancel'}}",
|
||||
"color": "{{test.status === 'passed' ? 'success' : 'error'}}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ListItemText",
|
||||
"primary": "{{test.name}}",
|
||||
"secondary": "{{test.duration}}ms"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
45
packages/lua_test/package.json
Normal file
45
packages/lua_test/package.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-metadata.schema.json",
|
||||
"packageId": "lua_test",
|
||||
"name": "Lua Test",
|
||||
"version": "1.0.0",
|
||||
"description": "Unit testing framework for Lua scripts in MetaBuilder packages",
|
||||
"author": "MetaBuilder",
|
||||
"license": "MIT",
|
||||
"category": "tools",
|
||||
"minLevel": 3,
|
||||
"primary": false,
|
||||
"icon": "static_content/icon.svg",
|
||||
"keywords": [
|
||||
"testing",
|
||||
"lua",
|
||||
"unit-test",
|
||||
"framework",
|
||||
"assertions",
|
||||
"mocks"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"exports": {
|
||||
"components": [
|
||||
"TestRunner",
|
||||
"TestResults"
|
||||
],
|
||||
"scripts": [
|
||||
"framework",
|
||||
"runner",
|
||||
"assertions",
|
||||
"mocks"
|
||||
]
|
||||
},
|
||||
"tests": {
|
||||
"scripts": [
|
||||
"tests/metadata.test.lua"
|
||||
],
|
||||
"parameterized": [
|
||||
{
|
||||
"parameters": "tests/metadata.cases.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
53
packages/lua_test/permissions/roles.json
Normal file
53
packages/lua_test/permissions/roles.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/permissions.schema.json",
|
||||
"schemaVersion": "1.0.0",
|
||||
"package": "lua_test",
|
||||
"description": "Lua test framework access permissions",
|
||||
"permissions": [
|
||||
{
|
||||
"id": "lua.test.run",
|
||||
"name": "Run Lua Tests",
|
||||
"description": "Execute Lua test suites",
|
||||
"resource": "lua_test",
|
||||
"action": "execute",
|
||||
"scope": "global",
|
||||
"minLevel": 3
|
||||
},
|
||||
{
|
||||
"id": "lua.test.view",
|
||||
"name": "View Test Results",
|
||||
"description": "View test results and reports",
|
||||
"resource": "lua_test",
|
||||
"action": "read",
|
||||
"scope": "global",
|
||||
"minLevel": 3
|
||||
},
|
||||
{
|
||||
"id": "lua.test.configure",
|
||||
"name": "Configure Test Runner",
|
||||
"description": "Configure test runner settings and filters",
|
||||
"resource": "lua_test",
|
||||
"action": "configure",
|
||||
"scope": "global",
|
||||
"minLevel": 4
|
||||
},
|
||||
{
|
||||
"id": "lua.test.debug",
|
||||
"name": "Debug Tests",
|
||||
"description": "Access detailed debug output and error traces",
|
||||
"resource": "lua_test",
|
||||
"action": "debug",
|
||||
"scope": "global",
|
||||
"minLevel": 4
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"id": "lua_test",
|
||||
"name": "Lua Test Framework",
|
||||
"type": "tool",
|
||||
"description": "Lua unit testing framework resources",
|
||||
"actions": ["read", "execute", "configure", "debug"]
|
||||
}
|
||||
]
|
||||
}
|
||||
228
packages/lua_test/scripts/functions.json
Normal file
228
packages/lua_test/scripts/functions.json
Normal file
@@ -0,0 +1,228 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/json-script.schema.json",
|
||||
"schemaVersion": "2.2.0",
|
||||
"package": "lua_test",
|
||||
"description": "Lua unit testing framework functions including assertions, mocks, and test runner",
|
||||
"functions": [
|
||||
{
|
||||
"id": "framework_load_cases",
|
||||
"name": "loadCases",
|
||||
"exported": true,
|
||||
"description": "Load test cases from JSON content",
|
||||
"category": "core",
|
||||
"luaScript": "framework.lua"
|
||||
},
|
||||
{
|
||||
"id": "framework_create_suite",
|
||||
"name": "createSuite",
|
||||
"exported": true,
|
||||
"description": "Create a new test suite",
|
||||
"category": "core",
|
||||
"luaScript": "framework.lua"
|
||||
},
|
||||
{
|
||||
"id": "describe_it",
|
||||
"name": "describe",
|
||||
"exported": true,
|
||||
"description": "BDD-style describe block for grouping tests",
|
||||
"category": "core",
|
||||
"luaScript": "describe.lua"
|
||||
},
|
||||
{
|
||||
"id": "describe_it_case",
|
||||
"name": "it",
|
||||
"exported": true,
|
||||
"description": "BDD-style it block for individual test cases",
|
||||
"category": "core",
|
||||
"luaScript": "describe.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_expect",
|
||||
"name": "expect",
|
||||
"exported": true,
|
||||
"description": "Chainable assertion builder",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_true",
|
||||
"name": "assertTrue",
|
||||
"exported": true,
|
||||
"description": "Assert value is truthy",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_false",
|
||||
"name": "assertFalse",
|
||||
"exported": true,
|
||||
"description": "Assert value is falsy",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_equal",
|
||||
"name": "assertEqual",
|
||||
"exported": true,
|
||||
"description": "Assert two values are equal",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_not_equal",
|
||||
"name": "assertNotEqual",
|
||||
"exported": true,
|
||||
"description": "Assert two values are not equal",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_nil",
|
||||
"name": "assertNil",
|
||||
"exported": true,
|
||||
"description": "Assert value is nil",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "assertions_not_nil",
|
||||
"name": "assertNotNil",
|
||||
"exported": true,
|
||||
"description": "Assert value is not nil",
|
||||
"category": "assertions",
|
||||
"luaScript": "assertions.lua"
|
||||
},
|
||||
{
|
||||
"id": "mocks_fn",
|
||||
"name": "fn",
|
||||
"exported": true,
|
||||
"description": "Create a mock function",
|
||||
"category": "mocks",
|
||||
"luaScript": "mocks.lua"
|
||||
},
|
||||
{
|
||||
"id": "mocks_spy_on",
|
||||
"name": "spyOn",
|
||||
"exported": true,
|
||||
"description": "Spy on an object method",
|
||||
"category": "mocks",
|
||||
"luaScript": "mocks.lua"
|
||||
},
|
||||
{
|
||||
"id": "mocks_mock_object",
|
||||
"name": "mockObject",
|
||||
"exported": true,
|
||||
"description": "Create a mock object",
|
||||
"category": "mocks",
|
||||
"luaScript": "mocks.lua"
|
||||
},
|
||||
{
|
||||
"id": "mocks_fake_timers",
|
||||
"name": "useFakeTimers",
|
||||
"exported": true,
|
||||
"description": "Mock timer functions for testing async code",
|
||||
"category": "mocks",
|
||||
"luaScript": "mocks.lua"
|
||||
},
|
||||
{
|
||||
"id": "runner_run_test",
|
||||
"name": "runTest",
|
||||
"exported": true,
|
||||
"description": "Run a single test",
|
||||
"category": "runner",
|
||||
"luaScript": "runner.lua"
|
||||
},
|
||||
{
|
||||
"id": "runner_run_suite",
|
||||
"name": "runSuite",
|
||||
"exported": true,
|
||||
"description": "Run all tests in a suite",
|
||||
"category": "runner",
|
||||
"luaScript": "runner.lua"
|
||||
},
|
||||
{
|
||||
"id": "runner_run_all",
|
||||
"name": "runAll",
|
||||
"exported": true,
|
||||
"description": "Run all registered test suites",
|
||||
"category": "runner",
|
||||
"luaScript": "runner.lua"
|
||||
},
|
||||
{
|
||||
"id": "runner_format_report",
|
||||
"name": "formatReport",
|
||||
"exported": true,
|
||||
"description": "Format test results as human-readable report",
|
||||
"category": "runner",
|
||||
"luaScript": "runner.lua"
|
||||
},
|
||||
{
|
||||
"id": "runner_format_json",
|
||||
"name": "formatJSON",
|
||||
"exported": true,
|
||||
"description": "Format test results as JSON",
|
||||
"category": "runner",
|
||||
"luaScript": "runner.lua"
|
||||
},
|
||||
{
|
||||
"id": "hooks_before_all",
|
||||
"name": "beforeAll",
|
||||
"exported": true,
|
||||
"description": "Run setup before all tests in suite",
|
||||
"category": "hooks",
|
||||
"luaScript": "hooks.lua"
|
||||
},
|
||||
{
|
||||
"id": "hooks_after_all",
|
||||
"name": "afterAll",
|
||||
"exported": true,
|
||||
"description": "Run teardown after all tests in suite",
|
||||
"category": "hooks",
|
||||
"luaScript": "hooks.lua"
|
||||
},
|
||||
{
|
||||
"id": "hooks_before_each",
|
||||
"name": "beforeEach",
|
||||
"exported": true,
|
||||
"description": "Run setup before each test",
|
||||
"category": "hooks",
|
||||
"luaScript": "hooks.lua"
|
||||
},
|
||||
{
|
||||
"id": "hooks_after_each",
|
||||
"name": "afterEach",
|
||||
"exported": true,
|
||||
"description": "Run teardown after each test",
|
||||
"category": "hooks",
|
||||
"luaScript": "hooks.lua"
|
||||
}
|
||||
],
|
||||
"exports": {
|
||||
"functions": [
|
||||
"loadCases",
|
||||
"createSuite",
|
||||
"describe",
|
||||
"it",
|
||||
"expect",
|
||||
"assertTrue",
|
||||
"assertFalse",
|
||||
"assertEqual",
|
||||
"assertNotEqual",
|
||||
"assertNil",
|
||||
"assertNotNil",
|
||||
"fn",
|
||||
"spyOn",
|
||||
"mockObject",
|
||||
"useFakeTimers",
|
||||
"runTest",
|
||||
"runSuite",
|
||||
"runAll",
|
||||
"formatReport",
|
||||
"formatJSON",
|
||||
"beforeAll",
|
||||
"afterAll",
|
||||
"beforeEach",
|
||||
"afterEach"
|
||||
]
|
||||
}
|
||||
}
|
||||
162
packages/lua_test/storybook/stories.json
Normal file
162
packages/lua_test/storybook/stories.json
Normal file
@@ -0,0 +1,162 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json",
|
||||
"featured": false,
|
||||
"title": "Lua Test Framework",
|
||||
"description": "Unit testing framework components for Lua scripts",
|
||||
"stories": [
|
||||
{
|
||||
"name": "TestRunner",
|
||||
"render": "framework",
|
||||
"description": "Interactive test runner for executing Lua test suites",
|
||||
"args": {
|
||||
"packageId": "dashboard",
|
||||
"autoRun": false,
|
||||
"filter": "",
|
||||
"verbose": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TestRunnerAutoRun",
|
||||
"render": "framework",
|
||||
"description": "Test runner with auto-run enabled",
|
||||
"args": {
|
||||
"packageId": "dashboard",
|
||||
"autoRun": true,
|
||||
"filter": "",
|
||||
"verbose": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TestRunnerFiltered",
|
||||
"render": "framework",
|
||||
"description": "Test runner with name filter applied",
|
||||
"args": {
|
||||
"packageId": "dashboard",
|
||||
"autoRun": false,
|
||||
"filter": "stats",
|
||||
"verbose": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TestResultsPassed",
|
||||
"render": "results",
|
||||
"description": "Test results showing all tests passed",
|
||||
"args": {
|
||||
"results": {
|
||||
"summary": "All tests passed",
|
||||
"passed": 5,
|
||||
"failed": 0,
|
||||
"duration": 42,
|
||||
"tests": [
|
||||
{ "name": "should calculate stats", "status": "passed", "duration": 8 },
|
||||
{ "name": "should format values", "status": "passed", "duration": 5 },
|
||||
{ "name": "should handle empty data", "status": "passed", "duration": 12 },
|
||||
{ "name": "should compute trends", "status": "passed", "duration": 9 },
|
||||
{ "name": "should validate input", "status": "passed", "duration": 8 }
|
||||
]
|
||||
},
|
||||
"showDuration": true,
|
||||
"expandErrors": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TestResultsMixed",
|
||||
"render": "results",
|
||||
"description": "Test results with some failures",
|
||||
"args": {
|
||||
"results": {
|
||||
"summary": "2 of 5 tests failed",
|
||||
"passed": 3,
|
||||
"failed": 2,
|
||||
"duration": 67,
|
||||
"tests": [
|
||||
{ "name": "should calculate stats", "status": "passed", "duration": 8 },
|
||||
{ "name": "should format values", "status": "failed", "duration": 15, "error": "Expected '1,234' but got '1234'" },
|
||||
{ "name": "should handle empty data", "status": "passed", "duration": 12 },
|
||||
{ "name": "should compute trends", "status": "failed", "duration": 22, "error": "Assertion failed: expected up, got down" },
|
||||
{ "name": "should validate input", "status": "passed", "duration": 10 }
|
||||
]
|
||||
},
|
||||
"showDuration": true,
|
||||
"expandErrors": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TestResultsFailed",
|
||||
"render": "results",
|
||||
"description": "Test results showing all tests failed",
|
||||
"args": {
|
||||
"results": {
|
||||
"summary": "All tests failed",
|
||||
"passed": 0,
|
||||
"failed": 3,
|
||||
"duration": 34,
|
||||
"tests": [
|
||||
{ "name": "should initialize framework", "status": "failed", "duration": 12, "error": "Module not found: suite" },
|
||||
{ "name": "should create suite", "status": "failed", "duration": 11, "error": "Dependency error" },
|
||||
{ "name": "should run tests", "status": "failed", "duration": 11, "error": "Framework not initialized" }
|
||||
]
|
||||
},
|
||||
"showDuration": true,
|
||||
"expandErrors": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"renders": {
|
||||
"framework": {
|
||||
"description": "Test runner component",
|
||||
"featured": true
|
||||
},
|
||||
"results": {
|
||||
"description": "Test results display"
|
||||
}
|
||||
},
|
||||
"defaultContext": {
|
||||
"user": {
|
||||
"id": "dev-user",
|
||||
"username": "developer",
|
||||
"level": 3,
|
||||
"email": "dev@example.com"
|
||||
},
|
||||
"tenant": {
|
||||
"id": "demo-tenant",
|
||||
"name": "Development Environment"
|
||||
}
|
||||
},
|
||||
"contextVariants": [
|
||||
{
|
||||
"name": "Developer",
|
||||
"description": "Can run and view tests",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "developer",
|
||||
"level": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Admin",
|
||||
"description": "Can run, view, and configure tests",
|
||||
"context": {
|
||||
"user": {
|
||||
"username": "admin",
|
||||
"level": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"renderFunctions": ["framework", "results"],
|
||||
"ignoredScripts": ["tests", "helpers"]
|
||||
},
|
||||
"parameters": {
|
||||
"layout": "padded",
|
||||
"backgrounds": {
|
||||
"default": "light",
|
||||
"values": [
|
||||
{ "name": "light", "value": "#f5f5f5" },
|
||||
{ "name": "dark", "value": "#1a1a1a" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
56
packages/lua_test/styles/tokens.json
Normal file
56
packages/lua_test/styles/tokens.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"$schema": "https://metabuilder.dev/schemas/package-styles.schema.json",
|
||||
"schemaVersion": "2.0.0",
|
||||
"colors": {
|
||||
"testPassed": "#28a745",
|
||||
"testFailed": "#dc3545",
|
||||
"testSkipped": "#ffc107",
|
||||
"testPending": "#6c757d",
|
||||
"testRunning": "#007bff",
|
||||
"assertionSuccess": "#28a745",
|
||||
"assertionFailure": "#dc3545",
|
||||
"mockHighlight": "#6f42c1",
|
||||
"codeBg": "#f8f9fa",
|
||||
"errorBg": "#fff5f5",
|
||||
"successBg": "#f0fff4"
|
||||
},
|
||||
"spacing": {
|
||||
"testResultPadding": "12px",
|
||||
"testItemGap": "8px",
|
||||
"suiteIndent": "16px",
|
||||
"assertionIndent": "24px",
|
||||
"errorStackPadding": "8px"
|
||||
},
|
||||
"shadows": {
|
||||
"testCard": "0 2px 8px rgba(0, 0, 0, 0.1)",
|
||||
"resultPanel": "0 1px 4px rgba(0, 0, 0, 0.08)",
|
||||
"errorHighlight": "inset 3px 0 0 #dc3545"
|
||||
},
|
||||
"typography": {
|
||||
"testName": {
|
||||
"fontFamily": "IBM Plex Sans",
|
||||
"fontSize": "14px",
|
||||
"fontWeight": 500
|
||||
},
|
||||
"suiteName": {
|
||||
"fontFamily": "Space Grotesk",
|
||||
"fontSize": "16px",
|
||||
"fontWeight": 600
|
||||
},
|
||||
"errorMessage": {
|
||||
"fontFamily": "JetBrains Mono",
|
||||
"fontSize": "12px",
|
||||
"fontWeight": 400
|
||||
},
|
||||
"codeBlock": {
|
||||
"fontFamily": "JetBrains Mono",
|
||||
"fontSize": "13px",
|
||||
"lineHeight": 1.5
|
||||
}
|
||||
},
|
||||
"borders": {
|
||||
"testItem": "1px solid #dee2e6",
|
||||
"suiteHeader": "2px solid #007bff",
|
||||
"errorBlock": "1px solid #dc3545"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user