Compare commits

..

1 Commits

Author SHA1 Message Date
5c2f15ec12 chore: improve package data typings 2025-12-29 23:39:17 +00:00
14036 changed files with 200563 additions and 2012976 deletions

View File

@@ -1,9 +1,43 @@
{
"permissions": {
"allow": [
"Bash(echo No metabuilder images found:*)",
"Bash(docker compose:*)",
"Bash(git pull:*)"
"Bash(git mv:*)",
"Bash(ls:*)",
"Bash(find:*)",
"Bash(npm run test:unit:*)",
"Bash(npm install:*)",
"Bash(xargs:*)",
"Bash(npm run db:generate:*)",
"Bash(npx prisma generate:*)",
"Bash(DATABASE_URL=\"file:./dev.db\" npx prisma generate:*)",
"Bash(git rm:*)",
"Bash(git log:*)",
"Bash(cat:*)",
"Bash(xargs git rm:*)",
"Bash(bun add:*)",
"Bash(bun install:*)",
"Bash(test -f:*)",
"Bash(bun run typecheck:*)",
"Bash(bun run test:unit:*)",
"Bash(echo:*)",
"Bash(npx prisma validate:*)",
"Bash(npm run typecheck:*)",
"Bash(npm run lint)",
"Bash(npm audit:*)",
"Bash(bun run lint)",
"Bash(git checkout:*)",
"Bash(bun audit:*)",
"Bash(git restore:*)",
"Bash(bunx playwright:*)",
"Bash(timeout 30 bun run build:*)",
"Bash(bun run lint:fix:*)",
"Bash(bun run format:*)",
"Bash(while read file)",
"Bash(do eslint:*)",
"Bash(done)",
"Bash(eslint:*)",
"Bash(bunx eslint:*)",
"Bash(bun test:*)"
]
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,46 +0,0 @@
---
sourceLocationPrefix: /Users/rmac/Documents/metabuilder
baselineLinesOfCode: 300769
unicodeNewlines: true
columnKind: utf16
primaryLanguage: javascript
inProgress:
primaryLanguage: javascript
installedExtractors:
go:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/go
python:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/python
rust:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/rust
java:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/java
html:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/html
xml:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/xml
properties:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/properties
cpp:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/cpp
swift:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/swift
csv:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/csv
actions:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/actions
yaml:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/yaml
csharp:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/csharp
javascript:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/javascript
ruby:
- /opt/homebrew/Caskroom/codeql/2.23.9/codeql/ruby
creationMetadata:
sha: 110d37c3bce07cb068c510bbed2c42d1ccba1b42
cliVersion: 2.23.9
creationTime: 2026-02-01T20:15:08.121510Z
finalised: false
overlayBaseDatabase: false
overlayDatabase: false

View File

@@ -1 +0,0 @@
{"timestamp":"2026-02-01T20:15:07.994462Z","source":{"id":"cli/platform","name":"Platform"},"markdownMessage":"On the Mac OS X (aarch64; 26.2) platform.","visibility":{"cliSummaryTable":false,"statusPage":false,"telemetry":true},"attributes":{"arch":"aarch64","version":"26.2","name":"Mac OS X"}}

View File

@@ -1 +0,0 @@
{"timestamp":"2026-02-01T20:15:08.117178Z","source":{"id":"cli/sip-enablement","name":"macOS SIP enablement status"},"severity":"note","visibility":{"cliSummaryTable":false,"statusPage":false,"telemetry":true},"attributes":{"isEnabled":true}}

View File

@@ -1,132 +0,0 @@
# Dependencies (installed fresh via npm ci in multi-stage builds)
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Build output (built fresh inside Docker)
**/.next
**/out
**/storybook-static
**/dist
# Testing
coverage
.nyc_output
*.test.ts
*.test.tsx
*.spec.ts
*.spec.tsx
__tests__
__mocks__
.vitest
# Misc
.DS_Store
*.pem
# Local env files
.env
.env*.local
.env.development
.env.test
.env.production
# Vercel
.vercel
# TypeScript build info
*.tsbuildinfo
next-env.d.ts
# IDE
.vscode
.idea
*.swp
*.swo
*~
# Git
.git
.gitignore
.gitattributes
# Documentation
docs
README*
CHANGELOG*
LICENSE
# CI/CD
.github
.gitlab-ci.yml
azure-pipelines.yml
# Docker (Dockerfiles are referenced by path, not COPYed)
docker-compose*
.dockerignore
# Development config
.editorconfig
.prettierrc*
.eslintrc*
.eslintignore
# E2E / test infrastructure
e2e
playwright-report
test-results
# Temporary files
tmp
temp
.tmp
.cache
# Large directories not needed by Node.js Docker builds
gameengine
dbal
services
old
txt
deployment
prisma
mojo
spec
scripts
.claude
dist
# Allow specific dbal paths through for app builds
!dbal/shared/ui
!dbal/shared/api/schema/entities
!dbal/shared/seeds/database
# Allow conanfiles through for base image builds (negation overrides above exclusions)
!dbal/production/build-config/conanfile.py
!gameengine/conanfile.py
!services/media_daemon/build-config/conanfile.txt
!frontends/qt6/conanfile.txt
!frontends/cli/conanfile.txt
# Allow requirements.txt for base-pip-deps image
!dbal/production/tests/integration/requirements.txt
!services/email_service/requirements.txt
!services/smtprelay/requirements.txt
# Allow deployment config files for baked-in Docker images
!deployment/portal
!deployment/config/nginx/production.conf
!deployment/config/prometheus/prometheus.yml
!deployment/config/prometheus/alerts.yml
!deployment/config/grafana/provisioning
!deployment/config/loki/loki-config.yml
!deployment/config/promtail/promtail-config.yml
!deployment/config/alertmanager/alertmanager.yml
# Allow DBAL templates for dbal-init volume seeder
!dbal/templates/sql
# Allow media daemon config for nginx-stream image
!services/media_daemon/config/nginx-stream.conf

32
.gitattributes vendored
View File

@@ -1,32 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Shell scripts should always use LF
*.sh text eol=lf
# Windows batch files should use CRLF
*.bat text eol=crlf
*.cmd text eol=crlf
# JSON, JavaScript, TypeScript should use LF
*.json text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.jsx text eol=lf
*.tsx text eol=lf
# Markdown and documentation should use LF
*.md text eol=lf
*.txt text eol=lf
# Binary files
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
*.woff binary
*.woff2 binary
*.ttf binary
*.otf binary

View File

@@ -1,91 +0,0 @@
name: 'Setup npm with local registry'
description: 'Starts Verdaccio, publishes patched packages, then runs npm install'
inputs:
node-version:
description: 'Node.js version'
required: false
default: '20'
runs:
using: composite
steps:
- name: Setup Node
uses: actions/setup-node@v5
with:
node-version: ${{ inputs.node-version }}
- name: Start Verdaccio and publish patched packages
shell: bash
run: |
# Install and start Verdaccio (lightweight npm registry, ~2s startup)
npm install -g verdaccio@6 --silent
mkdir -p /tmp/verdaccio-storage
cat > /tmp/verdaccio.yaml << 'VERDACCIO_EOF'
storage: /tmp/verdaccio-storage
uplinks:
npmjs:
url: https://registry.npmjs.org/
timeout: 60s
max_fails: 3
packages:
'@esbuild-kit/*':
access: $all
publish: $all
proxy: npmjs
'**':
access: $all
publish: $all
proxy: npmjs
server:
keepAliveTimeout: 60
log:
type: stdout
format: pretty
level: warn
listen: 0.0.0.0:4873
VERDACCIO_EOF
verdaccio --config /tmp/verdaccio.yaml &
VERDACCIO_PID=$!
echo "Verdaccio PID: $VERDACCIO_PID"
# Wait for Verdaccio to be ready (usually <3s)
timeout 30 bash -c 'until curl -sf http://localhost:4873/-/ping >/dev/null 2>&1; do sleep 1; done'
echo "Verdaccio ready"
# Create a CI user on Verdaccio and get an auth token
RESPONSE=$(curl -s -XPUT http://localhost:4873/-/user/org.couchdb.user:ci \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"ci","password":"ci","email":"ci@localhost","type":"user"}')
TOKEN=$(echo "$RESPONSE" | python3 -c "import json,sys; print(json.load(sys.stdin).get('token',''))" 2>/dev/null)
if [ -z "$TOKEN" ]; then
echo "Warning: could not get Verdaccio token, publish may fail"
else
npm set //localhost:4873/:_authToken="$TOKEN"
echo "Verdaccio auth configured"
fi
# Publish all patched tarballs
PATCHES_DIR="deployment/npm-patches"
for tarball in "$PATCHES_DIR"/*.tgz; do
[ -f "$tarball" ] || continue
echo "Publishing $tarball..."
npm publish "$tarball" \
--registry http://localhost:4873 \
--tag patched \
2>&1 | grep -v "^npm notice" || true
done
echo "Patched packages published to Verdaccio"
- name: Install npm dependencies
shell: bash
run: |
# Retry npm install up to 3 times for transient network failures
for attempt in 1 2 3; do
npm install && break
echo "npm install attempt $attempt failed, retrying in 15s..."
sleep 15
done

View File

@@ -1,42 +0,0 @@
name: "MetaBuilder CodeQL Config"
# CodeQL configuration for semantic code search across 2-3M LOC codebase
# Purpose: Enable pattern search, caller analysis, data flow queries for story planning
# NOT for security gates - that's handled by gated-pipeline.yml
# Paths to analyze (focus on source, exclude generated)
paths:
- frontends
- codegen
- workflowui
- packages
- fakemui/react
- workflow/plugins
- dbal
- services
- hooks
- redux
# Paths to ignore (generated, vendor, tests, archives)
paths-ignore:
- '**/node_modules/**'
- '**/.next/**'
- '**/dist/**'
- '**/build/**'
- '**/__pycache__/**'
- '**/test-results/**'
- '**/playwright-report/**'
- '**/coverage/**'
- 'old/**'
- 'txt/**'
- 'spec/**'
- '**/*.test.ts'
- '**/*.test.tsx'
- '**/*.spec.ts'
- '**/*.spec.tsx'
- '**/e2e/**'
# Query suites - security-and-quality provides comprehensive code analysis
# This enables rich semantic queries for code search, not just security scanning
queries:
- uses: security-and-quality

View File

@@ -2,13 +2,12 @@
## Architecture Overview
MetaBuilder is a **data-driven, multi-tenant platform** with 95% functionality in JSON, not TypeScript. The system combines:
MetaBuilder is a **data-driven, multi-tenant platform** with 95% functionality in JSON/Lua, not TypeScript. The system combines:
- **6-Level Permission System**: Public → User → Moderator → Admin → God → Supergod access hierarchies
- **5-Level Permission System**: Public → User → Admin → God → Supergod access hierarchies
- **DBAL (Database Abstraction Layer)**: TypeScript SDK + C++ daemon, language-agnostic via YAML contracts
- **Declarative Components**: Render complex UIs from JSON configuration using `RenderComponent`
- **Package System**: Self-contained modules in `/packages/{name}/seed/` with metadata, components, scripts
- **Multi-Source Package Repos**: Support for local and remote package registries via `PackageSourceManager`
- **Multi-Tenancy**: All data queries filter by `tenantId`; each tenant has isolated configurations
## 0-kickstart Operating Rules
@@ -30,7 +29,7 @@ Follow `.github/prompts/0-kickstart.md` as the current workflow source of truth.
### 1. API-First DBAL Development
When adding features to DBAL:
1. **Define in YAML first**: `api/schema/entities/*.yaml` and `api/schema/operations/*.yaml`
2. **Generate types**: Run type generation scripts (creates TS and C++ types)
2. **Generate types**: `python tools/codegen/gen_types.py` (creates TS and C++ types)
3. **Implement adapters**: TypeScript (`ts/src/adapters/`) for speed, C++ (`cpp/src/adapters/`) for security
4. **Add conformance tests**: `common/contracts/*_tests.yaml` (runs on both implementations to guarantee parity)
5. Never add fields/operations directly in code without updating YAML source of truth
@@ -57,31 +56,15 @@ Each package auto-loads on init:
```
packages/{name}/
├── seed/
│ ├── metadata.json # Package info, exports, dependencies, minLevel
│ ├── metadata.json # Package info, exports, dependencies
│ ├── components.json # Component definitions
│ ├── scripts/ # JSON scripts organized by function
│ ├── scripts/ # Lua scripts organized by function
│ └── index.ts # Exports packageSeed object
├── src/ # Optional React components
└── static_content/ # Assets (images, etc.)
```
Loaded by `initializePackageSystem()``buildPackageRegistry()``exportAllPackagesForSeed()`
### 3a. Multi-Source Package Repositories
Packages can come from multiple sources:
```typescript
import { createPackageSourceManager, LocalPackageSource, RemotePackageSource } from '@/lib/packages/package-glue'
const manager = createPackageSourceManager({
enableRemote: true,
remoteUrl: 'https://registry.metabuilder.dev/api/v1',
conflictResolution: 'priority' // or 'latest-version', 'local-first', 'remote-first'
})
const packages = await manager.fetchMergedIndex()
const pkg = await manager.loadPackage('dashboard')
```
See: `docs/packages/package-sources.md`, `package-glue/sources/`
### 4. Database Helpers Pattern
Always use `Database` class methods, never raw Prisma:
```typescript
@@ -94,8 +77,16 @@ const users = await prisma.user.findMany()
```
See: `src/lib/database.ts` (1200+ LOC utility wrapper)
### 5. Script Execution
Scripts are defined in JSON format and executed in a controlled environment with limited access to system resources.
### 5. Lua Sandbox Execution
Lua scripts run in isolated sandbox without access to `os`, `io`, `require`:
```typescript
// Sandbox context provided in script
function validateEmail(email)
-- No file I/O, no system access, no external requires
return string.match(email, "^[^@]+@[^@]+$") ~= nil
end
```
Always test scripts with `DeclarativeComponentRenderer.executeLuaScript()`
## Code Conventions
@@ -166,7 +157,7 @@ Material-UI with SASS; theme in `src/theme/mui-theme.ts` with light/dark mode su
1. Define database schema changes first (Prisma)
2. Add seed data to `src/seed-data/` or package `/seed/`
3. Use generic renderers (`RenderComponent`) not hardcoded JSX
4. Add JSON scripts in package `/seed/scripts/` as needed
4. Add Lua scripts in `src/lib/lua-snippets.ts` or package `/seed/scripts/`
5. Keep one lambda per file and split as needed
6. Add parameterized tests in `.test.ts` files with matching names
@@ -207,13 +198,14 @@ If fixing a DBAL bug:
2. Reproduce in TypeScript implementation first (faster feedback loop)
3. Apply fix to both TS and C++ adapters
4. Add/update conformance test in `common/contracts/`
5. Verify both implementations pass conformance tests
5. Verify both implementations pass test: `python tools/conformance/run_all.py`
## Common Mistakes
**Hardcoding values in TSX** → Move to database or YAML config
**Forgetting tenantId filter** → Breaks multi-tenancy
**Adding fields without Prisma generate** → Type errors in DB helper
**Plain JS loops over Fengari tables** → Use Lua, not TS, for Lua data
**Multiple lambdas per file** → Split into single-lambda files and wrap with a class only when needed
**New function without test**`npm run test:check-functions` will fail
**Missing TODO for unfinished behavior** → Leave a TODO comment where functionality is pending
@@ -232,7 +224,7 @@ If fixing a DBAL bug:
1. Is this hardcoded value better in database?
2. Could a generic component render this instead of custom TSX?
3. Does this query filter by tenantId?
4. Could JSON configuration handle this without code changes?
4. Could Lua handle this without code changes?
5. Is this one lambda per file (and test file name matches)?
6. Does this function have a parameterized test?
7. Is this DBAL change reflected in YAML schema first?

View File

@@ -9,4 +9,3 @@ updates:
directory: "/"
schedule:
interval: "weekly"

View File

@@ -1 +0,0 @@
Find stuff that the nextjs frontend does and the package systen doesnt, then make/edit packages. Usually user facing stuff. Also all the packages might want SVG icons.

571
.github/workflows/README.md vendored Normal file
View File

@@ -0,0 +1,571 @@
# GitHub Workflows Documentation
This directory contains automated workflows for CI/CD, code quality, and comprehensive AI-assisted development throughout the entire SDLC.
## 🚦 Enterprise Gated Tree Workflow
MetaBuilder uses an **Enterprise Gated Tree Workflow** that ensures all code changes pass through multiple validation gates before being merged and deployed.
**📖 Complete Guide:** [Enterprise Gated Workflow Documentation](../../docs/ENTERPRISE_GATED_WORKFLOW.md)
### Quick Overview
All PRs must pass through 5 sequential gates:
1. **Gate 1: Code Quality** - Prisma, TypeScript, Lint, Security
2. **Gate 2: Testing** - Unit, E2E, DBAL Daemon tests
3. **Gate 3: Build & Package** - Application build, quality metrics
4. **Gate 4: Review & Approval** - Human code review (1 approval required)
5. **Gate 5: Deployment** - Staging (auto) → Production (manual approval)
**Key Benefits:**
- ✅ Sequential gates prevent wasted resources
- ✅ Automatic merge after approval
- ✅ Manual approval required for production
- ✅ Clear visibility of gate status on PRs
- ✅ Audit trail for all deployments
### Legacy Workflow Cleanup
**Deprecated and Removed (Dec 2025):**
-`ci/ci.yml` - Replaced by `gated-ci.yml` (100% redundant)
-`quality/deployment.yml` - Replaced by `gated-deployment.yml` (100% redundant)
**Modified:**
-`development.yml` - Refactored to remove redundant quality checks, kept unique Copilot features
See [Legacy Pipeline Cruft Report](../../docs/LEGACY_PIPELINE_CRUFT_REPORT.md) for analysis.
## 🤖 GitHub Copilot Integration
All workflows are designed to work seamlessly with **GitHub Copilot** to assist throughout the Software Development Lifecycle:
- **Planning Phase**: Architecture review, PRD alignment, implementation guidance
- **Development Phase**: Continuous quality feedback, code suggestions, refactoring opportunities
- **Testing Phase**: Automated code review, security checks, quality validation
- **Deployment Phase**: Pre-deployment validation, health checks, monitoring
- **Maintenance Phase**: Issue triage, automated fixes, dependency management
**📖 Copilot Instructions:** [.github/copilot-instructions.md](../copilot-instructions.md)
## Workflows Overview
### 🚦 Enterprise Gated Workflows (New)
#### Issue and PR Triage (`triage.yml`) 🆕
**Triggered on:** Issues (opened/edited/reopened) and Pull Requests (opened/reopened/synchronize/edited)
**Purpose:** Quickly categorize inbound work so reviewers know what to look at first.
- Auto-applies labels for type (bug/enhancement/docs/security/testing/performance) and area (frontend/backend/database/workflows/documentation)
- Sets a default priority and highlights beginner-friendly issues
- Flags missing information (repro steps, expected/actual results, versions) with a checklist comment
- For PRs, labels areas touched, estimates risk based on change size and critical paths, and prompts for test plans/screenshots/linked issues
- Mentions **@copilot** to sanity-check the triage with GitHub-native AI (no external Codex webhooks)
This workflow runs alongside the existing PR management jobs to keep triage lightweight while preserving the richer checks in the gated pipelines.
#### 1. Enterprise Gated CI/CD Pipeline (`gated-ci.yml`)
**Triggered on:** Push to main/master/develop branches, Pull requests
**Structure:**
- **Gate 1:** Code Quality (Prisma, TypeScript, Lint, Security)
- **Gate 2:** Testing (Unit, E2E, DBAL Daemon)
- **Gate 3:** Build & Package (Build, Quality Metrics)
- **Gate 4:** Review & Approval (Human review required)
**Features:**
- Sequential gate execution for efficiency
- Clear gate status reporting on PRs
- Automatic progression through gates
- Summary report with all gate results
**Best for:** Small to medium teams, straightforward workflows
#### 1a. Enterprise Gated CI/CD Pipeline - Atomic (`gated-ci-atomic.yml`) 🆕
**Triggered on:** Push to main/master/develop branches, Pull requests
**Structure:**
- **Gate 1:** Code Quality - 7 atomic steps
- 1.1 Prisma Validation
- 1.2 TypeScript Check (+ strict mode analysis)
- 1.3 ESLint (+ any-type detection + ts-ignore detection)
- 1.4 Security Scan (+ dependency audit)
- 1.5 File Size Check
- 1.6 Code Complexity Analysis
- 1.7 Stub Implementation Detection
- **Gate 2:** Testing - 3 atomic steps
- 2.1 Unit Tests (+ coverage analysis)
- 2.2 E2E Tests
- 2.3 DBAL Daemon Tests
- **Gate 3:** Build & Package - 2 atomic steps
- 3.1 Application Build (+ bundle analysis)
- 3.2 Quality Metrics
- **Gate 4:** Review & Approval (Human review required)
**Features:**
- **Atomic validation steps** for superior visualization
- Each tool from `/tools` runs as separate job
- **Gate artifacts** persisted between steps (30-day retention)
- Granular failure detection
- Parallel execution within gates
- Complete audit trail with JSON artifacts
- Individual step timing and status
**Best for:** Large teams, enterprise compliance, audit requirements
**Documentation:** See [Atomic Gated Workflow Architecture](../../docs/ATOMIC_GATED_WORKFLOW.md)
#### 2. Enterprise Gated Deployment (`gated-deployment.yml`)
**Triggered on:** Push to main/master, Releases, Manual workflow dispatch
**Environments:**
- **Staging:** Automatic deployment after merge to main
- **Production:** Manual approval required
**Features:**
- Pre-deployment validation (schema, security, size)
- Breaking change detection and warnings
- Environment-specific deployment paths
- Post-deployment health checks
- Automatic deployment tracking issues
- Rollback preparation and procedures
**Gate 5:** Deployment gate ensures only reviewed code reaches production
### 🔄 Legacy Workflows (Still Active)
#### 3. CI/CD Workflow (`ci/ci.yml`) - ❌ REMOVED
**Status:** Deprecated and removed (Dec 2025)
**Reason:** 100% functionality superseded by `gated-ci.yml`
**Jobs:** ~~Prisma Check, Lint, Build, E2E Tests, Quality Check~~
**Replacement:** Use `gated-ci.yml` for all CI/CD operations
**Triggered on:** Push to main/master/develop branches, Pull requests
**Jobs:**
- **Prisma Check**: Validates database schema and generates Prisma client
- **Lint**: Runs ESLint to check code quality
- **Build**: Builds the application and uploads artifacts
- **E2E Tests**: Runs Playwright end-to-end tests
- **Quality Check**: Checks for console.log statements and TODO comments
### 4. Automated Code Review (`code-review.yml`)
**Triggered on:** Pull request opened, synchronized, or reopened
**Features:**
- Analyzes code changes for security issues (eval, innerHTML, XSS risks)
- Checks for code quality issues (console.log, debugger, any types)
- Provides suggestions for improvements
- **Auto-approves PRs** if no blocking issues are found
- Adds appropriate labels (needs-changes, ready-for-review, has-warnings)
**Review Criteria:**
- ✅ Security vulnerabilities
- ✅ Code quality issues
- ✅ Type safety
- ✅ React best practices
- ✅ File size warnings
### 5. Auto Merge (`auto-merge.yml`) - Updated for Gated Workflow
**Triggered on:** PR approval, CI workflow completion
**Features:**
- Automatically merges PRs when:
- PR is approved by reviewers
- All gates pass (supports both gated and legacy CI checks)
- No merge conflicts
- PR is not in draft
- **Automatically deletes the branch** after successful merge
- Uses squash merge strategy
- Posts comments about merge status
- **Updated:** Now supports Enterprise Gated CI/CD Pipeline checks
### 6. Issue Triage (`issue-triage.yml`)
**Triggered on:** New issues opened, issues labeled
**Features:**
- Automatically categorizes and labels issues:
- Type: bug, enhancement, documentation, testing, security, performance
- Priority: high, medium, low
- AI-fixable flag for automated fixes
- Posts welcome message with issue summary
- Suggests automated fix attempts for simple issues
- Can create fix branches automatically with `create-pr` label
### 7. PR Management (`pr-management.yml`)
**Triggered on:** PR opened, synchronized, labeled
**Features:**
- Auto-labels PRs based on changed files:
- workflows, tests, documentation, ui, styling, configuration, dependencies
- Size labels (small/medium/large)
- Type labels from PR title (bug, enhancement, refactor, etc.)
- Validates PR descriptions
- Links related issues automatically
- Posts comments on related issues
### 8. Merge Conflict Check (`merge-conflict-check.yml`)
**Triggered on:** PR opened/synchronized, push to main/master
**Features:**
- Detects merge conflicts
- Posts comment mentioning @copilot to resolve
- Adds/removes `merge-conflict` label
- Fails CI if conflicts exist
### 9. Planning & Design (`planning.yml`) 🆕
**Triggered on:** Issues opened or labeled with enhancement/feature-request
**Features:**
- **Architecture Review**: Analyzes feature requests against architectural principles
- **PRD Alignment Check**: Ensures new features align with project mission
- **Implementation Suggestions**: Provides step-by-step implementation guidance
- Validates declarative-first approach
- Checks multi-tenant and permission considerations
- Creates design checklists for feature implementation
- **@copilot integration** for architecture guidance
**SDLC Phase:** Planning & Design
### 10. Development Assistance (`development.yml`) 🆕 - Refactored
**Triggered on:** Pull request updates, @copilot mentions
**Features:**
- **Architectural Compliance Feedback**: Monitors declarative ratio and component sizes
- **@copilot Interaction Handler**: Responds to @copilot mentions with context-aware guidance
- **Refactoring Suggestions**: Identifies opportunities for improvement
- Provides architectural reminders and best practices
**Note:** Refactored to remove redundant quality checks (lint/build now in gated-ci.yml)
**SDLC Phase:** Development
### 11. Deployment & Monitoring (`deployment.yml`) - ❌ REMOVED
**Status:** Deprecated and removed (Dec 2025)
**Reason:** 100% functionality superseded by `gated-deployment.yml` with improvements
**Jobs:** ~~Pre-Deployment Validation, Deployment Summary, Post-Deployment Health Checks~~
**Replacement:** Use `gated-deployment.yml` for all deployment operations
### 12. Code Size Limits (`size-limits.yml`)
**Triggered on:** Pull requests, pushes to main (when source files change)
**Features:**
- Enforces file size limits and posts PR comments on violations
- Uploads a size report artifact
- Monitors `frontends/nextjs/src/**` and runs `scripts/enforce-size-limits.ts` from `frontends/nextjs`
## SDLC Coverage
### 🎯 Complete Lifecycle Support
```
┌─────────────┐
│ Planning │ ← planning.yml (Architecture Review, PRD Check)
└──────┬──────┘
┌─────────────┐
│ Development │ ← development.yml (Quality Feedback, Refactoring)
└──────┬──────┘
┌─────────────┐
│ Testing │ ← ci.yml, code-review.yml (Lint, Build, E2E)
└──────┬──────┘
┌─────────────┐
│ Integration │ ← pr-management.yml, auto-merge.yml
└──────┬──────┘
┌─────────────┐
│ Deployment │ ← deployment.yml (Validation, Health Checks)
└──────┬──────┘
┌─────────────┐
│ Maintenance │ ← issue-triage.yml, dependabot.yml
└─────────────┘
```
## Labels Used
### Automated Labels
- `bug` - Bug fixes
- `enhancement` - New features
- `feature-request` - Proposed new features
- `ready-to-implement` - Features ready for development
- `documentation` - Documentation changes
- `tests` - Test-related changes
- `security` - Security issues
- `performance` - Performance improvements
- `needs-changes` - PR requires changes
- `ready-for-review` - PR is ready for review
- `has-warnings` - PR has warnings to address
- `large-pr` - PR with many changes
- `size: small/medium/large` - PR size indicators
- `ai-fixable` - Issues that can be auto-fixed
- `good first issue` - Good for newcomers
- `priority: high/medium/low` - Issue priority
- `merge-conflict` - PR has merge conflicts
- `auto-fix` - Request automated fix
- `create-pr` - Create fix PR for issue
- `deployment` - Deployment tracking
- `monitoring` - Monitoring and observability
- `dependencies` - Dependency updates
- `refactor` - Code refactoring
- `chore` - Maintenance tasks
- `workflows` - Workflow changes
- `ui` - UI/UX changes
- `styling` - CSS/Tailwind changes
- `configuration` - Config file changes
## Configuration
### ESLint
The project uses ESLint with TypeScript support and React-specific rules:
- File: `eslint.config.js`
- Strict type checking (warnings for gradual adoption)
- React hooks validation
- Code quality rules
### Playwright E2E Tests
- Configuration: `playwright.config.ts`
- Tests directory: `e2e/`
- Runs on Chromium browser
- Tests include:
- Login functionality
- Navigation
- CRUD operations
- Form interactions
## Usage
### Working with GitHub Copilot
**In Issues:**
```markdown
@copilot implement this issue
@copilot review the architecture
@copilot suggest testing strategy
@copilot help with this
```
**In Pull Requests:**
- Automated feedback on every push
- Continuous quality metrics
- Refactoring suggestions
- Architectural compliance checks
**In Your IDE:**
- Reference `.github/copilot-instructions.md` for context
- Use docs/getting-started/PRD.md for feature context
- Follow existing patterns in `/packages/`
- Ask Copilot about architectural decisions
### Testing Workflows Locally with Act
Before pushing to GitHub, test workflows locally using [act](https://github.com/nektos/act):
```bash
# Quick diagnostics (no act required)
./scripts/diagnose-workflows.sh
# Interactive workflow testing
./scripts/test-workflows.sh
# Or use act directly
act -l # List all workflows
act push # Run CI pipeline
act -j lint # Test linting job
act -j build # Test build job
```
**📖 See [ACT_TESTING.md](../../docs/ACT_TESTING.md) for comprehensive act testing guide**
### Running Locally
```bash
# Run linter
bun run lint
# Fix linting issues automatically
bun run lint:fix
# Run e2e tests
bun run test:e2e
# Run e2e tests with UI
bun run test:e2e:ui
# Run e2e tests in headed mode
bun run test:e2e:headed
# Build the project
bun run build
```
### Triggering Workflows
**Planning Phase:**
1. Create issue with `enhancement` or `feature-request` label
2. Automated architecture review and PRD alignment check
3. Add `ready-to-implement` label for implementation guidance
4. Follow suggested step-by-step plan
**Development Phase:**
1. Create feature branch: `git checkout -b feature/issue-X`
2. Push changes - triggers continuous quality feedback
3. Get real-time metrics on declarative ratio, component sizes
4. Mention `@copilot` in commits/PRs for specific help
5. Review refactoring suggestions
**Testing & Review Phase:**
1. Open PR - automatically reviewed, labeled, and validated
2. Address any architectural compliance issues
3. Get approval + pass tests
4. Automatically merged and branch deleted
**Deployment Phase:**
1. Merge to main - triggers pre-deployment validation
2. Create release - generates deployment notes and tracking issue
3. Post-deployment health checks run automatically
4. Monitor deployment tracking issue for 48 hours
**Maintenance Phase:**
1. Security audits run on every deployment
2. Dependabot creates automated dependency PRs
3. Issue triage handles new bug reports
4. @copilot assists with fixes and improvements
### For Issues:
1. Create an issue - automatically triaged and labeled
2. Add `enhancement` label - triggers architecture review
3. Add `ready-to-implement` label - get implementation guidance
4. Add `auto-fix` label to request automated fix
5. Add `create-pr` label to create a fix branch
6. Mention `@copilot` for specific assistance
**For PRs:**
1. Open a PR - automatically reviewed, labeled, and validated
2. Push changes - triggers CI/CD pipeline and quality feedback
3. Get approval + pass tests - automatically merged and branch deleted
4. Receive continuous refactoring suggestions
### Working with AI Assistance
**In Issues & PRs:**
- Mention `@copilot implement this` - Get implementation guidance
- Mention `@copilot review` - Request code review
- Mention `@copilot architecture` - Get architectural guidance
- Mention `@copilot test` - Get testing help
- Mention `@copilot fix this issue` - Request automated fix
**In Your IDE:**
- Use GitHub Copilot extension with context from `.github/copilot-instructions.md`
- Reference docs/getting-started/PRD.md when prompting for features
- Follow patterns from existing packages
- Ask about architectural decisions before implementing
**Automated Copilot Features:**
- Architecture review on feature requests
- Continuous quality feedback during development
- Refactoring opportunity detection
- PRD alignment checking
- Implementation step-by-step guidance
## Best Practices
### For Development
1. **Follow declarative-first principles** - Prefer JSON + Lua over TypeScript
2. **Keep components under 150 LOC** - Break large files into smaller ones
3. **Use generic renderers** - Avoid hardcoded component TSX files
4. **Store config in database** - Use Prisma, not hardcoded values
5. **Organize as packages** - Self-contained features with seed data
### For Pull Requests
### For Pull Requests
1. **Write descriptive PR titles** - Used for automatic labeling
2. **Link issues in PR descriptions** - Enables automatic issue closing
3. **Keep PRs focused and small** - Easier to review and merge
4. **Address all review comments** - Even warnings should be considered
5. **Test locally before pushing** - Run lint and tests
6. **Don't commit console.log statements** - Will be flagged in review
7. **Remove debugger statements** - Treated as blocking issues
8. **Review refactoring suggestions** - Continuous improvement opportunities
### For Issues
1. **Use clear, descriptive titles** - Helps with automatic categorization
2. **Provide context** - Link to docs/getting-started/PRD.md sections, mention permission levels
3. **Consider architecture** - Is this declarative? Package-worthy? Multi-tenant?
4. **Use labels appropriately** - Triggers relevant workflow automation
5. **Engage with @copilot** - Get AI assistance throughout implementation
## Troubleshooting
### Running Act to Find Workflow Issues
Use act to test workflows locally and identify issues before pushing:
```bash
# Run full diagnostics
./scripts/diagnose-workflows.sh
# Test specific failing job
act -j <job-name> -v
# Test entire CI pipeline
./scripts/test-workflows.sh
```
**📖 Complete guide:** [ACT_TESTING.md](../../docs/ACT_TESTING.md)
### PR Not Auto-Merging
- Check that all CI checks passed
- Verify PR has approval
- Ensure no merge conflicts
- Confirm PR is not in draft mode
### Tests Failing
- Run tests locally: `bun run test:e2e`
- Check test report artifacts in GitHub Actions
- Ensure dev server starts correctly
- Test with act: `act -j test-e2e`
### Linting Errors
- Run `bun run lint:fix` to auto-fix
- Review errors: `bun run lint`
- Check `eslint.config.js` for rule configuration
- Test with act: `act -j lint`
### Build Failures
- Test locally: `bun run build`
- Check for TypeScript errors
- Verify all dependencies are installed
- Test with act: `act -j build`
### Prisma Issues
- Ensure schema exists: `prisma/schema.prisma`
- Generate client: `bunx prisma generate`
- Run migrations: `bunx prisma migrate dev`
- Test with act: `act -j prisma-check`
## Contributing
When adding new workflows:
1. Document the workflow in this README
2. Add appropriate error handling
3. Test the workflow on a test branch
4. Ensure proper permissions are set
5. Add labels if needed (they'll be created automatically)
## Security
Workflows use `GITHUB_TOKEN` with minimal required permissions:
- `contents: read/write` - For reading code and merging PRs
- `pull-requests: write` - For commenting and managing PRs
- `issues: write` - For managing issues
- `checks: read` - For reading CI status
No secrets are required for basic functionality.

57
.github/workflows/ci/cli.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: CLI Build
on:
push:
branches: [ main, develop ]
paths:
- 'frontends/cli/**'
- '.github/workflows/ci/cli.yml'
pull_request:
branches: [ main, develop ]
paths:
- 'frontends/cli/**'
- '.github/workflows/ci/cli.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
build:
name: Build MetaBuilder CLI
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build python3-pip libssl-dev
- name: Install Conan
run: |
python3 -m pip install --upgrade pip
python3 -m pip install conan
- name: Detect Conan profile
run: conan profile detect --force
- name: Install Conan dependencies
run: |
mkdir -p frontends/cli/build
conan install frontends/cli \
--output-folder frontends/cli/build \
--build missing
- name: Configure CLI with CMake
run: |
cmake -S frontends/cli -B frontends/cli/build -G Ninja \
-DCMAKE_TOOLCHAIN_FILE=frontends/cli/build/conan_toolchain.cmake
- name: Build CLI executable
run: cmake --build frontends/cli/build
- name: Run help command to verify binary
run: frontends/cli/build/bin/metabuilder-cli --help

308
.github/workflows/ci/cpp-build.yml vendored Normal file
View File

@@ -0,0 +1,308 @@
name: C++ Build & Test
on:
push:
branches: [ main, develop ]
paths:
- 'dbal/production/**'
- 'dbal/shared/tools/cpp-build-assistant.cjs'
- '.github/workflows/cpp-build.yml'
pull_request:
branches: [ main, develop ]
paths:
- 'dbal/production/**'
- 'dbal/shared/tools/cpp-build-assistant.cjs'
- '.github/workflows/cpp-build.yml'
workflow_dispatch:
permissions:
contents: read
jobs:
check-implementation:
name: Check C++ Implementation Status
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
has_sources: ${{ steps.check.outputs.has_sources }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check if C++ sources exist
id: check
run: |
if [ -d "dbal/production/src" ] && [ "$(find dbal/production/src -name '*.cpp' | wc -l)" -gt 0 ]; then
echo "has_sources=true" >> $GITHUB_OUTPUT
echo "✓ C++ source files found"
else
echo "has_sources=false" >> $GITHUB_OUTPUT
echo "⚠ C++ implementation not yet available - skipping build"
fi
build-linux:
name: Build on Linux
runs-on: ubuntu-latest
needs: check-implementation
if: needs.check-implementation.outputs.has_sources == 'true'
strategy:
matrix:
build_type: [Release, Debug]
compiler:
- { cc: gcc, cxx: g++ }
- { cc: clang, cxx: clang++ }
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build ${{ matrix.compiler.cxx }}
pip install conan
- name: Setup Conan profile
run: conan profile detect --force
- name: Check C++ dependencies
run: bun run cpp:check
- name: Initialize Conanfile
run: bun run cpp:init
- name: Install Conan dependencies
env:
CMAKE_BUILD_TYPE: ${{ matrix.build_type }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
run: bun run cpp:install
- name: Configure CMake
env:
CMAKE_BUILD_TYPE: ${{ matrix.build_type }}
CC: ${{ matrix.compiler.cc }}
CXX: ${{ matrix.compiler.cxx }}
run: |
if [ "${{ matrix.build_type }}" = "Debug" ]; then
bun run cpp:build -- configure --debug
else
bun run cpp:configure
fi
- name: Build C++ project
env:
CMAKE_BUILD_TYPE: ${{ matrix.build_type }}
run: bun run cpp:build
- name: Run C++ tests
run: bun run cpp:test
- name: Upload build artifacts
if: matrix.build_type == 'Release' && matrix.compiler.cxx == 'g++'
uses: actions/upload-artifact@v4
with:
name: dbal-daemon-linux
path: |
dbal/production/build/dbal_daemon
dbal/production/build/*.so
retention-days: 7
build-macos:
name: Build on macOS
runs-on: macos-latest
needs: check-implementation
if: needs.check-implementation.outputs.has_sources == 'true'
strategy:
matrix:
build_type: [Release, Debug]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install system dependencies
run: |
brew install cmake ninja conan
- name: Setup Conan profile
run: conan profile detect --force
- name: Check C++ dependencies
run: bun run cpp:check
- name: Full C++ build
env:
CMAKE_BUILD_TYPE: ${{ matrix.build_type }}
run: |
if [ "${{ matrix.build_type }}" = "Debug" ]; then
node dbal/shared/tools/cpp-build-assistant.cjs full --debug
else
bun run cpp:full
fi
- name: Run C++ tests
run: bun run cpp:test
- name: Upload build artifacts
if: matrix.build_type == 'Release'
uses: actions/upload-artifact@v4
with:
name: dbal-daemon-macos
path: |
dbal/production/build/dbal_daemon
dbal/production/build/*.dylib
retention-days: 7
build-windows:
name: Build on Windows
runs-on: windows-latest
needs: check-implementation
if: needs.check-implementation.outputs.has_sources == 'true'
strategy:
matrix:
build_type: [Release, Debug]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install system dependencies
run: |
choco install cmake ninja -y
pip install conan
- name: Setup Conan profile
run: conan profile detect --force
- name: Check C++ dependencies
run: bun run cpp:check
- name: Full C++ build
env:
CMAKE_BUILD_TYPE: ${{ matrix.build_type }}
shell: bash
run: |
if [ "${{ matrix.build_type }}" = "Debug" ]; then
node dbal/shared/tools/cpp-build-assistant.cjs full --debug
else
bun run cpp:full
fi
- name: Run C++ tests
run: bun run cpp:test
- name: Upload build artifacts
if: matrix.build_type == 'Release'
uses: actions/upload-artifact@v4
with:
name: dbal-daemon-windows
path: |
dbal/production/build/dbal_daemon.exe
dbal/production/build/*.dll
retention-days: 7
code-quality:
name: C++ Code Quality
runs-on: ubuntu-latest
needs: check-implementation
if: needs.check-implementation.outputs.has_sources == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build cppcheck clang-format
pip install conan
- name: Setup Conan
run: conan profile detect --force
- name: Configure project
run: bun run cpp:full
- name: Run cppcheck
run: |
cppcheck --enable=all --inconclusive --error-exitcode=1 \
--suppress=missingIncludeSystem \
-I dbal/production/include \
dbal/production/src/
continue-on-error: true
- name: Check formatting
run: |
find dbal/production/src dbal/production/include -name '*.cpp' -o -name '*.hpp' | \
xargs clang-format --dry-run --Werror
continue-on-error: true
integration:
name: Integration Test
runs-on: ubuntu-latest
needs: [check-implementation, build-linux]
if: needs.check-implementation.outputs.has_sources == 'true'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Download Linux build
uses: actions/download-artifact@v4
with:
name: dbal-daemon-linux
path: dbal/production/build/
- name: Make daemon executable
run: chmod +x dbal/production/build/dbal_daemon
- name: Run integration tests
run: |
# Start C++ daemon
./dbal/production/build/dbal_daemon &
DAEMON_PID=$!
sleep 2
# Run TypeScript integration tests
bun run test:unit
# Cleanup
kill $DAEMON_PID
continue-on-error: true

199
.github/workflows/ci/detect-stubs.yml vendored Normal file
View File

@@ -0,0 +1,199 @@
name: Stub Implementation Detection
on:
pull_request:
branches: [ main, master, develop ]
types: [opened, synchronize, reopened]
push:
branches: [ main, master, develop ]
workflow_dispatch:
schedule:
- cron: '0 0 * * 1' # Weekly on Monday
permissions:
contents: read
pull-requests: write
checks: write
jobs:
detect-stubs:
name: Detect Stub Implementations
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
# Pattern-based stub detection
- name: Detect stub patterns
id: detect-patterns
run: bunx tsx ../../tools/detect-stub-implementations.ts > stub-patterns.json
continue-on-error: true
# Implementation completeness analysis
- name: Analyze implementation completeness
id: analyze-completeness
run: bunx tsx ../../tools/analyze-implementation-completeness.ts > implementation-analysis.json
continue-on-error: true
# Generate detailed report
- name: Generate stub report
id: generate-report
run: bunx tsx ../../tools/generate-stub-report.ts > stub-report.md
continue-on-error: true
# Check for unimplemented TODOs in changed files (PR only)
- name: Check changed files for stubs
if: github.event_name == 'pull_request'
id: check-changed
run: |
git diff origin/${{ github.base_ref }}...HEAD -- 'src/**/*.{ts,tsx}' | \
grep -E '^\+.*(TODO|FIXME|not implemented|stub|placeholder|mock)' | \
tee changed-stubs.txt || true
STUB_COUNT=$(wc -l < changed-stubs.txt)
echo "stub_count=$STUB_COUNT" >> $GITHUB_OUTPUT
continue-on-error: true
# Post PR comment with findings
- name: Post stub detection comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let comment = '## 🔍 Stub Implementation Detection Report\n\n';
try {
const patternData = JSON.parse(fs.readFileSync('stub-patterns.json', 'utf8'));
const completenessData = JSON.parse(fs.readFileSync('implementation-analysis.json', 'utf8'));
// Summary table
comment += '### Summary\n\n';
comment += `**Pattern-Based Stubs**: ${patternData.totalStubsFound}\n`;
comment += `**Low Completeness Items**: ${completenessData.bySeverity.high + completenessData.bySeverity.medium}\n`;
comment += `**Average Completeness**: ${completenessData.averageCompleteness}%\n\n`;
// Severity breakdown
if (patternData.totalStubsFound > 0) {
comment += '### Severity Breakdown (Patterns)\n\n';
comment += `| Severity | Count |\n`;
comment += `|----------|-------|\n`;
comment += `| 🔴 Critical | ${patternData.bySeverity.high} |\n`;
comment += `| 🟠 Medium | ${patternData.bySeverity.medium} |\n`;
comment += `| 🟡 Low | ${patternData.bySeverity.low} |\n\n`;
}
// Type breakdown
if (Object.values(patternData.byType).some(v => v > 0)) {
comment += '### Issue Types\n\n';
for (const [type, count] of Object.entries(patternData.byType)) {
if (count > 0) {
comment += `- **${type}**: ${count}\n`;
}
}
comment += '\n';
}
// Critical issues
if (patternData.criticalIssues && patternData.criticalIssues.length > 0) {
comment += '### 🔴 Critical Issues Found\n\n';
comment += '<details><summary>Click to expand</summary>\n\n';
comment += `| File | Line | Function | Type |\n`;
comment += `|------|------|----------|------|\n`;
patternData.criticalIssues.slice(0, 10).forEach(issue => {
comment += `| ${issue.file} | ${issue.line} | \`${issue.function}\` | ${issue.type} |\n`;
});
comment += '\n</details>\n\n';
}
// Recommendations
comment += '### 📋 Recommendations\n\n';
comment += '- [ ] Review all critical stubs before merging\n';
comment += '- [ ] Replace TODO comments with GitHub issues\n';
comment += '- [ ] Implement placeholder functions before production\n';
comment += '- [ ] Run `bun run test:check-functions` to ensure coverage\n';
comment += '- [ ] Use type system to force implementation (avoid `any` types)\n\n';
// Artifacts info
comment += '### 📁 Detailed Reports\n\n';
comment += 'Full analysis available in artifacts:\n';
comment += '- `stub-patterns.json` - Pattern-based detection results\n';
comment += '- `implementation-analysis.json` - Completeness scoring\n';
comment += '- `stub-report.md` - Detailed markdown report\n';
} catch (e) {
comment += '⚠️ Could not generate detailed report. Check logs for errors.\n';
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
# Upload detailed reports
- name: Upload stub detection reports
uses: actions/upload-artifact@v4
if: always()
with:
name: stub-detection-reports
path: |
stub-patterns.json
implementation-analysis.json
stub-report.md
changed-stubs.txt
retention-days: 30
# Create check run with summary
- name: Create check run
uses: actions/github-script@v7
if: always()
with:
script: |
const fs = require('fs');
let summary = '';
try {
const data = JSON.parse(fs.readFileSync('stub-patterns.json', 'utf8'));
summary = `Found ${data.totalStubsFound} stub implementations (${data.bySeverity.high} high severity)`;
} catch (e) {
summary = 'Stub detection completed. See artifacts for details.';
}
github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'Stub Implementation Detection',
head_sha: context.sha,
status: 'completed',
conclusion: 'neutral',
summary: summary
});

View File

@@ -1,169 +0,0 @@
name: DBAL Tests
on:
push:
paths:
- 'dbal/**'
- '.github/workflows/dbal-tests.yml'
pull_request:
paths:
- 'dbal/**'
jobs:
# ── Unit + security tests (no DB, no containers) ────────────────────────────
unit-tests:
name: Unit & Security Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install system deps
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential cmake ninja-build python3-pip \
libpq-dev libmysqlclient-dev
- name: Install Conan
run: pip3 install conan
- name: Detect Conan profile
run: conan profile detect --force
- name: Cache Conan packages
uses: actions/cache@v6
with:
path: ~/.conan2/p
key: conan-unit-${{ hashFiles('dbal/production/build-config/conanfile.tests.py') }}
restore-keys: conan-unit-
- name: Install C++ test dependencies
working-directory: dbal/production
run: |
mkdir -p _build && cd _build
conan install ../build-config/conanfile.tests.py \
--output-folder=. \
--build=missing \
-s build_type=Release \
-s compiler.cppstd=20
- name: Configure CMake
working-directory: dbal/production/_build
run: |
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=./build/Release/generators/conan_toolchain.cmake \
-DBUILD_DAEMON=OFF \
-DBUILD_TESTING=ON \
-G Ninja
- name: Build
working-directory: dbal/production/_build
run: cmake --build . --target dbal_unit_tests --parallel
- name: Test
working-directory: dbal/production/_build
run: ctest -R dbal_unit_tests --output-on-failure
- name: Upload results
uses: actions/upload-artifact@v6
if: always()
with:
name: unit-test-results
path: dbal/production/_build/test_results.xml
# ── Integration tests — containers managed by testcontainers-sidecar ────────
# Docker is available by default on ubuntu-latest (no services: block needed).
# testcontainers-go (via the sidecar) starts postgres/mysql containers itself,
# and Ryuk cleans them up after the test binary exits.
integration-tests:
name: Integration Tests (SQLite + PostgreSQL + MySQL via testcontainers)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Go (for testcontainers-sidecar)
uses: actions/setup-go@v5
with:
go-version: '1.21'
- name: Install system deps
run: |
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends \
build-essential cmake ninja-build python3-pip \
libpq-dev libmysqlclient-dev
- name: Install Conan
run: pip3 install conan
- name: Detect Conan profile
run: conan profile detect --force
- name: Configure Nexus as primary Conan remote
run: |
conan remote add nexus "${{ secrets.NEXUS_URL }}" --force
conan remote login nexus "${{ secrets.NEXUS_USER }}" \
--password "${{ secrets.NEXUS_PASS }}"
# Nexus first (has testcontainers-sidecar), Conan Center as fallback
conan remote update nexus --index 0
# If NEXUS_URL secret is not set, fall back to building sidecar from source
continue-on-error: true
- name: Build testcontainers-sidecar from source (fallback if no Nexus)
if: env.NEXUS_URL == ''
env:
NEXUS_URL: ${{ secrets.NEXUS_URL }}
TESTCONTAINERS_SIDECAR_SRC: ${{ github.workspace }}/dbal/testcontainers-sidecar
run: |
# Build and register in the local Conan cache so conan install succeeds below.
TESTCONTAINERS_SIDECAR_SRC="$TESTCONTAINERS_SIDECAR_SRC" \
conan create dbal/production/build-config/conan-recipes/testcontainers-sidecar \
-s build_type=Release -s compiler.cppstd=20
- name: Cache Conan packages
uses: actions/cache@v6
with:
path: ~/.conan2/p
key: conan-integration-${{ hashFiles('dbal/production/build-config/conanfile.tests.py') }}
restore-keys: conan-integration-
- name: Install C++ test dependencies (with sidecar from Nexus)
working-directory: dbal/production
run: |
mkdir -p _build && cd _build
conan install ../build-config/conanfile.tests.py \
--output-folder=. \
--build=missing \
-s build_type=Release \
-s compiler.cppstd=20
continue-on-error: true
- name: Configure CMake
working-directory: dbal/production/_build
run: |
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=./build/Release/generators/conan_toolchain.cmake \
-DBUILD_DAEMON=OFF \
-DBUILD_INTEGRATION_TESTS=ON \
-G Ninja
- name: Build
working-directory: dbal/production/_build
run: cmake --build . --target dbal_integration_tests --parallel
- name: Run integration tests
working-directory: dbal/production/_build
# Docker socket is available by default on ubuntu-latest.
# testcontainers-go will start postgres and mysql containers automatically.
run: ctest -R dbal_integration_tests --output-on-failure -V
- name: Upload results
uses: actions/upload-artifact@v6
if: always()
with:
name: integration-test-results
path: dbal/production/_build/integration_results.xml

360
.github/workflows/development.yml vendored Normal file
View File

@@ -0,0 +1,360 @@
name: Development Assistance
on:
pull_request:
types: [opened, synchronize, ready_for_review]
issue_comment:
types: [created]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
code-quality-feedback:
name: Continuous Quality Feedback
runs-on: ubuntu-latest
if: |
github.event_name == 'pull_request' && !github.event.pull_request.draft
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Analyze code metrics (no redundant checks)
id: quality
run: |
# Note: Lint/build/tests are handled by gated-ci.yml
# This job only collects metrics for architectural feedback
# Count TypeScript files and their sizes
TOTAL_TS_FILES=$(find src -name "*.ts" -o -name "*.tsx" 2>/dev/null | wc -l)
LARGE_FILES=$(find src -name "*.ts" -o -name "*.tsx" -exec wc -l {} \; 2>/dev/null | awk '$1 > 150 {print $2}' | wc -l)
echo "total_ts_files=$TOTAL_TS_FILES" >> $GITHUB_OUTPUT
echo "large_files=$LARGE_FILES" >> $GITHUB_OUTPUT
# Check for declarative vs imperative balance
JSON_FILES=$(find src packages -name "*.json" 2>/dev/null | wc -l)
LUA_SCRIPTS=$(find src packages -name "*.lua" 2>/dev/null | wc -l)
echo "json_files=$JSON_FILES" >> $GITHUB_OUTPUT
echo "lua_scripts=$LUA_SCRIPTS" >> $GITHUB_OUTPUT
- name: Check architectural compliance
id: architecture
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
let issues = [];
let suggestions = [];
// Get changed files
let changedFiles = [];
if (context.eventName === 'pull_request') {
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
changedFiles = files.map(f => f.filename);
}
// Check for hardcoded components outside ui/
const hardcodedComponents = changedFiles.filter(f =>
f.endsWith('.tsx') &&
f.includes('src/components/') &&
!f.includes('src/components/ui/') &&
!f.includes('src/components/shared/') &&
!['RenderComponent', 'FieldRenderer', 'GenericPage'].some(g => f.includes(g))
);
if (hardcodedComponents.length > 0) {
suggestions.push(`Consider if these components could be declarative: ${hardcodedComponents.join(', ')}`);
}
// Check for database changes without seed data
const schemaChanged = changedFiles.some(f => f.includes('schema.prisma'));
const seedChanged = changedFiles.some(f => f.includes('seed'));
if (schemaChanged && !seedChanged) {
suggestions.push('Database schema changed but no seed data updates detected. Consider updating seed data.');
}
// Check for new routes without PageRoutes table updates
const routeFiles = changedFiles.filter(f => f.includes('Route') || f.includes('route'));
if (routeFiles.length > 0) {
suggestions.push('Route changes detected. Ensure PageRoutes table is updated for dynamic routing.');
}
// Check for large TypeScript files
const largeFiles = parseInt('${{ steps.quality.outputs.large_files }}');
if (largeFiles > 0) {
issues.push(`${largeFiles} TypeScript files exceed 150 lines. Consider breaking them into smaller components.`);
}
return { issues, suggestions };
- name: Provide development feedback
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const analysis = JSON.parse('${{ steps.architecture.outputs.result }}');
const totalFiles = parseInt('${{ steps.quality.outputs.total_ts_files }}');
const largeFiles = parseInt('${{ steps.quality.outputs.large_files }}');
const jsonFiles = parseInt('${{ steps.quality.outputs.json_files }}');
const luaScripts = parseInt('${{ steps.quality.outputs.lua_scripts }}');
let comment = `## 💻 Development Quality Feedback\n\n`;
comment += `### 📊 Code Metrics\n\n`;
comment += `- TypeScript files: ${totalFiles}\n`;
comment += `- Files >150 LOC: ${largeFiles} ${largeFiles > 0 ? '⚠️' : '✅'}\n`;
comment += `- JSON config files: ${jsonFiles}\n`;
comment += `- Lua scripts: ${luaScripts}\n`;
comment += `- Declarative ratio: ${((jsonFiles + luaScripts) / Math.max(totalFiles, 1) * 100).toFixed(1)}%\n\n`;
if (analysis.issues.length > 0) {
comment += `### ⚠️ Architectural Issues\n\n`;
analysis.issues.forEach(issue => comment += `- ${issue}\n`);
comment += '\n';
}
if (analysis.suggestions.length > 0) {
comment += `### 💡 Suggestions\n\n`;
analysis.suggestions.forEach(suggestion => comment += `- ${suggestion}\n`);
comment += '\n';
}
comment += `### 🎯 Project Goals Reminder\n\n`;
comment += `- **Declarative First:** Prefer JSON + Lua over TypeScript\n`;
comment += `- **Component Size:** Keep files under 150 LOC\n`;
comment += `- **Generic Renderers:** Use RenderComponent for dynamic components\n`;
comment += `- **Database-Driven:** Store configuration in database, not code\n`;
comment += `- **Package-Based:** Organize features as importable packages\n\n`;
comment += `**@copilot** can help refactor code to better align with these principles.\n\n`;
comment += `📖 See [Architecture Guidelines](/.github/copilot-instructions.md)`;
// Check if we already commented
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Development Quality Feedback')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: comment
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}
copilot-interaction:
name: Handle Copilot Mentions
runs-on: ubuntu-latest
if: |
github.event_name == 'issue_comment' &&
contains(github.event.comment.body, '@copilot')
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Parse Copilot request
uses: actions/github-script@v7
with:
script: |
const comment = context.payload.comment.body.toLowerCase();
const issue = context.payload.issue;
let response = `## 🤖 Copilot Assistance\n\n`;
// Determine what the user is asking for
if (comment.includes('implement') || comment.includes('fix this')) {
response += `To implement this with Copilot assistance:\n\n`;
response += `1. **Create a branch:** \`git checkout -b feature/issue-${issue.number}\`\n`;
response += `2. **Use Copilot in your IDE** to generate code with context from:\n`;
response += ` - [Copilot Instructions](/.github/copilot-instructions.md)\n`;
response += ` - [PRD.md](/PRD.md)\n`;
response += ` - Existing package structure in \`/packages/\`\n`;
response += `3. **Follow the architectural principles:**\n`;
response += ` - Declarative over imperative\n`;
response += ` - Database-driven configuration\n`;
response += ` - Generic renderers vs hardcoded components\n`;
response += `4. **Test your changes:** \`bun run lint && bun run test:e2e\`\n`;
response += `5. **Create a PR** - The automated workflows will review it\n\n`;
}
if (comment.includes('review') || comment.includes('check')) {
response += `Copilot can review this through:\n\n`;
response += `- **Automated Code Review** workflow (runs on PRs)\n`;
response += `- **Development Assistance** workflow (runs on pushes)\n`;
response += `- **Planning & Design** workflow (runs on feature requests)\n\n`;
response += `Create a PR to trigger comprehensive review!\n\n`;
}
if (comment.includes('architecture') || comment.includes('design')) {
response += `### 🏗️ Architectural Guidance\n\n`;
response += `MetaBuilder follows these principles:\n\n`;
response += `1. **5-Level Architecture:** User → Admin → God → SuperGod levels\n`;
response += `2. **Multi-Tenant:** Isolated tenant instances with independent configs\n`;
response += `3. **Declarative Components:** JSON config + Lua scripts, not TSX\n`;
response += `4. **Package System:** Self-contained, importable feature bundles\n`;
response += `5. **Database-First:** All config in Prisma, not hardcoded\n\n`;
response += `📖 Full details: [PRD.md](/PRD.md)\n\n`;
}
if (comment.includes('test') || comment.includes('e2e')) {
response += `### 🧪 Testing with Copilot\n\n`;
response += `\`\`\`bash\n`;
response += `# Run E2E tests\n`;
response += `bun run test:e2e\n\n`;
response += `# Run with UI\n`;
response += `bun run test:e2e:ui\n\n`;
response += `# Run linter\n`;
response += `bun run lint\n`;
response += `\`\`\`\n\n`;
response += `Use Copilot in your IDE to:\n`;
response += `- Generate test cases based on user stories\n`;
response += `- Write Playwright selectors and assertions\n`;
response += `- Create mock data for tests\n\n`;
}
if (comment.includes('help') || (!comment.includes('implement') && !comment.includes('review') && !comment.includes('architecture') && !comment.includes('test'))) {
response += `### 🆘 How to Use Copilot\n\n`;
response += `Mention **@copilot** in comments with:\n\n`;
response += `- \`@copilot implement this\` - Get implementation guidance\n`;
response += `- \`@copilot review this\` - Request code review\n`;
response += `- \`@copilot architecture\` - Get architectural guidance\n`;
response += `- \`@copilot test this\` - Get testing guidance\n`;
response += `- \`@copilot fix this issue\` - Request automated fix\n\n`;
response += `**In your IDE:**\n`;
response += `- Use GitHub Copilot with context from [Copilot Instructions](/.github/copilot-instructions.md)\n`;
response += `- Reference the [PRD](/PRD.md) when prompting\n`;
response += `- Follow patterns from existing packages in \`/packages/\`\n\n`;
}
response += `---\n`;
response += `*This is an automated response. For detailed Copilot assistance, use the extension in your IDE with project context.*`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: response
});
suggest-refactoring:
name: Suggest Refactoring Opportunities
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' && !github.event.pull_request.draft
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Analyze refactoring opportunities
uses: actions/github-script@v7
with:
script: |
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
let opportunities = [];
// Look for opportunities in changed files
for (const file of files) {
const patch = file.patch || '';
// Check for repeated code patterns
if (patch.split('\n').length > 100) {
opportunities.push({
file: file.filename,
type: 'Size',
suggestion: 'Large changeset - consider breaking into smaller PRs or extracting common utilities'
});
}
// Check for hardcoded values
if (patch.match(/['"][A-Z_]{3,}['"]\s*:/)) {
opportunities.push({
file: file.filename,
type: 'Configuration',
suggestion: 'Hardcoded constants detected - consider moving to database configuration'
});
}
// Check for new TSX components
if (file.filename.includes('components/') && file.filename.endsWith('.tsx') && file.status === 'added') {
opportunities.push({
file: file.filename,
type: 'Architecture',
suggestion: 'New component added - could this be implemented declaratively with JSON + Lua?'
});
}
// Check for inline styles or complex class strings
if (patch.includes('style={{') || patch.match(/className="[^"]{50,}"/)) {
opportunities.push({
file: file.filename,
type: 'Styling',
suggestion: 'Complex styling detected - consider extracting to theme configuration'
});
}
}
if (opportunities.length > 0) {
let comment = `## 🔄 Refactoring Opportunities\n\n`;
comment += `**@copilot** identified potential improvements:\n\n`;
const grouped = {};
opportunities.forEach(opp => {
if (!grouped[opp.type]) grouped[opp.type] = [];
grouped[opp.type].push(opp);
});
for (const [type, opps] of Object.entries(grouped)) {
comment += `### ${type}\n\n`;
opps.forEach(opp => {
comment += `- **${opp.file}**: ${opp.suggestion}\n`;
});
comment += '\n';
}
comment += `---\n`;
comment += `These are suggestions, not requirements. Consider them as part of continuous improvement.\n\n`;
comment += `Use **@copilot** in your IDE to help implement these refactorings.`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}

1033
.github/workflows/gated-ci-atomic.yml vendored Normal file

File diff suppressed because it is too large Load Diff

610
.github/workflows/gated-ci.yml vendored Normal file
View File

@@ -0,0 +1,610 @@
name: Enterprise Gated CI/CD Pipeline
on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master, develop ]
permissions:
contents: read
pull-requests: write
checks: write
statuses: write
# Enterprise Gated Tree Workflow
# Changes must pass through 5 gates before merge:
# Gate 1: Code Quality (lint, typecheck, security)
# Gate 2: Testing (unit, E2E)
# Gate 3: Build & Package
# Gate 4: Review & Approval
# Gate 5: Deployment (staging → production with manual approval)
jobs:
# ============================================================================
# GATE 1: Code Quality Gates
# ============================================================================
gate-1-start:
name: "Gate 1: Code Quality - Starting"
runs-on: ubuntu-latest
steps:
- name: Gate 1 checkpoint
run: |
echo "🚦 GATE 1: CODE QUALITY VALIDATION"
echo "================================================"
echo "Running: Prisma validation, TypeScript check, Linting, Security scan"
echo "Status: IN PROGRESS"
prisma-check:
name: "Gate 1.1: Validate Prisma Schema"
runs-on: ubuntu-latest
needs: gate-1-start
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Validate Prisma Schema
run: bunx prisma validate
env:
DATABASE_URL: file:./dev.db
typecheck:
name: "Gate 1.2: TypeScript Type Check"
runs-on: ubuntu-latest
needs: prisma-check
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Run TypeScript type check
run: bun run typecheck
lint:
name: "Gate 1.3: Lint Code"
runs-on: ubuntu-latest
needs: prisma-check
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Run ESLint
run: bun run lint
security-scan:
name: "Gate 1.4: Security Scan"
runs-on: ubuntu-latest
needs: prisma-check
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Run security audit
run: bun audit --audit-level=moderate
continue-on-error: true
- name: Check for vulnerable dependencies
run: |
echo "Checking for known vulnerabilities..."
bun audit --json > audit-results.json 2>&1 || true
if [ -f audit-results.json ]; then
echo "Security audit completed"
fi
gate-1-complete:
name: "Gate 1: Code Quality - Passed ✅"
runs-on: ubuntu-latest
needs: [prisma-check, typecheck, lint, security-scan]
steps:
- name: Gate 1 passed
run: |
echo "✅ GATE 1 PASSED: CODE QUALITY"
echo "================================================"
echo "✓ Prisma schema validated"
echo "✓ TypeScript types checked"
echo "✓ Code linted"
echo "✓ Security scan completed"
echo ""
echo "Proceeding to Gate 2: Testing..."
# ============================================================================
# GATE 2: Testing Gates
# ============================================================================
gate-2-start:
name: "Gate 2: Testing - Starting"
runs-on: ubuntu-latest
needs: gate-1-complete
steps:
- name: Gate 2 checkpoint
run: |
echo "🚦 GATE 2: TESTING VALIDATION"
echo "================================================"
echo "Running: Unit tests, E2E tests, DBAL daemon tests"
echo "Status: IN PROGRESS"
test-unit:
name: "Gate 2.1: Unit Tests"
runs-on: ubuntu-latest
needs: gate-2-start
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Run unit tests
run: bun run test:unit
env:
DATABASE_URL: file:./dev.db
- name: Upload coverage report
if: always()
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: coverage-report
path: frontends/nextjs/coverage/
retention-days: 7
test-e2e:
name: "Gate 2.2: E2E Tests"
runs-on: ubuntu-latest
needs: gate-2-start
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Install Playwright Browsers
run: bunx playwright install --with-deps chromium
- name: Run Playwright tests
run: bun run test:e2e
env:
DATABASE_URL: file:./dev.db
- name: Upload test results
if: always()
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: playwright-report
path: frontends/nextjs/playwright-report/
retention-days: 7
test-dbal-daemon:
name: "Gate 2.3: DBAL Daemon E2E"
runs-on: ubuntu-latest
needs: gate-2-start
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Install Playwright Browsers
run: bunx playwright install --with-deps chromium
- name: Run DBAL daemon suite
run: bun run test:e2e:dbal-daemon
env:
DATABASE_URL: file:./dev.db
- name: Upload daemon test report
if: always()
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: playwright-report-dbal-daemon
path: frontends/nextjs/playwright-report/
retention-days: 7
gate-2-complete:
name: "Gate 2: Testing - Passed ✅"
runs-on: ubuntu-latest
needs: [test-unit, test-e2e, test-dbal-daemon]
steps:
- name: Gate 2 passed
run: |
echo "✅ GATE 2 PASSED: TESTING"
echo "================================================"
echo "✓ Unit tests passed"
echo "✓ E2E tests passed"
echo "✓ DBAL daemon tests passed"
echo ""
echo "Proceeding to Gate 3: Build & Package..."
# ============================================================================
# GATE 3: Build & Package Gates
# ============================================================================
gate-3-start:
name: "Gate 3: Build & Package - Starting"
runs-on: ubuntu-latest
needs: gate-2-complete
steps:
- name: Gate 3 checkpoint
run: |
echo "🚦 GATE 3: BUILD & PACKAGE VALIDATION"
echo "================================================"
echo "Running: Application build, artifact packaging"
echo "Status: IN PROGRESS"
build:
name: "Gate 3.1: Build Application"
runs-on: ubuntu-latest
needs: gate-3-start
defaults:
run:
working-directory: frontends/nextjs
outputs:
build-success: ${{ steps.build-step.outcome }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Build
id: build-step
run: bun run build
env:
DATABASE_URL: file:./dev.db
- name: Upload build artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist
path: frontends/nextjs/.next/
retention-days: 7
quality-check:
name: "Gate 3.2: Code Quality Metrics"
runs-on: ubuntu-latest
needs: gate-3-start
if: github.event_name == 'pull_request'
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '20'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Check for console.log statements
run: |
if git diff origin/${{ github.base_ref }}...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx' | grep -E '^\+.*console\.(log|debug|info)'; then
echo "⚠️ Found console.log statements in the changes"
echo "Please remove console.log statements before merging"
exit 1
fi
continue-on-error: true
- name: Check for TODO comments
run: |
TODO_COUNT=$(git diff origin/${{ github.base_ref }}...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx' | grep -E '^\+.*TODO|FIXME' | wc -l)
if [ $TODO_COUNT -gt 0 ]; then
echo "⚠️ Found $TODO_COUNT TODO/FIXME comments in the changes"
echo "Please address TODO comments before merging or create issues for them"
fi
continue-on-error: true
gate-3-complete:
name: "Gate 3: Build & Package - Passed ✅"
runs-on: ubuntu-latest
needs: [build, quality-check]
if: always() && needs.build.result == 'success' && (needs.quality-check.result == 'success' || needs.quality-check.result == 'skipped')
steps:
- name: Gate 3 passed
run: |
echo "✅ GATE 3 PASSED: BUILD & PACKAGE"
echo "================================================"
echo "✓ Application built successfully"
echo "✓ Build artifacts packaged"
echo "✓ Quality metrics validated"
echo ""
echo "Proceeding to Gate 4: Review & Approval..."
# ============================================================================
# GATE 4: Review & Approval Gate (PR only)
# ============================================================================
gate-4-review-required:
name: "Gate 4: Review & Approval Required"
runs-on: ubuntu-latest
needs: gate-3-complete
if: github.event_name == 'pull_request'
steps:
- name: Check PR approval status
uses: actions/github-script@v7
with:
script: |
const { data: reviews } = await github.rest.pulls.listReviews({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
const latestReviews = {};
for (const review of reviews) {
latestReviews[review.user.login] = review.state;
}
const hasApproval = Object.values(latestReviews).includes('APPROVED');
const hasRequestChanges = Object.values(latestReviews).includes('CHANGES_REQUESTED');
console.log('Review Status:');
console.log('==============');
console.log('Approvals:', Object.values(latestReviews).filter(s => s === 'APPROVED').length);
console.log('Change Requests:', Object.values(latestReviews).filter(s => s === 'CHANGES_REQUESTED').length);
if (hasRequestChanges) {
core.setFailed('❌ Changes requested - PR cannot proceed to deployment');
} else if (!hasApproval) {
core.notice('⏳ PR approval required before merge - this gate will pass when approved');
} else {
console.log('✅ PR approved - gate passed');
}
gate-4-complete:
name: "Gate 4: Review & Approval - Status"
runs-on: ubuntu-latest
needs: gate-4-review-required
if: always() && github.event_name == 'pull_request'
steps:
- name: Gate 4 status
run: |
echo "🚦 GATE 4: REVIEW & APPROVAL"
echo "================================================"
echo "Note: This gate requires human approval"
echo "PR must be approved by reviewers before auto-merge"
echo ""
if [ "${{ needs.gate-4-review-required.result }}" == "success" ]; then
echo "✅ Review approval received"
echo "Proceeding to Gate 5: Deployment (post-merge)..."
else
echo "⏳ Awaiting review approval"
echo "Gate will complete when PR is approved"
fi
# ============================================================================
# GATE 5: Deployment Gate (post-merge, main branch only)
# ============================================================================
gate-5-deployment-ready:
name: "Gate 5: Deployment Ready"
runs-on: ubuntu-latest
needs: gate-3-complete
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
steps:
- name: Deployment gate checkpoint
run: |
echo "🚦 GATE 5: DEPLOYMENT VALIDATION"
echo "================================================"
echo "Code merged to main branch"
echo "Ready for staging deployment"
echo ""
echo "✅ ALL GATES PASSED"
echo "================================================"
echo "✓ Gate 1: Code Quality"
echo "✓ Gate 2: Testing"
echo "✓ Gate 3: Build & Package"
echo "✓ Gate 4: Review & Approval"
echo "✓ Gate 5: Ready for Deployment"
echo ""
echo "Note: Production deployment requires manual approval"
echo "Use workflow_dispatch with environment='production'"
# ============================================================================
# Summary Report
# ============================================================================
gates-summary:
name: "🎯 Gates Summary"
runs-on: ubuntu-latest
needs: [gate-1-complete, gate-2-complete, gate-3-complete]
if: always()
steps:
- name: Generate gates report
uses: actions/github-script@v7
with:
script: |
const gates = [
{ name: 'Gate 1: Code Quality', status: '${{ needs.gate-1-complete.result }}' },
{ name: 'Gate 2: Testing', status: '${{ needs.gate-2-complete.result }}' },
{ name: 'Gate 3: Build & Package', status: '${{ needs.gate-3-complete.result }}' }
];
let summary = '## 🚦 Enterprise Gated CI/CD Pipeline Summary\n\n';
for (const gate of gates) {
const icon = gate.status === 'success' ? '✅' :
gate.status === 'failure' ? '❌' :
gate.status === 'skipped' ? '⏭️' : '⏳';
summary += `${icon} **${gate.name}**: ${gate.status}\n`;
}
if (context.eventName === 'pull_request') {
summary += '\n### Next Steps\n';
summary += '- ✅ All CI gates passed\n';
summary += '- ⏳ Awaiting PR approval (Gate 4)\n';
summary += '- 📋 Once approved, PR will auto-merge\n';
summary += '- 🚀 Deployment gates (Gate 5) run after merge to main\n';
}
console.log(summary);
// Post comment on PR if applicable
if (context.eventName === 'pull_request') {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: summary
});
}

617
.github/workflows/gated-deployment.yml vendored Normal file
View File

@@ -0,0 +1,617 @@
name: Enterprise Gated Deployment
on:
push:
branches:
- main
- master
release:
types: [published]
workflow_dispatch:
inputs:
environment:
description: 'Target deployment environment'
required: true
type: choice
options:
- staging
- production
skip_tests:
description: 'Skip pre-deployment tests (emergency only)'
required: false
type: boolean
default: false
permissions:
contents: read
issues: write
pull-requests: write
deployments: write
# Enterprise Deployment with Environment Gates
# Staging: Automatic deployment after main branch push
# Production: Requires manual approval
jobs:
# ============================================================================
# Pre-Deployment Validation
# ============================================================================
pre-deployment-validation:
name: Pre-Deployment Checks
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
outputs:
has-breaking-changes: ${{ steps.breaking.outputs.has_breaking }}
deployment-environment: ${{ steps.determine-env.outputs.environment }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Determine target environment
id: determine-env
run: |
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
echo "environment=${{ inputs.environment }}" >> $GITHUB_OUTPUT
elif [ "${{ github.event_name }}" == "release" ]; then
echo "environment=production" >> $GITHUB_OUTPUT
else
echo "environment=staging" >> $GITHUB_OUTPUT
fi
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Validate database schema
run: bunx prisma validate
env:
DATABASE_URL: file:./dev.db
- name: Check for breaking changes
id: breaking
uses: actions/github-script@v7
with:
script: |
const commits = await github.rest.repos.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 10
});
let hasBreaking = false;
let breakingChanges = [];
for (const commit of commits.data) {
const message = commit.commit.message.toLowerCase();
if (message.includes('breaking') || message.includes('breaking:') || message.startsWith('!')) {
hasBreaking = true;
breakingChanges.push({
sha: commit.sha.substring(0, 7),
message: commit.commit.message.split('\n')[0]
});
}
}
core.setOutput('has_breaking', hasBreaking);
if (hasBreaking) {
console.log('⚠️ Breaking changes detected:');
breakingChanges.forEach(c => console.log(` - ${c.sha}: ${c.message}`));
core.warning('Breaking changes detected in recent commits');
}
- name: Security audit
run: bun audit --audit-level=moderate
continue-on-error: true
- name: Check package size
run: |
bun run build
SIZE=$(du -sm .next/ | cut -f1)
echo "Build size: ${SIZE}MB"
if [ $SIZE -gt 50 ]; then
echo "::warning::Build size is ${SIZE}MB (>50MB). Consider optimizing."
fi
# ============================================================================
# Staging Deployment (Automatic)
# ============================================================================
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: pre-deployment-validation
if: |
needs.pre-deployment-validation.outputs.deployment-environment == 'staging' &&
(github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'staging'))
environment:
name: staging
url: https://staging.metabuilder.example.com
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
- name: Build for staging
run: bun run build
env:
DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
NEXT_PUBLIC_ENV: staging
- name: Deploy to staging
run: |
echo "🚀 Deploying to staging environment..."
echo "Build artifacts ready for deployment"
echo "Note: Replace this with actual deployment commands"
echo "Examples:"
echo " - docker build/push"
echo " - kubectl apply"
echo " - terraform apply"
echo " - vercel deploy"
- name: Run smoke tests
run: |
echo "🧪 Running smoke tests on staging..."
echo "Basic health checks:"
echo " ✓ Application starts"
echo " ✓ Database connection"
echo " ✓ API endpoints responding"
echo "Note: Implement actual smoke tests here"
- name: Post deployment summary
uses: actions/github-script@v7
with:
script: |
const summary = `## 🚀 Staging Deployment Successful
**Environment:** staging
**Commit:** ${context.sha.substring(0, 7)}
**Time:** ${new Date().toISOString()}
### Deployment Details
- ✅ Pre-deployment validation passed
- ✅ Build completed
- ✅ Deployed to staging
- ✅ Smoke tests passed
### Next Steps
- Monitor staging environment for issues
- Run integration tests
- Request QA validation
- If stable, promote to production with manual approval
**Staging URL:** https://staging.metabuilder.example.com
`;
console.log(summary);
# ============================================================================
# Production Deployment Gate (Manual Approval Required)
# ============================================================================
production-approval-gate:
name: Production Deployment Gate
runs-on: ubuntu-latest
needs: [pre-deployment-validation]
if: |
needs.pre-deployment-validation.outputs.deployment-environment == 'production' &&
(github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'production'))
steps:
- name: Pre-production checklist
uses: actions/github-script@v7
with:
script: |
const hasBreaking = '${{ needs.pre-deployment-validation.outputs.has-breaking-changes }}' === 'true';
let checklist = `## 🚨 Production Deployment Gate
### Pre-Deployment Checklist
#### Automatic Checks
- ✅ All CI/CD gates passed
- ✅ Code merged to main branch
- ✅ Pre-deployment validation completed
${hasBreaking ? '- ⚠️ **Breaking changes detected** - review required' : '- ✅ No breaking changes detected'}
#### Manual Verification Required
- [ ] Staging environment validated
- [ ] QA sign-off received
- [ ] Database migrations reviewed
- [ ] Rollback plan prepared
- [ ] Monitoring alerts configured
- [ ] On-call engineer notified
${hasBreaking ? '- [ ] **Breaking changes documented and communicated**' : ''}
### Approval Process
This deployment requires manual approval from authorized personnel.
**To approve:** Use the GitHub Actions UI to approve this deployment.
**To reject:** Cancel the workflow run.
### Emergency Override
If this is an emergency hotfix, the skip_tests option was set to: ${{ inputs.skip_tests || false }}
`;
console.log(checklist);
if (hasBreaking) {
core.warning('Breaking changes detected - extra caution required for production deployment');
}
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: [pre-deployment-validation, production-approval-gate]
if: |
needs.pre-deployment-validation.outputs.deployment-environment == 'production' &&
(github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.environment == 'production'))
environment:
name: production
url: https://metabuilder.example.com
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: bun install
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
- name: Build for production
run: bun run build
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
NEXT_PUBLIC_ENV: production
NODE_ENV: production
- name: Pre-deployment backup
run: |
echo "📦 Creating pre-deployment backup..."
echo "Note: Implement actual backup commands"
echo " - Database backup"
echo " - File system backup"
echo " - Configuration backup"
- name: Run database migrations
run: |
echo "🗄️ Running database migrations..."
echo "Note: Implement actual migration commands"
echo "bunx prisma migrate deploy"
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
- name: Deploy to production
run: |
echo "🚀 Deploying to production environment..."
echo "Build artifacts ready for deployment"
echo "Note: Replace this with actual deployment commands"
echo "Examples:"
echo " - docker build/push"
echo " - kubectl apply"
echo " - terraform apply"
echo " - vercel deploy --prod"
- name: Run smoke tests
run: |
echo "🧪 Running smoke tests on production..."
echo "Basic health checks:"
echo " ✓ Application starts"
echo " ✓ Database connection"
echo " ✓ API endpoints responding"
echo " ✓ Critical user flows working"
echo "Note: Implement actual smoke tests here"
- name: Post deployment summary
uses: actions/github-script@v7
with:
script: |
const hasBreaking = '${{ needs.pre-deployment-validation.outputs.has-breaking-changes }}' === 'true';
const summary = `## 🎉 Production Deployment Successful
**Environment:** production
**Commit:** ${context.sha.substring(0, 7)}
**Time:** ${new Date().toISOString()}
${hasBreaking ? '**⚠️ Contains Breaking Changes**' : ''}
### Deployment Details
- ✅ Manual approval received
- ✅ Pre-deployment validation passed
- ✅ Database migrations completed
- ✅ Build completed
- ✅ Deployed to production
- ✅ Smoke tests passed
### Post-Deployment Monitoring
- 🔍 Monitor error rates for 1 hour
- 📊 Check performance metrics
- 👥 Monitor user feedback
- 🚨 Keep rollback plan ready
**Production URL:** https://metabuilder.example.com
### Emergency Contacts
- On-call engineer: Check PagerDuty
- Rollback procedure: See docs/deployment/rollback.md
`;
console.log(summary);
// Create deployment tracking issue
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `🚀 Production Deployment - ${new Date().toISOString().split('T')[0]}`,
body: summary,
labels: ['deployment', 'production', 'monitoring']
});
console.log(`Created monitoring issue #${issue.data.number}`);
# ============================================================================
# Post-Deployment Monitoring
# ============================================================================
post-deployment-health:
name: Post-Deployment Health Check
runs-on: ubuntu-latest
needs: [pre-deployment-validation, deploy-staging, deploy-production]
if: always() && (needs.deploy-staging.result == 'success' || needs.deploy-production.result == 'success')
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Determine deployed environment
id: env
run: |
if [ "${{ needs.deploy-production.result }}" == "success" ]; then
echo "environment=production" >> $GITHUB_OUTPUT
else
echo "environment=staging" >> $GITHUB_OUTPUT
fi
- name: Wait for application warm-up
run: |
echo "⏳ Waiting 30 seconds for application to warm up..."
sleep 30
- name: Run health checks
run: |
ENV="${{ steps.env.outputs.environment }}"
echo "🏥 Running health checks for $ENV environment..."
echo ""
echo "Checking:"
echo " - Application availability"
echo " - Database connectivity"
echo " - API response times"
echo " - Error rates"
echo " - Memory usage"
echo " - CPU usage"
echo ""
echo "Note: Implement actual health check commands"
echo "Examples:"
echo " curl -f https://$ENV.metabuilder.example.com/api/health"
echo " npm run health-check --env=$ENV"
- name: Schedule 24h monitoring
uses: actions/github-script@v7
with:
script: |
const env = '${{ steps.env.outputs.environment }}';
const deploymentTime = new Date().toISOString();
console.log(`📅 Scheduling 24-hour monitoring for ${env} deployment`);
console.log(`Deployment time: ${deploymentTime}`);
console.log('');
console.log('Monitoring checklist:');
console.log(' - Hour 1: Active monitoring of error rates');
console.log(' - Hour 6: Check performance metrics');
console.log(' - Hour 24: Full health assessment');
console.log('');
console.log('Note: Set up actual monitoring alerts in your observability platform');
# ============================================================================
# Deployment Failure Handler - Prefer Roll Forward
# ============================================================================
deployment-failure-handler:
name: Handle Deployment Failure
runs-on: ubuntu-latest
needs: [pre-deployment-validation, deploy-production]
if: |
failure() &&
(needs.pre-deployment-validation.result == 'failure' || needs.deploy-production.result == 'failure')
steps:
- name: Determine failure stage
id: failure-stage
run: |
if [ "${{ needs.pre-deployment-validation.result }}" == "failure" ]; then
echo "stage=pre-deployment" >> $GITHUB_OUTPUT
echo "severity=low" >> $GITHUB_OUTPUT
else
echo "stage=production" >> $GITHUB_OUTPUT
echo "severity=high" >> $GITHUB_OUTPUT
fi
- name: Display roll-forward guidance
run: |
echo "⚡ DEPLOYMENT FAILURE DETECTED"
echo "================================"
echo ""
echo "Failure Stage: ${{ steps.failure-stage.outputs.stage }}"
echo "Severity: ${{ steps.failure-stage.outputs.severity }}"
echo ""
echo "🎯 RECOMMENDED APPROACH: ROLL FORWARD"
echo "────────────────────────────────────────"
echo ""
echo "Rolling forward is preferred because it:"
echo " ✅ Fixes the root cause permanently"
echo " ✅ Maintains forward progress"
echo " ✅ Builds team capability"
echo " ✅ Prevents recurrence"
echo ""
echo "Steps to roll forward:"
echo " 1. Review failure logs (link below)"
echo " 2. Identify and fix the root cause"
echo " 3. Test the fix locally"
echo " 4. Push fix to trigger new deployment"
echo ""
echo "⚠️ ROLLBACK ONLY IF:"
echo "────────────────────────"
echo " • Production is actively broken"
echo " • Users are experiencing outages"
echo " • Critical security vulnerability"
echo " • Data integrity at risk"
echo ""
if [ "${{ steps.failure-stage.outputs.stage }}" == "pre-deployment" ]; then
echo "✅ GOOD NEWS: Failure occurred pre-deployment"
echo " → Production is NOT affected"
echo " → Safe to fix and retry"
echo " → No rollback needed"
else
echo "🚨 Production deployment failed"
echo " → Assess production impact immediately"
echo " → Check monitoring dashboards"
echo " → Verify user-facing functionality"
fi
- name: Create fix-forward issue
uses: actions/github-script@v7
with:
script: |
const stage = '${{ steps.failure-stage.outputs.stage }}';
const severity = '${{ steps.failure-stage.outputs.severity }}';
const isProd = stage === 'production';
const title = isProd
? '🚨 Production Deployment Failed - Fix Required'
: '⚠️ Pre-Deployment Validation Failed';
const body = `## Deployment Failure - ${stage === 'production' ? 'Production' : 'Pre-Deployment'}
**Time:** ${new Date().toISOString()}
**Commit:** ${context.sha.substring(0, 7)}
**Workflow Run:** [View Logs](${context.payload.repository.html_url}/actions/runs/${context.runId})
**Failure Stage:** ${stage}
**Severity:** ${severity}
${!isProd ? '✅ **Good News:** Production is NOT affected. The failure occurred during pre-deployment checks.\n' : '🚨 **Alert:** Production deployment failed. Assess impact immediately.\n'}
### 🎯 Recommended Action: Roll Forward (Fix and Re-deploy)
Rolling forward is the preferred approach because it:
- ✅ Fixes the root cause permanently
- ✅ Maintains development momentum
- ✅ Prevents the same issue from recurring
- ✅ Builds team problem-solving skills
### 📋 Fix-Forward Checklist
- [ ] **Investigate:** Review [workflow logs](${context.payload.repository.html_url}/actions/runs/${context.runId})
- [ ] **Diagnose:** Identify root cause of failure
- [ ] **Fix:** Implement fix in a new branch/commit
- [ ] **Test:** Verify fix locally (run relevant tests/builds)
- [ ] **Deploy:** Push fix to trigger new deployment
- [ ] **Verify:** Monitor deployment and confirm success
- [ ] **Document:** Update this issue with resolution details
${isProd ? `
### 🚨 Production Impact Assessment
**Before proceeding, verify:**
- [ ] Check monitoring dashboards for errors/alerts
- [ ] Verify critical user flows are working
- [ ] Check application logs for issues
- [ ] Assess if immediate rollback is needed
` : ''}
### ⚠️ When to Rollback Instead
**Only rollback if:**
- 🔴 Production is actively broken with user impact
- 🔴 Critical security vulnerability exposed
- 🔴 Data integrity at risk
- 🔴 Cannot fix forward within acceptable timeframe
${isProd ? `
### 🔄 Rollback Procedure (if absolutely necessary)
1. **Re-run workflow** with previous stable commit SHA
2. **OR use manual rollback:**
- Rollback specific migration: \`npx prisma migrate resolve --rolled-back MIGRATION_NAME --schema=prisma/schema.prisma\`
- Deploy previous Docker image/build
- Restore from pre-deployment backup if needed
- ⚠️ Avoid \`prisma migrate reset\` in production (causes data loss)
3. **Notify:** Update team and status page
4. **Document:** Create post-mortem issue
See [Rollback Procedure](docs/deployment/rollback.md) for details.
` : `
### 💡 Common Pre-Deployment Failures
- **Prisma Generate:** Check schema.prisma syntax and DATABASE_URL
- **Build Failure:** Review TypeScript errors or missing dependencies
- **Test Failure:** Fix failing tests or update test snapshots
- **Lint Errors:** Run \`npm run lint:fix\` locally
`}
### 📚 Resources
- [Workflow Run Logs](${context.payload.repository.html_url}/actions/runs/${context.runId})
- [Commit Details](${context.payload.repository.html_url}/commit/${context.sha})
- [Deployment Documentation](docs/deployment/)
`;
const labels = isProd
? ['deployment', 'production', 'incident', 'high-priority', 'fix-forward']
: ['deployment', 'pre-deployment', 'ci-failure', 'fix-forward'];
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: labels
});

File diff suppressed because it is too large Load Diff

182
.github/workflows/issue-triage.yml vendored Normal file
View File

@@ -0,0 +1,182 @@
name: Issue Triage and Auto-Fix
on:
issues:
types: [opened, labeled]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
triage-issue:
name: Triage and Label Issues
runs-on: ubuntu-latest
if: github.event.action == 'opened'
steps:
- name: Analyze and label issue
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const title = issue.title.toLowerCase();
const body = (issue.body || '').toLowerCase();
const text = title + ' ' + body;
let labels = [];
// Categorize by type
if (text.match(/bug|error|crash|broken|fail/)) {
labels.push('bug');
}
if (text.match(/feature|enhancement|add|new|implement/)) {
labels.push('enhancement');
}
if (text.match(/document|readme|docs|guide/)) {
labels.push('documentation');
}
if (text.match(/test|testing|spec|e2e/)) {
labels.push('testing');
}
if (text.match(/security|vulnerability|exploit|xss|sql/)) {
labels.push('security');
}
if (text.match(/performance|slow|optimize|speed/)) {
labels.push('performance');
}
// Categorize by priority
if (text.match(/critical|urgent|asap|blocker/)) {
labels.push('priority: high');
} else if (text.match(/minor|low|nice to have/)) {
labels.push('priority: low');
} else {
labels.push('priority: medium');
}
// Check if it's a good first issue
if (text.match(/beginner|easy|simple|starter/) || labels.length <= 2) {
labels.push('good first issue');
}
// Check if AI can help
if (labels.includes('bug') || labels.includes('documentation') || labels.includes('testing')) {
labels.push('ai-fixable');
}
// Add labels
if (labels.length > 0) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: labels
});
} catch (e) {
console.log('Some labels may not exist:', e.message);
}
}
// Post welcome comment
const aiHelpText = labels.includes('ai-fixable')
? '\n\n🤖 This issue appears to be something AI can help with! A fix may be automatically attempted.'
: '';
const comment = '👋 Thank you for opening this issue!\n\n' +
'This issue has been automatically labeled as: ' + labels.join(', ') +
aiHelpText + '\n\n' +
'A maintainer will review this issue soon. In the meantime, please make sure you have provided:\n' +
'- A clear description of the issue\n' +
'- Steps to reproduce (for bugs)\n' +
'- Expected vs actual behavior\n' +
'- Any relevant error messages or screenshots\n\n' +
'Copilot may be able to help with this issue.';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});
attempt-auto-fix:
name: Attempt Automated Fix
runs-on: ubuntu-latest
if: |
(github.event.action == 'labeled' && github.event.label.name == 'ai-fixable') ||
(github.event.action == 'labeled' && github.event.label.name == 'auto-fix')
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Analyze issue and suggest fix
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const labelList = issue.labels.map(l => l.name).join(', ');
const comment = '🤖 **AI-Assisted Fix Attempt**\n\n' +
'I have analyzed this issue and here are my suggestions:\n\n' +
'**Issue Type:** ' + labelList + '\n\n' +
'**Suggested Actions:**\n' +
'1. Review the issue description carefully\n' +
'2. Check for similar issues in the repository history\n' +
'3. Consider using Copilot to help implement the fix\n\n' +
'**To request an automated fix:**\n' +
'- Add the auto-fix label to this issue\n' +
'- Ensure the issue description clearly explains:\n' +
' - What needs to be fixed\n' +
' - Where the issue is located (file/line if known)\n' +
' - Expected behavior\n\n' +
'**Note:** Complex issues may require human review before implementation.\n\n' +
'Would you like me to attempt an automated fix? If so, please confirm by commenting "Copilot fix this issue".';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});
create-fix-pr:
name: Create Fix PR
runs-on: ubuntu-latest
if: github.event.action == 'labeled' && github.event.label.name == 'create-pr'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Create fix branch and PR
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const branchName = 'auto-fix/issue-' + issue.number;
const comment = '🤖 **Automated Fix PR Creation**\n\n' +
'I have created a branch ' + branchName + ' for this fix.\n\n' +
'**Next Steps:**\n' +
'1. A developer or Copilot will work on the fix in this branch\n' +
'2. A pull request will be created automatically\n' +
'3. The PR will be linked to this issue\n\n' +
'**Branch:** ' + branchName + '\n\n' +
'To work on this fix:\n' +
'git fetch origin\n' +
'git checkout ' + branchName + '\n\n' +
'This issue will be automatically closed when the PR is merged.';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});

202
.github/workflows/pr/auto-merge.yml vendored Normal file
View File

@@ -0,0 +1,202 @@
name: Auto Merge
on:
pull_request_review:
types: [submitted]
check_suite:
types: [completed]
workflow_run:
workflows: ["CI/CD", "Enterprise Gated CI/CD Pipeline"]
types: [completed]
permissions:
contents: write
pull-requests: write
jobs:
auto-merge:
name: Auto Merge PR
runs-on: ubuntu-latest
if: >
${{
(github.event_name == 'pull_request_review' && github.event.review.state == 'approved') ||
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')
}}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check PR status and merge
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
// Get PR number from event
let prNumber;
if (context.payload.pull_request) {
prNumber = context.payload.pull_request.number;
} else if (context.payload.workflow_run) {
// Get PR from workflow run
const { data: prs } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
head: `${context.repo.owner}:${context.payload.workflow_run.head_branch}`
});
if (prs.length === 0) {
console.log('No open PR found for this branch');
return;
}
prNumber = prs[0].number;
} else {
console.log('Could not determine PR number');
return;
}
console.log(`Checking PR #${prNumber}`);
// Get PR details
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
if (pr.state !== 'open') {
console.log('PR is not open');
return;
}
if (pr.draft) {
console.log('PR is still in draft');
return;
}
// Check if PR is approved
const { data: reviews } = await github.rest.pulls.listReviews({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const latestReviews = {};
for (const review of reviews) {
latestReviews[review.user.login] = review.state;
}
const hasApproval = Object.values(latestReviews).includes('APPROVED');
const hasRequestChanges = Object.values(latestReviews).includes('CHANGES_REQUESTED');
if (!hasApproval) {
console.log('PR has not been approved yet');
return;
}
if (hasRequestChanges) {
console.log('PR has requested changes');
return;
}
// Check CI status - support both old and new gated workflows
const { data: checks } = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: pr.head.sha
});
// Required checks for old CI/CD workflow
const legacyRequiredChecks = ['Lint Code', 'Build Application', 'E2E Tests'];
// Required gate checks for new Enterprise Gated CI/CD Pipeline
const gatedRequiredChecks = [
'Gate 1: Code Quality - Passed ✅',
'Gate 2: Testing - Passed ✅',
'Gate 3: Build & Package - Passed ✅'
];
const checkStatuses = {};
for (const check of checks.check_runs) {
checkStatuses[check.name] = check.conclusion;
}
console.log('Check statuses:', checkStatuses);
// Check if using new gated workflow or old workflow
const hasGatedChecks = gatedRequiredChecks.some(checkName =>
checkStatuses[checkName] !== undefined
);
const requiredChecks = hasGatedChecks ? gatedRequiredChecks : legacyRequiredChecks;
console.log('Using checks:', hasGatedChecks ? 'Enterprise Gated' : 'Legacy');
// Wait for all required checks to pass
const allChecksPassed = requiredChecks.every(checkName =>
checkStatuses[checkName] === 'success' || checkStatuses[checkName] === 'skipped'
);
if (!allChecksPassed) {
console.log('Not all required checks have passed');
// Check if any checks failed
const anyChecksFailed = Object.values(checkStatuses).some(status =>
status === 'failure'
);
if (anyChecksFailed) {
console.log('Some checks failed, not merging');
return;
}
console.log('Checks are still running, will retry later');
return;
}
console.log('All conditions met, merging PR');
// Add comment before merging
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '✅ All checks passed and PR is approved! Auto-merging and cleaning up branch.'
});
try {
// Merge the PR
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
merge_method: 'squash',
commit_title: `${pr.title} (#${prNumber})`,
commit_message: pr.body || ''
});
console.log('PR merged successfully');
// Delete the branch
try {
await github.rest.git.deleteRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: `heads/${pr.head.ref}`
});
console.log(`Branch ${pr.head.ref} deleted successfully`);
} catch (deleteError) {
console.log('Could not delete branch:', deleteError.message);
// Don't fail the workflow if branch deletion fails
}
} catch (mergeError) {
console.error('Failed to merge PR:', mergeError.message);
// Post comment about merge failure
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: `❌ Auto-merge failed: ${mergeError.message}\n\nPlease merge manually.`
});
}

277
.github/workflows/pr/code-review.yml vendored Normal file
View File

@@ -0,0 +1,277 @@
name: Automated Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
checks: read
jobs:
automated-review:
name: AI-Assisted Code Review
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Run linter for review
id: lint
run: |
bun run lint > lint-output.txt 2>&1 || echo "LINT_FAILED=true" >> $GITHUB_OUTPUT
cat lint-output.txt
continue-on-error: true
- name: Analyze code changes
id: analyze
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// Get PR diff
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
let issues = [];
let warnings = [];
let suggestions = [];
// Analyze each file
for (const file of files) {
const patch = file.patch || '';
const filename = file.filename;
// Check for security issues
if (patch.match(/eval\s*\(/)) {
issues.push(`⚠️ **Security**: Use of \`eval()\` found in ${filename}`);
}
if (patch.match(/innerHTML\s*=/)) {
warnings.push(`⚠️ **Security**: Direct \`innerHTML\` usage in ${filename}. Consider using safer alternatives.`);
}
if (patch.match(/dangerouslySetInnerHTML/)) {
warnings.push(`⚠️ **Security**: \`dangerouslySetInnerHTML\` usage in ${filename}. Ensure content is sanitized.`);
}
// Check for code quality
if (patch.match(/console\.(log|debug|info)/)) {
warnings.push(`🔍 **Code Quality**: Console statements found in ${filename}. Remove before merging.`);
}
if (patch.match(/debugger/)) {
issues.push(`🐛 **Debug Code**: Debugger statement found in ${filename}. Remove before merging.`);
}
if (patch.match(/(:\s*any\b|\bany\s*[>;,\)])/)) {
suggestions.push(`💡 **Type Safety**: Consider replacing \`any\` types with specific types in ${filename}`);
}
// Check for best practices
if (filename.endsWith('.tsx') || filename.endsWith('.jsx')) {
if (patch.match(/useEffect.*\[\]/) && !patch.includes('// eslint-disable')) {
suggestions.push(`💡 **React**: Empty dependency array in useEffect in ${filename}. Verify if intentional.`);
}
}
// Check for large files
if (file.additions > 500) {
warnings.push(`📏 **File Size**: ${filename} has ${file.additions} additions. Consider breaking into smaller files.`);
}
}
// Read lint output if exists
let lintIssues = '';
try {
lintIssues = fs.readFileSync('lint-output.txt', 'utf8');
} catch (e) {
// File doesn't exist
}
// Determine if auto-approve is appropriate
const hasBlockingIssues = issues.length > 0 || lintIssues.includes('error');
return {
issues,
warnings,
suggestions,
lintIssues,
hasBlockingIssues,
fileCount: files.length,
totalAdditions: files.reduce((sum, f) => sum + f.additions, 0),
totalDeletions: files.reduce((sum, f) => sum + f.deletions, 0)
};
- name: Post review comment
uses: actions/github-script@v7
with:
script: |
const analysis = JSON.parse('${{ steps.analyze.outputs.result }}');
let comment = '## 🤖 Automated Code Review\n\n';
comment += `**Changes Summary:**\n`;
comment += `- Files changed: ${analysis.fileCount}\n`;
comment += `- Lines added: ${analysis.totalAdditions}\n`;
comment += `- Lines deleted: ${analysis.totalDeletions}\n\n`;
if (analysis.issues.length > 0) {
comment += '### ❌ Blocking Issues\n\n';
analysis.issues.forEach(issue => comment += `- ${issue}\n`);
comment += '\n';
}
if (analysis.warnings.length > 0) {
comment += '### ⚠️ Warnings\n\n';
analysis.warnings.forEach(warning => comment += `- ${warning}\n`);
comment += '\n';
}
if (analysis.suggestions.length > 0) {
comment += '### 💡 Suggestions\n\n';
analysis.suggestions.forEach(suggestion => comment += `- ${suggestion}\n`);
comment += '\n';
}
if (analysis.lintIssues && analysis.lintIssues.includes('error')) {
comment += '### 🔴 Linting Errors\n\n';
comment += '```\n' + analysis.lintIssues + '\n```\n\n';
}
if (analysis.hasBlockingIssues) {
comment += '---\n';
comment += '### ❌ Review Status: **CHANGES REQUESTED**\n\n';
comment += 'Please address the blocking issues above before this PR can be approved.\n';
} else {
comment += '---\n';
comment += '### ✅ Review Status: **APPROVED**\n\n';
comment += 'No blocking issues found! This PR looks good to merge after CI checks pass.\n';
}
// Check if we already commented
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(c =>
c.user.type === 'Bot' && c.body.includes('Automated Code Review')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: comment
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}
- name: Add labels based on review
uses: actions/github-script@v7
with:
script: |
const analysis = JSON.parse('${{ steps.analyze.outputs.result }}');
let labels = [];
if (analysis.hasBlockingIssues) {
labels.push('needs-changes');
} else {
labels.push('ready-for-review');
}
if (analysis.warnings.length > 0) {
labels.push('has-warnings');
}
if (analysis.totalAdditions > 500) {
labels.push('large-pr');
}
// Remove conflicting labels first
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'needs-changes'
});
} catch (e) {
// Label doesn't exist
}
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'ready-for-review'
});
} catch (e) {
// Label doesn't exist
}
// Add new labels
for (const label of labels) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: [label]
});
} catch (e) {
console.log(`Label ${label} might not exist, skipping...`);
}
}
- name: Auto-approve if no issues
if: steps.analyze.outputs.result && !fromJSON(steps.analyze.outputs.result).hasBlockingIssues
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.pulls.createReview({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
event: 'APPROVE',
body: '✅ Automated review passed! No blocking issues found. This PR is approved pending successful CI checks.'
});

View File

@@ -0,0 +1,132 @@
name: Check for Merge Conflicts
on:
pull_request:
types: [opened, synchronize, reopened]
# Also run when the base branch is updated
push:
branches:
- main
- master
jobs:
check-conflicts:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch base branch
run: |
git fetch origin ${{ github.base_ref || github.event.repository.default_branch }}
- name: Check for merge conflicts
id: conflict-check
run: |
# Determine the base branch
BASE_BRANCH="${{ github.base_ref }}"
if [ -z "$BASE_BRANCH" ]; then
BASE_BRANCH="${{ github.event.repository.default_branch }}"
fi
echo "Checking for conflicts with origin/$BASE_BRANCH"
# Try to merge the base branch to see if there are conflicts
if git merge-tree $(git merge-base HEAD origin/$BASE_BRANCH) origin/$BASE_BRANCH HEAD | grep -q "^<<<<<"; then
echo "has_conflicts=true" >> $GITHUB_OUTPUT
echo "✗ Merge conflicts detected!"
else
echo "has_conflicts=false" >> $GITHUB_OUTPUT
echo "✓ No merge conflicts detected"
fi
- name: Comment on PR if conflicts exist
if: steps.conflict-check.outputs.has_conflicts == 'true' && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const comment = `## ⚠️ Merge Conflicts Detected
@copilot This pull request has merge conflicts that need to be resolved.
**Please resolve the conflicts by:**
1. Merging the latest changes from the base branch
2. Resolving any conflicting files
3. Pushing the updated changes
---
*This is an automated message from the merge conflict checker.*`;
// Check if we already commented
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Merge Conflicts Detected')
);
if (botComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: comment
});
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}
- name: Add label if conflicts exist
if: steps.conflict-check.outputs.has_conflicts == 'true' && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['merge-conflict']
});
} catch (error) {
console.log('Label might not exist yet, skipping...');
}
- name: Remove label if no conflicts
if: steps.conflict-check.outputs.has_conflicts == 'false' && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'merge-conflict'
});
} catch (error) {
console.log('Label does not exist or is not applied, skipping...');
}
- name: Fail if conflicts exist
if: steps.conflict-check.outputs.has_conflicts == 'true'
run: |
echo "❌ This PR has merge conflicts and cannot be merged."
exit 1

193
.github/workflows/pr/pr-management.yml vendored Normal file
View File

@@ -0,0 +1,193 @@
name: PR Labeling and Management
on:
pull_request:
types: [opened, synchronize, reopened, labeled, unlabeled]
permissions:
contents: read
pull-requests: write
issues: write
jobs:
label-pr:
name: Auto-Label Pull Request
runs-on: ubuntu-latest
if: github.event.action == 'opened' || github.event.action == 'synchronize'
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Analyze PR and add labels
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
// Get PR files
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
});
let labels = [];
// Analyze file changes
const fileTypes = {
workflows: files.some(f => f.filename.includes('.github/workflows')),
tests: files.some(f => f.filename.includes('test') || f.filename.includes('spec') || f.filename.includes('e2e')),
docs: files.some(f => f.filename.includes('README') || f.filename.includes('.md') || f.filename.includes('docs/')),
components: files.some(f => f.filename.includes('components/') || f.filename.includes('.tsx')),
styles: files.some(f => f.filename.includes('.css') || f.filename.includes('style')),
config: files.some(f => f.filename.match(/\.(json|yml|yaml|config\.(js|ts))$/)),
dependencies: files.some(f => f.filename === 'package.json' || f.filename === 'package-lock.json'),
};
if (fileTypes.workflows) labels.push('workflows');
if (fileTypes.tests) labels.push('tests');
if (fileTypes.docs) labels.push('documentation');
if (fileTypes.components) labels.push('ui');
if (fileTypes.styles) labels.push('styling');
if (fileTypes.config) labels.push('configuration');
if (fileTypes.dependencies) labels.push('dependencies');
// Size labels
const totalChanges = files.reduce((sum, f) => sum + f.additions + f.deletions, 0);
if (totalChanges < 50) {
labels.push('size: small');
} else if (totalChanges < 200) {
labels.push('size: medium');
} else {
labels.push('size: large');
}
// Check PR title for type
const title = pr.title.toLowerCase();
if (title.match(/^fix|bug/)) labels.push('bug');
if (title.match(/^feat|feature|add/)) labels.push('enhancement');
if (title.match(/^refactor/)) labels.push('refactor');
if (title.match(/^docs/)) labels.push('documentation');
if (title.match(/^test/)) labels.push('tests');
if (title.match(/^chore/)) labels.push('chore');
// Add labels
if (labels.length > 0) {
try {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: labels
});
} catch (e) {
console.log('Some labels may not exist:', e.message);
}
}
check-pr-description:
name: Check PR Description
runs-on: ubuntu-latest
if: github.event.action == 'opened'
steps:
- name: Validate PR description
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const body = pr.body || '';
let issues = [];
// Check if description is too short
if (body.length < 50) {
issues.push('PR description is too short. Please provide more details about the changes.');
}
// Check if description links to an issue
if (!body.match(/#\d+|https:\/\/github\.com/)) {
issues.push('Consider linking to a related issue using #issue_number');
}
// Check for test information
if (body.toLowerCase().includes('test') === false &&
!pr.labels.some(l => l.name === 'documentation')) {
issues.push('Please mention how these changes were tested.');
}
if (issues.length > 0) {
const issueList = issues.map(i => '- [ ] ' + i).join('\n');
const comment = [
'## \uD83D\uDCCB PR Description Checklist',
'',
'The following items could improve this PR:',
'',
issueList,
'',
'**Good PR descriptions include:**',
'- What changes were made and why',
'- How to test the changes',
'- Any breaking changes or special considerations',
'- Links to related issues',
'- Screenshots (for UI changes)',
'',
'This is a friendly reminder to help maintain code quality! \uD83D\uDE0A'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: comment
});
}
link-related-issues:
name: Link Related Issues
runs-on: ubuntu-latest
if: github.event.action == 'opened'
steps:
- name: Find and link related issues
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const body = pr.body || '';
const title = pr.title;
// Extract issue numbers from PR body
const issueNumbers = [...body.matchAll(/#(\d+)/g)].map(m => m[1]);
if (issueNumbers.length > 0) {
const relatedList = issueNumbers.map(n => '#' + n).join(', ');
const comment = [
'\uD83D\uDD17 **Related Issues**',
'',
'This PR is related to: ' + relatedList,
'',
'These issues will be automatically closed when this PR is merged.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: comment
});
// Add comment to related issues
for (const issueNum of issueNumbers) {
try {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: parseInt(issueNum),
body: '\uD83D\uDD17 Pull request #' + pr.number + ' has been created to address this issue.'
});
} catch (e) {
console.log('Could not comment on issue #' + issueNum);
}
}
}

218
.github/workflows/quality/planning.yml vendored Normal file
View File

@@ -0,0 +1,218 @@
name: Planning & Design
on:
issues:
types: [opened, labeled]
permissions:
contents: read
issues: write
jobs:
architecture-review:
name: Architecture & Design Review
runs-on: ubuntu-latest
if: |
github.event.action == 'labeled' &&
(github.event.label.name == 'enhancement' || github.event.label.name == 'feature-request')
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Review against architecture principles
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const title = issue.title;
const body = issue.body || '';
let suggestions = [];
let questions = [];
// Check if feature aligns with declarative approach
if (body.toLowerCase().includes('component') && !body.toLowerCase().includes('json')) {
suggestions.push('💡 Consider implementing this as a **declarative component** using JSON configuration and Lua scripts instead of a TypeScript file.');
}
// Check if database schema is mentioned
if (!body.toLowerCase().includes('database') && !body.toLowerCase().includes('schema')) {
questions.push('🤔 Will this feature require database schema changes? Consider adding Prisma schema details.');
}
// Check if package structure is considered
if (body.toLowerCase().includes('new') && !body.toLowerCase().includes('package')) {
suggestions.push('📦 This might be a good candidate for a **package-based implementation** with isolated seed data.');
}
// Check for multi-tenant considerations
if (!body.toLowerCase().includes('tenant') && !body.toLowerCase().includes('supergod')) {
questions.push('🏢 How should this feature work across different **tenants**? Should it be tenant-specific or global?');
}
// Check for permission levels
if (!body.toLowerCase().match(/level [1-5]|user|admin|god|supergod/)) {
questions.push('🔐 Which **permission levels** should have access to this feature? (user/admin/god/supergod)');
}
// Check for Lua consideration
if (body.toLowerCase().includes('logic') && !body.toLowerCase().includes('lua')) {
suggestions.push('🌙 Consider implementing business logic in **Lua scripts** for better flexibility and sandboxing.');
}
let comment = `## 🏗️ Architecture Review\n\n`;
comment += `Thank you for proposing this enhancement! Here's an architectural review:\n\n`;
if (suggestions.length > 0) {
comment += `### 💡 Architectural Suggestions\n\n`;
suggestions.forEach(s => comment += `${s}\n\n`);
}
if (questions.length > 0) {
comment += `### 🤔 Questions to Consider\n\n`;
questions.forEach(q => comment += `${q}\n\n`);
}
comment += `### ✅ Design Checklist\n\n`;
comment += `- [ ] Database schema changes identified\n`;
comment += `- [ ] Package structure planned (if applicable)\n`;
comment += `- [ ] Multi-tenant implications considered\n`;
comment += `- [ ] Permission levels defined\n`;
comment += `- [ ] Declarative approach preferred over imperative\n`;
comment += `- [ ] Component size kept under 150 LOC\n`;
comment += `- [ ] Security implications reviewed\n`;
comment += `- [ ] Testing strategy outlined\n\n`;
comment += `---\n`;
comment += `**@copilot** can help implement this feature following these architectural principles.\n\n`;
comment += `📖 See [Copilot Instructions](/.github/copilot-instructions.md) for development guidelines.`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});
prd-check:
name: Check PRD Alignment
runs-on: ubuntu-latest
if: github.event.action == 'labeled' && github.event.label.name == 'enhancement'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Check PRD for similar features
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const issue = context.payload.issue;
try {
const prd = fs.readFileSync('docs/getting-started/PRD.md', 'utf8');
// Extract key terms from issue
const issueText = (issue.title + ' ' + issue.body).toLowerCase();
const keywords = ['level', 'god', 'tenant', 'package', 'component', 'workflow', 'lua', 'declarative'];
const foundKeywords = keywords.filter(k => issueText.includes(k));
let comment = `## 📋 PRD Alignment Check\n\n`;
if (foundKeywords.length > 0) {
comment += `This feature relates to the following PRD concepts: **${foundKeywords.join(', ')}**\n\n`;
comment += `Please review [docs/getting-started/PRD.md](/docs/getting-started/PRD.md) to ensure alignment with the project mission and existing features.\n\n`;
}
comment += `### 🎯 Mission Statement\n\n`;
comment += `MetaBuilder aims to be a "fully declarative, procedurally-generated multi-tenant application platform where 95% of functionality is defined through JSON and Lua."\n\n`;
comment += `Does this feature support that mission? If so, how?\n\n`;
comment += `---\n`;
comment += `**@copilot** Review the PRD and suggest implementation approach.`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});
} catch (e) {
console.log('Could not read PRD.md:', e.message);
}
suggest-implementation:
name: Suggest Implementation Approach
runs-on: ubuntu-latest
if: |
github.event.action == 'labeled' &&
github.event.label.name == 'ready-to-implement'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Generate implementation suggestion
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
let comment = `## 🛠️ Implementation Guidance\n\n`;
comment += `This issue is ready for implementation! Here's a suggested approach:\n\n`;
comment += `### 📝 Step-by-Step Plan\n\n`;
comment += `1. **Planning Phase**\n`;
comment += ` - [ ] Review PRD.md and update if needed\n`;
comment += ` - [ ] Check existing package structure\n`;
comment += ` - [ ] Design database schema changes (if any)\n`;
comment += ` - [ ] Sketch component hierarchy\n\n`;
comment += `2. **Database Phase**\n`;
comment += ` - [ ] Update \`prisma/schema.prisma\`\n`;
comment += ` - [ ] Run \`bun run db:generate\`\n`;
comment += ` - [ ] Create or update seed data\n`;
comment += ` - [ ] Test database operations\n\n`;
comment += `3. **Implementation Phase**\n`;
comment += ` - [ ] Create package structure (if new package)\n`;
comment += ` - [ ] Build generic renderers (prefer over specific components)\n`;
comment += ` - [ ] Add Lua scripts for business logic\n`;
comment += ` - [ ] Wire up UI components\n`;
comment += ` - [ ] Ensure components are <150 LOC\n\n`;
comment += `4. **Testing Phase**\n`;
comment += ` - [ ] Run \`bun run lint\` and fix issues\n`;
comment += ` - [ ] Add E2E tests in \`e2e/\` directory\n`;
comment += ` - [ ] Test at all permission levels\n`;
comment += ` - [ ] Verify multi-tenant isolation\n`;
comment += ` - [ ] Test package import/export\n\n`;
comment += `5. **Documentation Phase**\n`;
comment += ` - [ ] Update PRD.md with feature details\n`;
comment += ` - [ ] Document Lua APIs if new\n`;
comment += ` - [ ] Add usage examples\n`;
comment += ` - [ ] Update workflow docs if needed\n\n`;
comment += `### 🤖 Copilot Assistance\n\n`;
comment += `**@copilot** can help with:\n`;
comment += `- Generating Prisma schema definitions\n`;
comment += `- Creating seed data JSON structures\n`;
comment += `- Writing Lua script templates\n`;
comment += `- Building generic component renderers\n`;
comment += `- Writing E2E tests\n\n`;
comment += `### 🔗 Useful Resources\n\n`;
comment += `- [Copilot Instructions](/.github/copilot-instructions.md)\n`;
comment += `- [PRD](/.github/../PRD.md)\n`;
comment += `- [Workflow Testing](/.github/workflows/README.md)\n`;
comment += `- [Package Structure](/packages/)\n\n`;
comment += `Ready to start? Create a branch: \`feature/issue-${issue.number}\``;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment
});

View File

@@ -0,0 +1,666 @@
name: Comprehensive Quality Metrics
on:
pull_request:
branches: [ main, master, develop ]
push:
branches: [ main, master ]
workflow_dispatch:
concurrency:
group: quality-${{ github.ref }}
cancel-in-progress: true
jobs:
# ============================================================================
# CODE QUALITY METRICS
# ============================================================================
code-quality:
name: Code Quality Analysis
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
# Cyclomatic Complexity
- name: Check code complexity
id: complexity
run: |
bun install --dev --no-save ts-morph @swc/core
bunx tsx ../../tools/check-code-complexity.ts > complexity-report.json
cat complexity-report.json
continue-on-error: true
# Function metrics
- name: Analyze function metrics
id: metrics
run: bunx tsx ../../tools/analyze-function-metrics.ts > function-metrics.json
continue-on-error: true
# Maintainability Index
- name: Calculate maintainability index
id: maintainability
run: bunx tsx ../../tools/check-maintainability.ts > maintainability-report.json
continue-on-error: true
- name: Detect stub implementations
id: stub-detection
run: bunx tsx ../../tools/detect-stub-implementations.ts > stub-report.json
continue-on-error: true
- name: Upload quality reports
uses: actions/upload-artifact@v4
if: always()
with:
name: code-quality-reports
path: |
frontends/nextjs/complexity-report.json
frontends/nextjs/function-metrics.json
frontends/nextjs/maintainability-report.json
frontends/nextjs/stub-report.json
retention-days: 30
# ============================================================================
# TEST COVERAGE METRICS
# ============================================================================
coverage-metrics:
name: Test Coverage Analysis
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Run tests with coverage
run: bun run test:unit:coverage
env:
DATABASE_URL: file:./dev.db
continue-on-error: true
- name: Generate coverage report
run: bun run test:coverage:report
continue-on-error: true
- name: Check function test coverage
id: function-coverage
run: bun run test:check-functions > function-coverage.txt 2>&1
continue-on-error: true
- name: Extract coverage metrics
id: coverage-extract
run: bunx tsx ../../tools/extract-coverage-metrics.ts
continue-on-error: true
- name: Upload coverage artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: coverage-reports
path: |
frontends/nextjs/coverage/
frontends/nextjs/FUNCTION_TEST_COVERAGE.md
frontends/nextjs/function-coverage.txt
frontends/nextjs/coverage-metrics.json
retention-days: 30
# ============================================================================
# SECURITY SCANNING
# ============================================================================
security-scan:
name: Security Vulnerability Scan
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
permissions:
contents: read
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
# Npm audit for dependencies
- name: NPM Security Audit
id: npm-audit
run: |
bun audit --json > npm-audit.json || true
bunx tsx ../../tools/parse-npm-audit.ts
continue-on-error: true
# Check for security anti-patterns
- name: Scan for security issues
id: security-scan
run: bunx tsx ../../tools/security-scanner.ts > security-report.json
continue-on-error: true
# OWASP Dependency Check (if configured)
- name: Run dependency check
uses: dependency-check/Dependency-Check_Action@1e54355a8b4c8abaa8cc7d0b70aa655a3bb15a6c # main
with:
path: '.'
format: 'JSON'
args: >
--scan .
--exclude node_modules
--exclude build
--exclude .git
--exclude dbal/production/build
continue-on-error: true
- name: Upload security reports
uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: |
frontends/nextjs/npm-audit.json
frontends/nextjs/security-report.json
dependency-check-report.json
retention-days: 30
# ============================================================================
# DOCUMENTATION QUALITY
# ============================================================================
documentation-quality:
name: Documentation Coverage & Quality
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Check JSDoc coverage
id: jsdoc
run: bunx tsx ../../tools/check-jsdoc-coverage.ts > jsdoc-report.json
continue-on-error: true
- name: Validate README files
id: readme
run: bunx tsx ../../tools/validate-readme-quality.ts > readme-report.json
continue-on-error: true
- name: Validate markdown links
id: markdown-links
run: bunx tsx ../../tools/validate-markdown-links.ts > markdown-links-report.json
continue-on-error: true
- name: Check API documentation
id: api-docs
run: bunx tsx ../../tools/validate-api-docs.ts > api-docs-report.json
continue-on-error: true
- name: Verify code examples
id: code-examples
run: bunx tsx ../../tools/validate-code-examples.ts > code-examples-report.json
continue-on-error: true
- name: Upload documentation reports
uses: actions/upload-artifact@v4
if: always()
with:
name: documentation-reports
path: |
frontends/nextjs/jsdoc-report.json
frontends/nextjs/readme-report.json
frontends/nextjs/markdown-links-report.json
frontends/nextjs/api-docs-report.json
frontends/nextjs/code-examples-report.json
retention-days: 30
# ============================================================================
# PERFORMANCE METRICS
# ============================================================================
performance-metrics:
name: Performance Analysis
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: Build application
run: bun run build
env:
DATABASE_URL: file:./dev.db
- name: Analyze bundle size
id: bundle
run: bunx tsx ../../tools/analyze-bundle-size.ts > bundle-analysis.json
continue-on-error: true
- name: Check performance budget
id: perf-budget
run: bunx tsx ../../tools/check-performance-budget.ts > performance-budget.json
continue-on-error: true
- name: Lighthouse audit
id: lighthouse
run: bunx tsx ../../tools/run-lighthouse-audit.ts > lighthouse-report.json
continue-on-error: true
- name: Analyze render performance
id: render-perf
run: bunx tsx ../../tools/analyze-render-performance.ts > render-performance.json
continue-on-error: true
- name: Upload performance reports
uses: actions/upload-artifact@v4
if: always()
with:
name: performance-reports
path: |
frontends/nextjs/bundle-analysis.json
frontends/nextjs/performance-budget.json
frontends/nextjs/lighthouse-report.json
frontends/nextjs/render-performance.json
retention-days: 30
# ============================================================================
# SIZE & STRUCTURE METRICS
# ============================================================================
size-metrics:
name: File Size & Architecture Analysis
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Check source file sizes
id: file-sizes
run: bunx tsx ../../tools/check-file-sizes.ts > file-sizes-report.json
continue-on-error: true
- name: Analyze directory structure
id: dir-structure
run: bunx tsx ../../tools/analyze-directory-structure.ts > directory-structure.json
continue-on-error: true
- name: Check for code duplication
id: duplication
run: bunx tsx ../../tools/detect-code-duplication.ts > duplication-report.json
continue-on-error: true
- name: Analyze import chains
id: imports
run: bunx tsx ../../tools/analyze-import-chains.ts > import-analysis.json
continue-on-error: true
- name: Upload size reports
uses: actions/upload-artifact@v4
if: always()
with:
name: size-reports
path: |
frontends/nextjs/file-sizes-report.json
frontends/nextjs/directory-structure.json
frontends/nextjs/duplication-report.json
frontends/nextjs/import-analysis.json
retention-days: 30
# ============================================================================
# DEPENDENCY ANALYSIS
# ============================================================================
dependency-analysis:
name: Dependency Health Check
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Check outdated dependencies
id: outdated
run: bun outdated --json > outdated-deps.json || true
continue-on-error: true
- name: License compliance check
id: licenses
run: bunx tsx ../../tools/check-license-compliance.ts > license-report.json
continue-on-error: true
- name: Analyze dependency tree
id: tree
run: bunx tsx ../../tools/analyze-dependency-tree.ts > dependency-tree.json
continue-on-error: true
- name: Check for circular dependencies
id: circular
run: bunx tsx ../../tools/detect-circular-dependencies.ts > circular-deps.json
continue-on-error: true
- name: Upload dependency reports
uses: actions/upload-artifact@v4
if: always()
with:
name: dependency-reports
path: |
frontends/nextjs/outdated-deps.json
frontends/nextjs/license-report.json
frontends/nextjs/dependency-tree.json
frontends/nextjs/circular-deps.json
retention-days: 30
# ============================================================================
# TYPE SAFETY & LINTING
# ============================================================================
type-and-lint-metrics:
name: Type Safety & Code Style Metrics
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Generate Prisma Client
run: bun run db:generate
env:
DATABASE_URL: file:./dev.db
- name: TypeScript strict check
id: ts-strict
run: bunx tsx ../../tools/check-typescript-strict.ts > ts-strict-report.json
continue-on-error: true
- name: ESLint detailed report
id: eslint
run: |
bunx eslint . --format json > eslint-report.json || true
bunx tsx ../../tools/parse-eslint-report.ts
continue-on-error: true
- name: Check for @ts-ignore usage
id: ts-ignore
run: bunx tsx ../../tools/find-ts-ignores.ts > ts-ignore-report.json
continue-on-error: true
- name: Check for any types
id: any-types
run: bunx tsx ../../tools/find-any-types.ts > any-types-report.json
continue-on-error: true
- name: Upload type reports
uses: actions/upload-artifact@v4
if: always()
with:
name: type-reports
path: |
frontends/nextjs/ts-strict-report.json
frontends/nextjs/eslint-report.json
frontends/nextjs/ts-ignore-report.json
frontends/nextjs/any-types-report.json
retention-days: 30
# ============================================================================
# QUALITY SUMMARY & REPORTING
# ============================================================================
quality-summary:
name: Quality Metrics Summary
runs-on: ubuntu-latest
needs: [
code-quality,
coverage-metrics,
security-scan,
documentation-quality,
performance-metrics,
size-metrics,
dependency-analysis,
type-and-lint-metrics
]
if: always()
defaults:
run:
working-directory: frontends/nextjs
permissions:
checks: write
pull-requests: write
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Download all reports
uses: actions/download-artifact@v4
with:
path: quality-reports/
- name: Generate quality summary
id: summary
run: bunx tsx ../../tools/generate-quality-summary.ts > quality-summary.md
continue-on-error: true
- name: Post summary as PR comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
let summaryContent = '';
const summaryPath = 'frontends/nextjs/quality-summary.md';
if (fs.existsSync(summaryPath)) {
summaryContent = fs.readFileSync(summaryPath, 'utf8');
}
const comment = `## 📊 Quality Metrics Report\n\n${summaryContent}\n\n<details><summary>📁 Full Reports (click to expand)</summary>\n\nAll detailed reports are available as build artifacts.\n</details>`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
- name: Create check run with summary
uses: actions/github-script@v7
if: github.event_name == 'pull_request'
with:
script: |
const fs = require('fs');
const summaryPath = 'frontends/nextjs/quality-summary.md';
const summary = fs.existsSync(summaryPath)
? fs.readFileSync(summaryPath, 'utf8')
: 'Quality metrics report generated.';
github.rest.checks.create({
owner: context.repo.owner,
repo: context.repo.repo,
name: 'Quality Metrics',
head_sha: context.payload.pull_request.head.sha,
status: 'completed',
conclusion: 'success',
summary: 'All quality metrics collected',
text: summary
});

View File

@@ -0,0 +1,92 @@
name: Code Size Limits
on:
pull_request:
paths:
- 'frontends/nextjs/src/**/*.{ts,tsx,js,jsx}'
- 'tools/enforce-size-limits.ts'
- '.github/workflows/size-limits.yml'
push:
branches:
- main
paths:
- 'frontends/nextjs/src/**/*.{ts,tsx,js,jsx}'
jobs:
size-limits:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontends/nextjs
steps:
- uses: actions/checkout@v6
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: '1.3.4'
- name: Cache Bun dependencies
uses: actions/cache@v4
with:
key: bun-deps-${{ runner.os }}-${{ hashFiles('bun.lock') }}
path: |
frontends/nextjs/node_modules
~/.bun
restore-keys: bun-deps-${{ runner.os }}-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Check code size limits
run: bunx tsx ../../tools/enforce-size-limits.ts
- name: Upload report
if: always()
uses: actions/upload-artifact@v4
with:
name: size-limits-report
path: frontends/nextjs/size-limits-report.json
retention-days: 7
- name: Comment on PR
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = JSON.parse(fs.readFileSync('frontends/nextjs/size-limits-report.json', 'utf8'));
let comment = '## 📏 Code Size Limits\n\n';
if (report.errors === 0 && report.warnings === 0) {
comment += '✅ All files pass size limits!';
} else {
if (report.errors > 0) {
comment += `### ❌ Errors (${report.errors})\n`;
report.violations
.filter(v => v.severity === 'error')
.forEach(v => {
comment += `- **${v.file}**: ${v.metric} (${v.current} / ${v.limit})\n`;
});
}
if (report.warnings > 0) {
comment += `\n### ⚠️ Warnings (${report.warnings})\n`;
report.violations
.filter(v => v.severity === 'warning')
.forEach(v => {
comment += `- **${v.file}**: ${v.metric} (${v.current} / ${v.limit})\n`;
});
}
comment += '\n[See refactoring guide →](../blob/main/docs/REFACTORING_ENFORCEMENT_GUIDE.md)';
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});

162
.github/workflows/todo-to-issues.yml vendored Normal file
View File

@@ -0,0 +1,162 @@
name: TODO to Issues Sync
# This workflow can be triggered manually to convert TODO items to GitHub issues
# or can be run on a schedule to keep issues in sync with TODO files
on:
workflow_dispatch:
inputs:
mode:
description: 'Execution mode'
required: true
type: choice
options:
- dry-run
- export-json
- create-issues
default: 'dry-run'
filter_priority:
description: 'Filter by priority (leave empty for all)'
required: false
type: choice
options:
- ''
- critical
- high
- medium
- low
filter_label:
description: 'Filter by label (e.g., security, frontend)'
required: false
type: string
exclude_checklist:
description: 'Exclude checklist items'
required: false
type: boolean
default: true
limit:
description: 'Limit number of issues (0 for no limit)'
required: false
type: number
default: 0
# Uncomment to run on a schedule (e.g., weekly)
# schedule:
# - cron: '0 0 * * 0' # Every Sunday at midnight
jobs:
convert-todos:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install GitHub CLI
run: |
type -p curl >/dev/null || (sudo apt update && sudo apt install curl -y)
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y
- name: Authenticate GitHub CLI
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "$GH_TOKEN" | gh auth login --with-token
gh auth status
- name: Build command arguments
id: args
run: |
ARGS=""
# Add mode
if [ "${{ inputs.mode }}" = "dry-run" ]; then
ARGS="$ARGS --dry-run"
elif [ "${{ inputs.mode }}" = "export-json" ]; then
ARGS="$ARGS --output todos-export.json"
elif [ "${{ inputs.mode }}" = "create-issues" ]; then
ARGS="$ARGS --create"
fi
# Add filters
if [ -n "${{ inputs.filter_priority }}" ]; then
ARGS="$ARGS --filter-priority ${{ inputs.filter_priority }}"
fi
if [ -n "${{ inputs.filter_label }}" ]; then
ARGS="$ARGS --filter-label ${{ inputs.filter_label }}"
fi
if [ "${{ inputs.exclude_checklist }}" = "true" ]; then
ARGS="$ARGS --exclude-checklist"
fi
# Add limit if specified
if [ "${{ inputs.limit }}" != "0" ]; then
ARGS="$ARGS --limit ${{ inputs.limit }}"
fi
echo "args=$ARGS" >> $GITHUB_OUTPUT
echo "Command arguments: $ARGS"
- name: Run populate-kanban script
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
python3 tools/project-management/populate-kanban.py ${{ steps.args.outputs.args }}
- name: Upload JSON export (if applicable)
if: inputs.mode == 'export-json'
uses: actions/upload-artifact@v4
with:
name: todos-export
path: todos-export.json
retention-days: 30
- name: Create summary
if: always()
run: |
echo "## TODO to Issues Conversion" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Mode:** ${{ inputs.mode }}" >> $GITHUB_STEP_SUMMARY
if [ -n "${{ inputs.filter_priority }}" ]; then
echo "**Priority Filter:** ${{ inputs.filter_priority }}" >> $GITHUB_STEP_SUMMARY
fi
if [ -n "${{ inputs.filter_label }}" ]; then
echo "**Label Filter:** ${{ inputs.filter_label }}" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ inputs.exclude_checklist }}" = "true" ]; then
echo "**Checklist Items:** Excluded" >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ inputs.limit }}" != "0" ]; then
echo "**Limit:** ${{ inputs.limit }} items" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ inputs.mode }}" = "export-json" ]; then
echo "✅ JSON export created successfully" >> $GITHUB_STEP_SUMMARY
echo "Download the artifact from the workflow run page" >> $GITHUB_STEP_SUMMARY
elif [ "${{ inputs.mode }}" = "create-issues" ]; then
echo "✅ GitHub issues created successfully" >> $GITHUB_STEP_SUMMARY
echo "View issues: https://github.com/${{ github.repository }}/issues" >> $GITHUB_STEP_SUMMARY
else
echo " Dry run completed - no issues created" >> $GITHUB_STEP_SUMMARY
fi

198
.github/workflows/triage.yml vendored Normal file
View File

@@ -0,0 +1,198 @@
name: Issue and PR Triage
on:
issues:
types: [opened, edited, reopened]
pull_request:
types: [opened, reopened, synchronize, edited]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
triage-issue:
name: Triage Issues
if: github.event_name == 'issues'
runs-on: ubuntu-latest
steps:
- name: Categorize and label issue
uses: actions/github-script@v7
with:
script: |
const issue = context.payload.issue;
const title = (issue.title || '').toLowerCase();
const body = (issue.body || '').toLowerCase();
const text = `${title}\n${body}`;
const labels = new Set();
const missing = [];
const typeMatchers = [
{ regex: /bug|error|crash|broken|fail/, label: 'bug' },
{ regex: /feature|enhancement|add|new|implement/, label: 'enhancement' },
{ regex: /document|readme|docs|guide/, label: 'documentation' },
{ regex: /test|testing|spec|e2e/, label: 'testing' },
{ regex: /security|vulnerability|exploit|xss|sql/, label: 'security' },
{ regex: /performance|slow|optimize|speed/, label: 'performance' },
];
for (const match of typeMatchers) {
if (text.match(match.regex)) {
labels.add(match.label);
}
}
const areaMatchers = [
{ regex: /frontend|react|next|ui|component|browser/, label: 'area: frontend' },
{ regex: /api|backend|service|server/, label: 'area: backend' },
{ regex: /database|prisma|schema|sql/, label: 'area: database' },
{ regex: /workflow|github actions|ci|pipeline/, label: 'area: workflows' },
{ regex: /docs|readme|guide/, label: 'area: documentation' },
];
for (const match of areaMatchers) {
if (text.match(match.regex)) {
labels.add(match.label);
}
}
if (text.match(/critical|urgent|asap|blocker/)) {
labels.add('priority: high');
} else if (text.match(/minor|low|nice to have/)) {
labels.add('priority: low');
} else {
labels.add('priority: medium');
}
if (text.match(/beginner|easy|simple|starter/) || labels.size <= 2) {
labels.add('good first issue');
}
const reproductionHints = ['steps to reproduce', 'expected', 'actual'];
for (const hint of reproductionHints) {
if (!body.includes(hint)) {
missing.push(hint);
}
}
const supportInfo = body.includes('version') || body.match(/v\d+\.\d+/);
if (!supportInfo) {
missing.push('version information');
}
if (labels.size > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: Array.from(labels),
}).catch(e => console.log('Some labels may not exist:', e.message));
}
const checklist = missing.map(item => `- [ ] Add ${item}`).join('\n') || '- [x] Description includes key details.';
const summary = Array.from(labels).map(l => `- ${l}`).join('\n') || '- No labels inferred yet.';
const comment = [
'👋 Thanks for reporting an issue! I ran a quick triage:',
'',
'**Proposed labels:**',
summary,
'',
'**Missing details:**',
checklist,
'',
'Adding the missing details will help reviewers respond faster. If the proposed labels look wrong, feel free to update them.',
'',
'@copilot Please review this triage and refine labels or request any additional context needed—no Codex webhooks involved.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: comment,
});
triage-pr:
name: Triage Pull Requests
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Analyze PR files and label
uses: actions/github-script@v7
with:
script: |
const pr = context.payload.pull_request;
const { data: files } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pr.number,
});
const labels = new Set();
const fileFlags = {
workflows: files.some(f => f.filename.includes('.github/workflows')),
docs: files.some(f => f.filename.match(/\.(md|mdx)$/) || f.filename.startsWith('docs/')),
frontend: files.some(f => f.filename.includes('frontends/nextjs')),
db: files.some(f => f.filename.includes('prisma/') || f.filename.includes('dbal/')),
tests: files.some(f => f.filename.match(/(test|spec)\.[jt]sx?/)),
};
if (fileFlags.workflows) labels.add('area: workflows');
if (fileFlags.docs) labels.add('area: documentation');
if (fileFlags.frontend) labels.add('area: frontend');
if (fileFlags.db) labels.add('area: database');
if (fileFlags.tests) labels.add('tests');
const totalChanges = files.reduce((sum, f) => sum + f.additions + f.deletions, 0);
const highRiskPaths = files.filter(f => f.filename.includes('.github/workflows') || f.filename.includes('prisma/'));
let riskLabel = 'risk: low';
if (highRiskPaths.length > 0 || totalChanges >= 400) {
riskLabel = 'risk: high';
} else if (totalChanges >= 150) {
riskLabel = 'risk: medium';
}
labels.add(riskLabel);
const missing = [];
const body = (pr.body || '').toLowerCase();
if (!body.includes('test')) missing.push('Test plan');
if (fileFlags.frontend && !body.includes('screenshot')) missing.push('Screenshots for UI changes');
if (!body.match(/#\d+|https:\/\/github\.com/)) missing.push('Linked issue reference');
if (labels.size > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: Array.from(labels),
}).catch(e => console.log('Some labels may not exist:', e.message));
}
const labelSummary = Array.from(labels).map(l => `- ${l}`).join('\n');
const missingList = missing.length ? missing.map(item => `- [ ] ${item}`).join('\n') : '- [x] Description includes required context.';
const comment = [
'🤖 **Automated PR triage**',
'',
'**Proposed labels:**',
labelSummary,
'',
'**Description check:**',
missingList,
'',
'If any labels look incorrect, feel free to adjust them. Closing the missing items will help reviewers move faster.',
'',
'@copilot Please double-check this triage (no Codex webhook) and add any extra labels or questions for the author.'
].join('\n');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: comment,
});

17
.gitignore vendored
View File

@@ -54,22 +54,14 @@ Thumbs.db
.spark-workbench-id
.spark-initial-sha
_codeql_detected_source_root/
.worktrees/
# Database
prisma/dev.db
prisma/dev.db-journal
*.db
*.sqlite
# Re-track project SQLite databases
!docs/docs.db
!txt/reports.db
*.sqlite3
# Generated Prisma schema (produced by dbal/shared/tools/codegen/gen_prisma_schema.js)
dbal/shared/prisma/
# Testing
/test-results/
/playwright-report/
@@ -107,12 +99,3 @@ vite.config.ts.bak*
.cache/
dist-old/
.vscode/claudesync.json
**/package-lock.json
bun.lockb
# CodeQL local databases
.codeql-dbs/
.codeql-db/
/.claude/worktrees
*.tsbuildinfo
# frontends/pastebin/public/pyodide/ # kept in fat repo

View File

@@ -1,37 +0,0 @@
image: node:20-bullseye
stages:
- lint
- test
- build
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .npm/
variables:
NPM_CONFIG_CACHE: $CI_PROJECT_DIR/.npm
before_script:
- npm ci
lint:
stage: lint
script:
- npm run lint
typecheck:
stage: test
script:
- npm run typecheck
unit_tests:
stage: test
script:
- npm test
build:
stage: build
script:
- npm run build

50
.npmrc
View File

@@ -1,50 +0,0 @@
# NPM Configuration for MetaBuilder
# Last Updated: 2026-01-23
# PACKAGE RESOLUTION
# Use the default npm registry
registry=https://registry.npmjs.org/
# AUDIT SETTINGS
# Report security vulnerabilities
audit-level=moderate
# VERSION MATCHING
# Use caret ranges for flexibility (^version)
# This allows minor/patch updates while locking major version
save-prefix=^
# OPTIONAL DEPENDENCIES
# Don't fail if optional dependencies aren't available
ignore-scripts=false
# WORKSPACE SETTINGS
# Enable workspace protocol for monorepo linking
workspaces-update=true
# BUILD SETTINGS
# Use standard npm, not yarn or pnpm
# (This is implicit but documented for clarity)
# PROXY SETTINGS (uncomment if behind corporate proxy)
# http-proxy=http://proxy.example.com:8080
# https-proxy=https://proxy.example.com:8443
# no-proxy=.example.com,localhost,127.0.0.1
# LOCAL NEXUS REGISTRY (uncomment to use patched packages from Nexus)
# Nexus npm-group merges npm-hosted (patched) + npm-proxy (npmjs.org cache)
# Start Nexus: cd deployment && docker compose -f docker-compose.nexus.yml up -d
# Publish patches: cd deployment && ./publish-npm-patches.sh
# registry=http://localhost:8091/repository/npm-group/
# //localhost:8091/repository/npm-hosted/:_auth=YWRtaW46bmV4dXM=
# NODE/NPM VERSION REQUIREMENTS
# These are documented in package.json engines field
# Current: Node 22.22.1, npm 11.11.0
# SCOPED VERDACCIO REGISTRY - @esbuild-kit patched packages
# Local dev: npx verdaccio --config deployment/verdaccio.yaml &
# bash deployment/publish-npm-patches.sh --verdaccio
# CI: started automatically via .github/actions/setup-npm composite action
@esbuild-kit:registry=http://localhost:4873/
//localhost:4873/:_authToken=

View File

@@ -1,47 +0,0 @@
---
name: MetaBuilder Roadmap Implementer
type: knowledge
version: 1.0.0
agent: CodeActAgent
triggers: []
---
Purpose
- Implement features described in ROADMAP.md and README.md.
- Keep both ROADMAP.md and README.md up to date as work progresses.
- Write and maintain Playwright E2E tests and unit tests.
- Follow the existing code style and project conventions.
- Use the existing JSON Schemas; they are mostly correct, do not modify schema definitions unless explicitly required by failing validation.
- Index the repository for quick navigation and make concise implementation notes.
- Align styling to match the old/ directory while using plain SASS files (no CSS-in-JS).
Scope and Guidance
- Source of truth for planned features: ROADMAP.md. Ensure README.md reflects any implemented capabilities or usage changes.
- Respect repository structure: prefer packages/, services/, frontends/, and dbal/ conventions already present. Avoid ad-hoc new folders.
- Testing:
- Unit tests: colocate or follow existing spec/ patterns.
- E2E: use Playwright per playwright.config.ts and the e2e/ folder conventions.
- Ensure new features include adequate test coverage and run locally before committing.
- Code style:
- Run the project linters/formatters defined in package.json scripts.
- Keep TypeScript strictness and fix type warnings instead of suppressing them.
- JSON Schema:
- Validate inputs against existing schemas in schemas/; do not overhaul schemas unless necessary.
- Styles:
- Use plain SASS (.scss) and mirror patterns from old/ to maintain visual continuity.
Operational Steps When Executing
1) Parse ROADMAP.md items and pick an actionable task.
2) Implement minimal code to satisfy the task; keep changes focused.
3) Update README.md and ROADMAP.md checkboxes/status to reflect progress.
4) Add/adjust unit tests and Playwright tests to cover the change.
5) Run lint, typecheck, and tests; fix issues.
6) Commit with a clear message referencing the task.
Notes and Indexing
- Maintain brief notes with references to key files you touched. Prefer adding developer notes to docs/ if appropriate, otherwise keep ephemeral notes out of VCS.
Limitations
- No triggers defined; manual invocation only.
- Does not modify JSON schemas unless validation requires it.

View File

@@ -1,119 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- generic [ref=e6]:
- generic [ref=e7]:
- heading "Navigation" [level=2] [ref=e8]
- generic [ref=e9]:
- button "Expand All" [ref=e10]
- button "Collapse All" [ref=e11]
- generic [ref=e15]:
- generic [ref=e16]:
- button "Overview 1" [ref=e17]:
- img [ref=e18]
- heading "Overview" [level=3] [ref=e20]
- generic [ref=e21]: "1"
- button "Dashboard" [ref=e24]:
- generic [ref=e25]: Dashboard
- generic [ref=e26]:
- button "Development 4" [ref=e27]:
- img [ref=e28]
- heading "Development" [level=3] [ref=e30]
- generic [ref=e31]: "4"
- generic [ref=e32]:
- button "Code Editor" [ref=e34]:
- generic [ref=e35]: Code Editor
- button "Models" [ref=e37]:
- generic [ref=e38]: Models
- button "Components" [ref=e40]:
- generic [ref=e41]: Components
- button "Component Trees" [ref=e43]:
- generic [ref=e44]: Component Trees
- generic [ref=e45]:
- button "Automation 2" [ref=e46]:
- img [ref=e47]
- heading "Automation" [level=3] [ref=e49]
- generic [ref=e50]: "2"
- generic [ref=e51]:
- button "Workflows" [ref=e53]:
- generic [ref=e54]: Workflows
- button "Lambdas" [ref=e56]:
- generic [ref=e57]: Lambdas
- generic [ref=e58]:
- button "Design & Styling 6" [ref=e59]:
- img [ref=e60]
- heading "Design & Styling" [level=3] [ref=e62]
- generic [ref=e63]: "6"
- generic [ref=e64]:
- button "Styling" [ref=e66]:
- generic [ref=e67]: Styling
- button "Sass Styles" [ref=e69]:
- generic [ref=e70]: Sass Styles
- button "Favicon Designer" [ref=e72]:
- generic [ref=e73]: Favicon Designer
- button "Feature Ideas" [ref=e75]:
- generic [ref=e76]: Feature Ideas
- button "Schema Editor" [ref=e78]:
- generic [ref=e79]: Schema Editor
- button "JSON UI" [ref=e81]:
- generic [ref=e82]: JSON UI
- generic [ref=e83]:
- button "Backend 1" [ref=e84]:
- img [ref=e85]
- heading "Backend" [level=3] [ref=e87]
- generic [ref=e88]: "1"
- button "Flask API" [ref=e91]:
- generic [ref=e92]: Flask API
- generic [ref=e93]:
- button "Testing 3" [ref=e94]:
- img [ref=e95]
- heading "Testing" [level=3] [ref=e97]
- generic [ref=e98]: "3"
- generic [ref=e99]:
- button "Playwright" [ref=e101]:
- generic [ref=e102]: Playwright
- button "Storybook" [ref=e104]:
- generic [ref=e105]: Storybook
- button "Unit Tests" [ref=e107]:
- generic [ref=e108]: Unit Tests
- generic [ref=e109]:
- button "Tools & Configuration 6" [ref=e110]:
- img [ref=e111]
- heading "Tools & Configuration" [level=3] [ref=e113]
- generic [ref=e114]: "6"
- generic [ref=e115]:
- button "Error Repair" [ref=e117]:
- generic [ref=e118]: Error Repair
- button "Documentation" [ref=e120]:
- generic [ref=e121]: Documentation
- button "JSON Conversion Showcase" [ref=e123]:
- generic [ref=e124]: JSON Conversion Showcase
- button "Settings" [ref=e126]:
- generic [ref=e127]: Settings
- button "PWA" [ref=e129]:
- generic [ref=e130]: PWA
- button "Features" [ref=e132]:
- generic [ref=e133]: Features
- main [ref=e134]:
- generic [ref=e135]:
- generic [ref=e136]: layers
- generic [ref=e138]:
- generic [ref=e139]:
- heading "Project Dashboard" [level=1] [ref=e140]
- paragraph [ref=e141]: Overview of your CodeForge project
- generic [ref=e142]:
- generic [ref=e143]:
- generic [ref=e145]:
- img [ref=e147]
- text: Project Completeness
- generic [ref=e150]:
- generic [ref=e152]: 30%
- generic [ref=e153]: In Progress
- progressbar [ref=e154]
- paragraph [ref=e156]: Just getting started. Add some components and models.
- generic [ref=e157]:
- generic [ref=e159]: GitHub Build Status
- generic [ref=e161]: "Custom component: GitHubBuildStatus"
- generic [ref=e162]:
- heading "Command Palette" [level=2] [ref=e163]
- paragraph [ref=e164]: Search for a command to run...
- alert [ref=e165]

View File

@@ -1,119 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- generic [ref=e6]:
- generic [ref=e7]:
- heading "Navigation" [level=2] [ref=e8]
- generic [ref=e9]:
- button "Expand All" [ref=e10]
- button "Collapse All" [ref=e11]
- generic [ref=e15]:
- generic [ref=e16]:
- button "Overview 1" [ref=e17]:
- img [ref=e18]
- heading "Overview" [level=3] [ref=e20]
- generic [ref=e21]: "1"
- button "Dashboard" [ref=e24]:
- generic [ref=e25]: Dashboard
- generic [ref=e26]:
- button "Development 4" [ref=e27]:
- img [ref=e28]
- heading "Development" [level=3] [ref=e30]
- generic [ref=e31]: "4"
- generic [ref=e32]:
- button "Code Editor" [ref=e34]:
- generic [ref=e35]: Code Editor
- button "Models" [ref=e37]:
- generic [ref=e38]: Models
- button "Components" [ref=e40]:
- generic [ref=e41]: Components
- button "Component Trees" [ref=e43]:
- generic [ref=e44]: Component Trees
- generic [ref=e45]:
- button "Automation 2" [ref=e46]:
- img [ref=e47]
- heading "Automation" [level=3] [ref=e49]
- generic [ref=e50]: "2"
- generic [ref=e51]:
- button "Workflows" [ref=e53]:
- generic [ref=e54]: Workflows
- button "Lambdas" [ref=e56]:
- generic [ref=e57]: Lambdas
- generic [ref=e58]:
- button "Design & Styling 6" [ref=e59]:
- img [ref=e60]
- heading "Design & Styling" [level=3] [ref=e62]
- generic [ref=e63]: "6"
- generic [ref=e64]:
- button "Styling" [ref=e66]:
- generic [ref=e67]: Styling
- button "Sass Styles" [ref=e69]:
- generic [ref=e70]: Sass Styles
- button "Favicon Designer" [ref=e72]:
- generic [ref=e73]: Favicon Designer
- button "Feature Ideas" [ref=e75]:
- generic [ref=e76]: Feature Ideas
- button "Schema Editor" [ref=e78]:
- generic [ref=e79]: Schema Editor
- button "JSON UI" [ref=e81]:
- generic [ref=e82]: JSON UI
- generic [ref=e83]:
- button "Backend 1" [ref=e84]:
- img [ref=e85]
- heading "Backend" [level=3] [ref=e87]
- generic [ref=e88]: "1"
- button "Flask API" [ref=e91]:
- generic [ref=e92]: Flask API
- generic [ref=e93]:
- button "Testing 3" [ref=e94]:
- img [ref=e95]
- heading "Testing" [level=3] [ref=e97]
- generic [ref=e98]: "3"
- generic [ref=e99]:
- button "Playwright" [ref=e101]:
- generic [ref=e102]: Playwright
- button "Storybook" [ref=e104]:
- generic [ref=e105]: Storybook
- button "Unit Tests" [ref=e107]:
- generic [ref=e108]: Unit Tests
- generic [ref=e109]:
- button "Tools & Configuration 6" [ref=e110]:
- img [ref=e111]
- heading "Tools & Configuration" [level=3] [ref=e113]
- generic [ref=e114]: "6"
- generic [ref=e115]:
- button "Error Repair" [ref=e117]:
- generic [ref=e118]: Error Repair
- button "Documentation" [ref=e120]:
- generic [ref=e121]: Documentation
- button "JSON Conversion Showcase" [ref=e123]:
- generic [ref=e124]: JSON Conversion Showcase
- button "Settings" [ref=e126]:
- generic [ref=e127]: Settings
- button "PWA" [ref=e129]:
- generic [ref=e130]: PWA
- button "Features" [ref=e132]:
- generic [ref=e133]: Features
- main [ref=e134]:
- generic [ref=e135]:
- generic [ref=e136]: layers
- generic [ref=e138]:
- generic [ref=e139]:
- heading "Project Dashboard" [level=1] [ref=e140]
- paragraph [ref=e141]: Overview of your CodeForge project
- generic [ref=e142]:
- generic [ref=e143]:
- generic [ref=e145]:
- img [ref=e147]
- text: Project Completeness
- generic [ref=e150]:
- generic [ref=e152]: 30%
- generic [ref=e153]: In Progress
- progressbar [ref=e154]
- paragraph [ref=e156]: Just getting started. Add some components and models.
- generic [ref=e157]:
- generic [ref=e159]: GitHub Build Status
- generic [ref=e161]: "Custom component: GitHubBuildStatus"
- generic [ref=e162]:
- heading "Command Palette" [level=2] [ref=e163]
- paragraph [ref=e164]: Search for a command to run...
- alert [ref=e165]

View File

@@ -1,7 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e4]:
- heading "404" [level=1] [ref=e5]
- paragraph [ref=e6]: Page not found
- link "Go to CodeForge" [ref=e7] [cursor=pointer]:
- /url: /codegen/
- alert [ref=e8]

View File

@@ -1,25 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- img [ref=e4]
- main [ref=e6]:
- generic [ref=e11]:
- generic [ref=e12]:
- heading "Project Dashboard" [level=1] [ref=e13]
- paragraph [ref=e14]: Overview of your CodeForge project
- generic [ref=e15]:
- generic [ref=e16]:
- generic [ref=e18]:
- img [ref=e20]
- text: Project Completeness
- generic [ref=e23]:
- generic [ref=e24]: 30%
- text: In Progress
- progressbar
- paragraph [ref=e25]: Just getting started. Add some components and models.
- generic [ref=e26]:
- generic [ref=e28]: GitHub Build Status
- generic [ref=e30]: "Custom component: GitHubBuildStatus"
- generic [ref=e32]:
- heading "Command Palette" [level=2] [ref=e33]
- paragraph [ref=e34]: Search for a command to run...
- alert [ref=e35]

View File

@@ -1,25 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- img [ref=e4]
- main [ref=e6]:
- generic [ref=e11]:
- generic [ref=e12]:
- heading "Project Dashboard" [level=1] [ref=e13]
- paragraph [ref=e14]: Overview of your CodeForge project
- generic [ref=e15]:
- generic [ref=e16]:
- generic [ref=e18]:
- img [ref=e20]
- text: Project Completeness
- generic [ref=e23]:
- generic [ref=e24]: 30%
- text: In Progress
- progressbar
- paragraph [ref=e25]: Just getting started. Add some components and models.
- generic [ref=e26]:
- generic [ref=e28]: GitHub Build Status
- generic [ref=e30]: "Custom component: GitHubBuildStatus"
- generic [ref=e32]:
- heading "Command Palette" [level=2] [ref=e33]
- paragraph [ref=e34]: Search for a command to run...
- alert [ref=e35]

View File

@@ -1,156 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [expanded] [ref=e6] [cursor=pointer]:
- generic [ref=e7]: menu
- generic [ref=e8]:
- generic [ref=e9]: code
- heading "CodeForge" [level=1] [ref=e10]
- button "Switch to dark mode" [ref=e12] [cursor=pointer]:
- generic [ref=e13]: dark_mode
- generic [ref=e14]:
- complementary "Navigation sidebar" [ref=e15]:
- paragraph [ref=e17]: Navigation
- navigation "Main navigation" [ref=e18]:
- group "Main" [ref=e19]:
- heading "Main" [level=3] [ref=e20]
- list "Main" [ref=e21]:
- listitem [ref=e22]:
- link "Dashboard" [ref=e23] [cursor=pointer]:
- /url: /codegen
- generic [ref=e24]: dashboard
- generic [ref=e25]: Dashboard
- listitem [ref=e26]:
- link "Code Editor" [ref=e27] [cursor=pointer]:
- /url: /codegen/code
- generic [ref=e28]: code
- generic [ref=e29]: Code Editor
- listitem [ref=e30]:
- link "Components" [ref=e31] [cursor=pointer]:
- /url: /codegen/components
- generic [ref=e32]: widgets
- generic [ref=e33]: Components
- listitem [ref=e34]:
- link "Models" [ref=e35] [cursor=pointer]:
- /url: /codegen/models
- generic [ref=e36]: schema
- generic [ref=e37]: Models
- group "Design" [ref=e38]:
- heading "Design" [level=3] [ref=e39]
- list "Design" [ref=e40]:
- listitem [ref=e41]:
- link "Component Trees" [ref=e42] [cursor=pointer]:
- /url: /codegen/component-trees
- generic [ref=e43]: account_tree
- generic [ref=e44]: Component Trees
- listitem [ref=e45]:
- link "Styling" [ref=e46] [cursor=pointer]:
- /url: /codegen/styling
- generic [ref=e47]: palette
- generic [ref=e48]: Styling
- listitem [ref=e49]:
- link "Sass" [ref=e50] [cursor=pointer]:
- /url: /codegen/sass
- generic [ref=e51]: style
- generic [ref=e52]: Sass
- listitem [ref=e53]:
- link "Atomic Library" [ref=e54] [cursor=pointer]:
- /url: /codegen/atomic-library
- generic [ref=e55]: library_books
- generic [ref=e56]: Atomic Library
- listitem [ref=e57]:
- link "Templates" [ref=e58] [cursor=pointer]:
- /url: /codegen/templates
- generic [ref=e59]: content_copy
- generic [ref=e60]: Templates
- group "Workflows" [ref=e61]:
- heading "Workflows" [level=3] [ref=e62]
- list "Workflows" [ref=e63]:
- listitem [ref=e64]:
- link "Workflows" [ref=e65] [cursor=pointer]:
- /url: /codegen/workflows
- generic [ref=e66]: share
- generic [ref=e67]: Workflows
- listitem [ref=e68]:
- link "Lambdas" [ref=e69] [cursor=pointer]:
- /url: /codegen/lambdas
- generic [ref=e70]: functions
- generic [ref=e71]: Lambdas
- group "Tools" [ref=e72]:
- heading "Tools" [level=3] [ref=e73]
- list "Tools" [ref=e74]:
- listitem [ref=e75]:
- link "JSON UI" [ref=e76] [cursor=pointer]:
- /url: /codegen/json-ui
- generic [ref=e77]: data_object
- generic [ref=e78]: JSON UI
- listitem [ref=e79]:
- link "Schema Editor" [ref=e80] [cursor=pointer]:
- /url: /codegen/schema-editor
- generic [ref=e81]: edit_note
- generic [ref=e82]: Schema Editor
- listitem [ref=e83]:
- link "Data Binding" [ref=e84] [cursor=pointer]:
- /url: /codegen/data-binding
- generic [ref=e85]: link
- generic [ref=e86]: Data Binding
- listitem [ref=e87]:
- link "Flask API" [ref=e88] [cursor=pointer]:
- /url: /codegen/flask
- generic [ref=e89]: api
- generic [ref=e90]: Flask API
- group "Testing" [ref=e91]:
- heading "Testing" [level=3] [ref=e92]
- list "Testing" [ref=e93]:
- listitem [ref=e94]:
- link "Playwright" [ref=e95] [cursor=pointer]:
- /url: /codegen/playwright
- generic [ref=e96]: bug_report
- generic [ref=e97]: Playwright
- listitem [ref=e98]:
- link "Unit Tests" [ref=e99] [cursor=pointer]:
- /url: /codegen/unit-tests
- generic [ref=e100]: science
- generic [ref=e101]: Unit Tests
- listitem [ref=e102]:
- link "Storybook" [ref=e103] [cursor=pointer]:
- /url: /codegen/storybook
- generic [ref=e104]: auto_stories
- generic [ref=e105]: Storybook
- group "System" [ref=e106]:
- heading "System" [level=3] [ref=e107]
- list "System" [ref=e108]:
- listitem [ref=e109]:
- link "Settings" [ref=e110] [cursor=pointer]:
- /url: /codegen/settings
- generic [ref=e111]: settings
- generic [ref=e112]: Settings
- listitem [ref=e113]:
- link "Documentation" [ref=e114] [cursor=pointer]:
- /url: /codegen/docs
- generic [ref=e115]: description
- generic [ref=e116]: Documentation
- listitem [ref=e117]:
- link "Features" [ref=e118] [cursor=pointer]:
- /url: /codegen/features
- generic [ref=e119]: toggle_on
- generic [ref=e120]: Features
- listitem [ref=e121]:
- link "Errors" [ref=e122] [cursor=pointer]:
- /url: /codegen/errors
- generic [ref=e123]: error
- generic [ref=e124]: Errors
- listitem [ref=e125]:
- link "Persistence" [ref=e126] [cursor=pointer]:
- /url: /codegen/persistence
- generic [ref=e127]: storage
- generic [ref=e128]: Persistence
- listitem [ref=e129]:
- link "PWA" [ref=e130] [cursor=pointer]:
- /url: /codegen/pwa
- generic [ref=e131]: install_desktop
- generic [ref=e132]: PWA
- main [ref=e133]:
- paragraph [ref=e137]: Loading projectdashboard...
- alert [ref=e138]

View File

@@ -1,128 +0,0 @@
- generic [active] [ref=e1]:
- alert [ref=e2]
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [ref=e6] [cursor=pointer]:
- img [ref=e7]
- generic [ref=e8]:
- img [ref=e9]
- heading "WorkflowUI" [level=1] [ref=e18]
- generic [ref=e19]:
- button "Notifications" [ref=e21] [cursor=pointer]:
- img [ref=e22]
- generic [ref=e24]: "2"
- button "Switch to dark mode" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e28]:
- complementary "Workflows sidebar" [ref=e29]:
- navigation [ref=e30]:
- generic [ref=e31]:
- heading "Main" [level=3] [ref=e32]
- list "Main navigation" [ref=e33]:
- listitem [ref=e34]:
- link "Dashboard" [ref=e35] [cursor=pointer]:
- /url: /workflowui
- img [ref=e37]
- generic [ref=e39]: Dashboard
- listitem [ref=e40]:
- link "Notifications 2" [ref=e41] [cursor=pointer]:
- /url: /workflowui/notifications
- img [ref=e43]
- generic [ref=e45]: Notifications
- generic [ref=e46]: "2"
- generic [ref=e47]:
- heading "Workflows" [level=3] [ref=e48]
- list "Workflows navigation" [ref=e49]:
- listitem [ref=e50]:
- link "All Workflows" [ref=e51] [cursor=pointer]:
- /url: /workflowui/workflows
- img [ref=e53]
- generic [ref=e55]: All Workflows
- listitem [ref=e56]:
- link "Recent" [ref=e57] [cursor=pointer]:
- /url: /workflowui/workflows/recent
- img [ref=e59]
- generic [ref=e61]: Recent
- listitem [ref=e62]:
- link "Favorites" [ref=e63] [cursor=pointer]:
- /url: /workflowui/workflows/favorites
- img [ref=e65]
- generic [ref=e67]: Favorites
- listitem [ref=e68]:
- link "Templates" [ref=e69] [cursor=pointer]:
- /url: /workflowui/templates
- img [ref=e71]
- generic [ref=e73]: Templates
- generic [ref=e74]:
- heading "System" [level=3] [ref=e75]
- list "System navigation" [ref=e76]:
- listitem [ref=e77]:
- link "Plugins" [ref=e78] [cursor=pointer]:
- /url: /workflowui/plugins
- img [ref=e80]
- generic [ref=e82]: Plugins
- listitem [ref=e83]:
- link "Settings" [ref=e84] [cursor=pointer]:
- /url: /workflowui/settings
- img [ref=e86]
- generic [ref=e88]: Settings
- generic [ref=e89]:
- heading "Help" [level=3] [ref=e90]
- list "Help navigation" [ref=e91]:
- listitem [ref=e92]:
- link "Documentation" [ref=e93] [cursor=pointer]:
- /url: /workflowui/docs
- img [ref=e95]
- generic [ref=e97]: Documentation
- listitem [ref=e98]:
- link "Help & Support" [ref=e99] [cursor=pointer]:
- /url: /workflowui/help
- img [ref=e101]
- generic [ref=e103]: Help & Support
- button "+ New Workflow" [ref=e105] [cursor=pointer]:
- generic [ref=e107]: + New Workflow
- main [ref=e108]:
- generic [ref=e109]:
- generic [ref=e110]:
- generic [ref=e111]:
- img [ref=e113]
- generic [ref=e115]:
- generic [ref=e116]: "23"
- generic [ref=e117]: nodes today
- generic [ref=e118]:
- img [ref=e120]
- generic [ref=e122]:
- generic [ref=e123]: "5"
- generic [ref=e124]: runs today
- generic [ref=e125]:
- img [ref=e127]
- generic [ref=e129]:
- generic [ref=e130]: "1"
- generic [ref=e131]: failed
- generic [ref=e132]:
- img [ref=e134]
- generic [ref=e136]:
- generic [ref=e137]: 1.2h
- generic [ref=e138]: saved today
- generic [ref=e140]:
- generic "First Steps" [ref=e141]:
- img [ref=e142]
- generic "Node Master" [ref=e144]:
- img [ref=e145]
- link "+4 more" [ref=e147] [cursor=pointer]:
- /url: /workflowui/achievements
- generic [ref=e148]:
- generic [ref=e149]:
- heading "Workspaces" [level=1] [ref=e150]
- paragraph [ref=e151]: Organize your projects and workflows
- button "New Workspace" [ref=e152] [cursor=pointer]:
- img [ref=e155]
- generic [ref=e157]: New Workspace
- generic [ref=e158]:
- progressbar [ref=e159]:
- generic [ref=e161]:
- img [ref=e163]
- img [ref=e166]
- img [ref=e169]
- paragraph [ref=e171]: Loading workspaces...

View File

@@ -1,122 +0,0 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- heading "MetaBuilder" [level=1] [ref=e3]
- paragraph [ref=e4]: Development Stack Portal
- generic [ref=e5]: Applications
- generic [ref=e6]:
- link "W WorkflowUI Visual workflow editor with n8n-style DAG canvas, step library, and JSON workflow execution. /workflowui" [ref=e7] [cursor=pointer]:
- /url: /workflowui
- generic [ref=e8]:
- generic [ref=e9]: W
- heading "WorkflowUI" [level=2] [ref=e10]
- paragraph [ref=e11]: Visual workflow editor with n8n-style DAG canvas, step library, and JSON workflow execution.
- generic [ref=e12]: /workflowui
- link "C CodeForge IDE Low-code application builder with Monaco editor, JSON-driven component architecture. /codegen" [ref=e13] [cursor=pointer]:
- /url: /codegen
- generic [ref=e14]:
- generic [ref=e15]: C
- heading "CodeForge IDE" [level=2] [ref=e16]
- paragraph [ref=e17]: Low-code application builder with Monaco editor, JSON-driven component architecture.
- generic [ref=e18]: /codegen
- link "P Pastebin Code snippet sharing with syntax highlighting, expiration, and privacy controls. /pastebin" [ref=e19] [cursor=pointer]:
- /url: /pastebin
- generic [ref=e20]:
- generic [ref=e21]: P
- heading "Pastebin" [level=2] [ref=e22]
- paragraph [ref=e23]: Code snippet sharing with syntax highlighting, expiration, and privacy controls.
- generic [ref=e24]: /pastebin
- link "E Email Client Full-featured email management with IMAP/SMTP, multi-account support, and search. /emailclient" [ref=e25] [cursor=pointer]:
- /url: /emailclient
- generic [ref=e26]:
- generic [ref=e27]: E
- heading "Email Client" [level=2] [ref=e28]
- paragraph [ref=e29]: Full-featured email management with IMAP/SMTP, multi-account support, and search.
- generic [ref=e30]: /emailclient
- link "D Postgres Dashboard PostgreSQL admin dashboard with query editor, table browser, and performance monitoring. /postgres" [ref=e31] [cursor=pointer]:
- /url: /postgres
- generic [ref=e32]:
- generic [ref=e33]: D
- heading "Postgres Dashboard" [level=2] [ref=e34]
- paragraph [ref=e35]: PostgreSQL admin dashboard with query editor, table browser, and performance monitoring.
- generic [ref=e36]: /postgres
- link "3D Exploded Diagrams Interactive 3D exploded diagram viewer with Three.js and JSCAD integration. /diagrams" [ref=e37] [cursor=pointer]:
- /url: /diagrams
- generic [ref=e38]:
- generic [ref=e39]: 3D
- heading "Exploded Diagrams" [level=2] [ref=e40]
- paragraph [ref=e41]: Interactive 3D exploded diagram viewer with Three.js and JSCAD integration.
- generic [ref=e42]: /diagrams
- link "S Storybook Component library preview with interactive props, documentation, and visual testing. /storybook" [ref=e43] [cursor=pointer]:
- /url: /storybook
- generic [ref=e44]:
- generic [ref=e45]: S
- heading "Storybook" [level=2] [ref=e46]
- paragraph [ref=e47]: Component library preview with interactive props, documentation, and visual testing.
- generic [ref=e48]: /storybook
- link "A Frontend App Main Next.js application with Drizzle ORM, i18n, Clerk auth, and DBAL integration. /app" [ref=e49] [cursor=pointer]:
- /url: /app
- generic [ref=e50]:
- generic [ref=e51]: A
- heading "Frontend App" [level=2] [ref=e52]
- paragraph [ref=e53]: Main Next.js application with Drizzle ORM, i18n, Clerk auth, and DBAL integration.
- generic [ref=e54]: /app
- generic [ref=e55]: Backend Services
- generic [ref=e56]:
- link "API DBAL API C++ database abstraction layer with RESTful CRUD, caching, and search. /api" [ref=e57] [cursor=pointer]:
- /url: /api/health
- generic [ref=e58]:
- generic [ref=e59]: API
- heading "DBAL API" [level=2] [ref=e60]
- paragraph [ref=e61]: C++ database abstraction layer with RESTful CRUD, caching, and search.
- generic [ref=e62]: /api
- link "EM Email Service Flask backend for IMAP/SMTP operations, email sync, and Celery task queue. /email-api" [ref=e63] [cursor=pointer]:
- /url: /email-api/health
- generic [ref=e64]:
- generic [ref=e65]: EM
- heading "Email Service" [level=2] [ref=e66]
- paragraph [ref=e67]: Flask backend for IMAP/SMTP operations, email sync, and Celery task queue.
- generic [ref=e68]: /email-api
- link "SM SMTP Relay Twisted SMTP relay dashboard for email testing and debugging. localhost:8025" [ref=e69] [cursor=pointer]:
- /url: http://localhost:8025
- generic [ref=e70]:
- generic [ref=e71]: SM
- heading "SMTP Relay" [level=2] [ref=e72]
- paragraph [ref=e73]: Twisted SMTP relay dashboard for email testing and debugging.
- generic [ref=e74]: localhost:8025
- generic [ref=e75]: Administration
- generic [ref=e76]:
- link "⚙ Database Settings Manage DBAL adapter configuration, switch backends, and test database connections. /portal/settings.html" [ref=e77] [cursor=pointer]:
- /url: /portal/settings.html
- generic [ref=e78]:
- generic [ref=e79]:
- heading "Database Settings" [level=2] [ref=e80]
- paragraph [ref=e81]: Manage DBAL adapter configuration, switch backends, and test database connections.
- generic [ref=e82]: /portal/settings.html
- link "PMA phpMyAdmin MySQL web administration with table browser, SQL editor, import/export, and user management. /phpmyadmin/" [ref=e83] [cursor=pointer]:
- /url: /phpmyadmin/
- generic [ref=e84]:
- generic [ref=e85]: PMA
- heading "phpMyAdmin" [level=2] [ref=e86]
- paragraph [ref=e87]: MySQL web administration with table browser, SQL editor, import/export, and user management.
- generic [ref=e88]: /phpmyadmin/
- link "ME Mongo Express MongoDB web administration with collection browser, document editor, and query interface. /mongo-express/" [ref=e89] [cursor=pointer]:
- /url: /mongo-express/
- generic [ref=e90]:
- generic [ref=e91]: ME
- heading "Mongo Express" [level=2] [ref=e92]
- paragraph [ref=e93]: MongoDB web administration with collection browser, document editor, and query interface.
- generic [ref=e94]: /mongo-express/
- link "RI RedisInsight Redis GUI with key browser, CLI console, memory analysis, and slow log inspection. /redis-insight/" [ref=e95] [cursor=pointer]:
- /url: /redis-insight/
- generic [ref=e96]:
- generic [ref=e97]: RI
- heading "RedisInsight" [level=2] [ref=e98]
- paragraph [ref=e99]: Redis GUI with key browser, CLI console, memory analysis, and slow log inspection.
- generic [ref=e100]: /redis-insight/
- link "KB Kibana Elasticsearch dashboard with Discover, index management, Dev Tools console, and visualizations. /kibana/" [ref=e101] [cursor=pointer]:
- /url: /kibana/
- generic [ref=e102]:
- generic [ref=e103]: KB
- heading "Kibana" [level=2] [ref=e104]
- paragraph [ref=e105]: Elasticsearch dashboard with Discover, index management, Dev Tools console, and visualizations.
- generic [ref=e106]: /kibana/

View File

@@ -1,156 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [expanded] [ref=e6] [cursor=pointer]:
- generic [ref=e7]: menu
- generic [ref=e8]:
- generic [ref=e9]: code
- heading "CodeForge" [level=1] [ref=e10]
- button "Switch to dark mode" [ref=e12] [cursor=pointer]:
- generic [ref=e13]: dark_mode
- generic [ref=e14]:
- complementary "Navigation sidebar" [ref=e15]:
- paragraph [ref=e17]: Navigation
- navigation "Main navigation" [ref=e18]:
- group "Main" [ref=e19]:
- heading "Main" [level=3] [ref=e20]
- list "Main" [ref=e21]:
- listitem [ref=e22]:
- link "Dashboard" [ref=e23] [cursor=pointer]:
- /url: /codegen
- generic [ref=e24]: dashboard
- generic [ref=e25]: Dashboard
- listitem [ref=e26]:
- link "Code Editor" [ref=e27] [cursor=pointer]:
- /url: /codegen/code
- generic [ref=e28]: code
- generic [ref=e29]: Code Editor
- listitem [ref=e30]:
- link "Components" [ref=e31] [cursor=pointer]:
- /url: /codegen/components
- generic [ref=e32]: widgets
- generic [ref=e33]: Components
- listitem [ref=e34]:
- link "Models" [ref=e35] [cursor=pointer]:
- /url: /codegen/models
- generic [ref=e36]: schema
- generic [ref=e37]: Models
- group "Design" [ref=e38]:
- heading "Design" [level=3] [ref=e39]
- list "Design" [ref=e40]:
- listitem [ref=e41]:
- link "Component Trees" [ref=e42] [cursor=pointer]:
- /url: /codegen/component-trees
- generic [ref=e43]: account_tree
- generic [ref=e44]: Component Trees
- listitem [ref=e45]:
- link "Styling" [ref=e46] [cursor=pointer]:
- /url: /codegen/styling
- generic [ref=e47]: palette
- generic [ref=e48]: Styling
- listitem [ref=e49]:
- link "Sass" [ref=e50] [cursor=pointer]:
- /url: /codegen/sass
- generic [ref=e51]: style
- generic [ref=e52]: Sass
- listitem [ref=e53]:
- link "Atomic Library" [ref=e54] [cursor=pointer]:
- /url: /codegen/atomic-library
- generic [ref=e55]: library_books
- generic [ref=e56]: Atomic Library
- listitem [ref=e57]:
- link "Templates" [ref=e58] [cursor=pointer]:
- /url: /codegen/templates
- generic [ref=e59]: content_copy
- generic [ref=e60]: Templates
- group "Workflows" [ref=e61]:
- heading "Workflows" [level=3] [ref=e62]
- list "Workflows" [ref=e63]:
- listitem [ref=e64]:
- link "Workflows" [ref=e65] [cursor=pointer]:
- /url: /codegen/workflows
- generic [ref=e66]: share
- generic [ref=e67]: Workflows
- listitem [ref=e68]:
- link "Lambdas" [ref=e69] [cursor=pointer]:
- /url: /codegen/lambdas
- generic [ref=e70]: functions
- generic [ref=e71]: Lambdas
- group "Tools" [ref=e72]:
- heading "Tools" [level=3] [ref=e73]
- list "Tools" [ref=e74]:
- listitem [ref=e75]:
- link "JSON UI" [ref=e76] [cursor=pointer]:
- /url: /codegen/json-ui
- generic [ref=e77]: data_object
- generic [ref=e78]: JSON UI
- listitem [ref=e79]:
- link "Schema Editor" [ref=e80] [cursor=pointer]:
- /url: /codegen/schema-editor
- generic [ref=e81]: edit_note
- generic [ref=e82]: Schema Editor
- listitem [ref=e83]:
- link "Data Binding" [ref=e84] [cursor=pointer]:
- /url: /codegen/data-binding
- generic [ref=e85]: link
- generic [ref=e86]: Data Binding
- listitem [ref=e87]:
- link "Flask API" [ref=e88] [cursor=pointer]:
- /url: /codegen/flask
- generic [ref=e89]: api
- generic [ref=e90]: Flask API
- group "Testing" [ref=e91]:
- heading "Testing" [level=3] [ref=e92]
- list "Testing" [ref=e93]:
- listitem [ref=e94]:
- link "Playwright" [ref=e95] [cursor=pointer]:
- /url: /codegen/playwright
- generic [ref=e96]: bug_report
- generic [ref=e97]: Playwright
- listitem [ref=e98]:
- link "Unit Tests" [ref=e99] [cursor=pointer]:
- /url: /codegen/unit-tests
- generic [ref=e100]: science
- generic [ref=e101]: Unit Tests
- listitem [ref=e102]:
- link "Storybook" [ref=e103] [cursor=pointer]:
- /url: /codegen/storybook
- generic [ref=e104]: auto_stories
- generic [ref=e105]: Storybook
- group "System" [ref=e106]:
- heading "System" [level=3] [ref=e107]
- list "System" [ref=e108]:
- listitem [ref=e109]:
- link "Settings" [ref=e110] [cursor=pointer]:
- /url: /codegen/settings
- generic [ref=e111]: settings
- generic [ref=e112]: Settings
- listitem [ref=e113]:
- link "Documentation" [ref=e114] [cursor=pointer]:
- /url: /codegen/docs
- generic [ref=e115]: description
- generic [ref=e116]: Documentation
- listitem [ref=e117]:
- link "Features" [ref=e118] [cursor=pointer]:
- /url: /codegen/features
- generic [ref=e119]: toggle_on
- generic [ref=e120]: Features
- listitem [ref=e121]:
- link "Errors" [ref=e122] [cursor=pointer]:
- /url: /codegen/errors
- generic [ref=e123]: error
- generic [ref=e124]: Errors
- listitem [ref=e125]:
- link "Persistence" [ref=e126] [cursor=pointer]:
- /url: /codegen/persistence
- generic [ref=e127]: storage
- generic [ref=e128]: Persistence
- listitem [ref=e129]:
- link "PWA" [ref=e130] [cursor=pointer]:
- /url: /codegen/pwa
- generic [ref=e131]: install_desktop
- generic [ref=e132]: PWA
- main [ref=e133]:
- paragraph [ref=e137]: Loading projectdashboard...
- alert [ref=e138]

View File

@@ -1,143 +0,0 @@
- generic [ref=e3]:
- banner "Storybook" [ref=e7]:
- heading "Storybook" [level=1] [ref=e8]
- img
- generic [ref=e12]:
- generic [ref=e14]:
- link "Skip to content" [ref=e15] [cursor=pointer]:
- /url: "#storybook-preview-wrapper"
- link "Storybook" [ref=e17] [cursor=pointer]:
- /url: ./
- img "Storybook" [ref=e18]
- switch "Settings" [ref=e23] [cursor=pointer]:
- img [ref=e24]
- generic [ref=e27]: Search for components
- search [ref=e28]:
- combobox "Search for components" [ref=e29]:
- generic:
- img
- searchbox "Search for components" [ref=e30]
- code:
- generic:
- text: K
- button "Tag filters" [ref=e32] [cursor=pointer]:
- img [ref=e33]
- navigation "Stories" [ref=e36]:
- heading "Stories" [level=2] [ref=e37]
- generic [ref=e39]:
- link "Introduction" [ref=e41] [cursor=pointer]:
- /url: /storybook/?path=/docs/introduction--docs
- img [ref=e43]
- text: Introduction
- generic [ref=e45]:
- button "Collapse" [expanded] [ref=e46] [cursor=pointer]:
- img [ref=e48]
- text: Developer
- button "Expand all" [ref=e50] [cursor=pointer]:
- img [ref=e51]
- link "Styles System" [ref=e54] [cursor=pointer]:
- /url: /storybook/?path=/docs/developer-styles-system--docs
- img [ref=e56]
- text: Styles System
- generic [ref=e58]:
- button "Collapse" [expanded] [ref=e59] [cursor=pointer]:
- img [ref=e61]
- text: Packages
- button "Expand all" [ref=e63] [cursor=pointer]:
- img [ref=e64]
- button "Auto-Discovered" [ref=e67] [cursor=pointer]:
- generic [ref=e68]:
- img [ref=e70]
- img [ref=e72]
- text: Auto-Discovered
- button "JSON Components" [ref=e75] [cursor=pointer]:
- generic [ref=e76]:
- img [ref=e78]
- img [ref=e80]
- text: JSON Components
- button "UI Home" [ref=e83] [cursor=pointer]:
- generic [ref=e84]:
- img [ref=e86]
- img [ref=e88]
- text: UI Home
- button "UI Level 2" [ref=e91] [cursor=pointer]:
- generic [ref=e92]:
- img [ref=e94]
- img [ref=e96]
- text: UI Level 2
- button "UI Level 3" [ref=e99] [cursor=pointer]:
- generic [ref=e100]:
- img [ref=e102]
- img [ref=e104]
- text: UI Level 3
- button "UI Level 4" [ref=e107] [cursor=pointer]:
- generic [ref=e108]:
- img [ref=e110]
- img [ref=e112]
- text: UI Level 4
- generic [ref=e114]:
- button "Collapse" [expanded] [ref=e115] [cursor=pointer]:
- img [ref=e117]
- text: Components
- button "Expand all" [ref=e119] [cursor=pointer]:
- img [ref=e120]
- button "Registry" [ref=e123] [cursor=pointer]:
- generic [ref=e124]:
- img [ref=e126]
- img [ref=e128]
- text: Registry
- generic [ref=e130]:
- button "Collapse" [expanded] [ref=e131] [cursor=pointer]:
- img [ref=e133]
- text: Design System
- button "Expand all" [ref=e135] [cursor=pointer]:
- img [ref=e136]
- button "Tokens" [ref=e139] [cursor=pointer]:
- generic [ref=e140]:
- img [ref=e142]
- img [ref=e144]
- text: Tokens
- generic [ref=e147]:
- region "Toolbar" [ref=e148]:
- heading "Toolbar" [level=2] [ref=e149]
- toolbar [ref=e150]
- main "Main preview area" [ref=e151]:
- heading "Main preview area" [level=2] [ref=e152]
- generic [ref=e153]:
- progressbar "Content is loading..." [ref=e155]
- iframe [ref=e160]:
- table [ref=f1e11]:
- rowgroup [ref=f1e12]:
- row [ref=f1e13]:
- columnheader [ref=f1e14]: Name
- columnheader [ref=f1e15]: Description
- columnheader [ref=f1e16]: Default
- columnheader [ref=f1e17]: Control
- rowgroup [ref=f1e18]:
- row [ref=f1e19]:
- cell [ref=f1e20]: propertyName*
- cell [ref=f1e21]:
- generic [ref=f1e22]: This is a short description
- generic [ref=f1e24]: summary
- cell [ref=f1e25]:
- generic [ref=f1e26]: defaultValue
- cell [ref=f1e27]:
- button [ref=f1e28] [cursor=pointer]: Set string
- row [ref=f1e29]:
- cell [ref=f1e30]: propertyName*
- cell [ref=f1e31]:
- generic [ref=f1e32]: This is a short description
- generic [ref=f1e34]: summary
- cell [ref=f1e35]:
- generic [ref=f1e36]: defaultValue
- cell [ref=f1e37]:
- button [ref=f1e38] [cursor=pointer]: Set string
- row [ref=f1e39]:
- cell [ref=f1e40]: propertyName*
- cell [ref=f1e41]:
- generic [ref=f1e42]: This is a short description
- generic [ref=f1e44]: summary
- cell [ref=f1e45]:
- generic [ref=f1e46]: defaultValue
- cell [ref=f1e47]:
- button [ref=f1e48] [cursor=pointer]: Set string

View File

@@ -1,156 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [expanded] [ref=e6] [cursor=pointer]:
- generic [ref=e7]: menu
- generic [ref=e8]:
- generic [ref=e9]: code
- heading "CodeForge" [level=1] [ref=e10]
- button "Switch to dark mode" [ref=e12] [cursor=pointer]:
- generic [ref=e13]: dark_mode
- generic [ref=e14]:
- complementary "Navigation sidebar" [ref=e15]:
- paragraph [ref=e17]: Navigation
- navigation "Main navigation" [ref=e18]:
- group "Main" [ref=e19]:
- heading "Main" [level=3] [ref=e20]
- list "Main" [ref=e21]:
- listitem [ref=e22]:
- link "Dashboard" [ref=e23] [cursor=pointer]:
- /url: /codegen
- generic [ref=e24]: dashboard
- generic [ref=e25]: Dashboard
- listitem [ref=e26]:
- link "Code Editor" [ref=e27] [cursor=pointer]:
- /url: /codegen/code
- generic [ref=e28]: code
- generic [ref=e29]: Code Editor
- listitem [ref=e30]:
- link "Components" [ref=e31] [cursor=pointer]:
- /url: /codegen/components
- generic [ref=e32]: widgets
- generic [ref=e33]: Components
- listitem [ref=e34]:
- link "Models" [ref=e35] [cursor=pointer]:
- /url: /codegen/models
- generic [ref=e36]: schema
- generic [ref=e37]: Models
- group "Design" [ref=e38]:
- heading "Design" [level=3] [ref=e39]
- list "Design" [ref=e40]:
- listitem [ref=e41]:
- link "Component Trees" [ref=e42] [cursor=pointer]:
- /url: /codegen/component-trees
- generic [ref=e43]: account_tree
- generic [ref=e44]: Component Trees
- listitem [ref=e45]:
- link "Styling" [ref=e46] [cursor=pointer]:
- /url: /codegen/styling
- generic [ref=e47]: palette
- generic [ref=e48]: Styling
- listitem [ref=e49]:
- link "Sass" [ref=e50] [cursor=pointer]:
- /url: /codegen/sass
- generic [ref=e51]: style
- generic [ref=e52]: Sass
- listitem [ref=e53]:
- link "Atomic Library" [ref=e54] [cursor=pointer]:
- /url: /codegen/atomic-library
- generic [ref=e55]: library_books
- generic [ref=e56]: Atomic Library
- listitem [ref=e57]:
- link "Templates" [ref=e58] [cursor=pointer]:
- /url: /codegen/templates
- generic [ref=e59]: content_copy
- generic [ref=e60]: Templates
- group "Workflows" [ref=e61]:
- heading "Workflows" [level=3] [ref=e62]
- list "Workflows" [ref=e63]:
- listitem [ref=e64]:
- link "Workflows" [ref=e65] [cursor=pointer]:
- /url: /codegen/workflows
- generic [ref=e66]: share
- generic [ref=e67]: Workflows
- listitem [ref=e68]:
- link "Lambdas" [ref=e69] [cursor=pointer]:
- /url: /codegen/lambdas
- generic [ref=e70]: functions
- generic [ref=e71]: Lambdas
- group "Tools" [ref=e72]:
- heading "Tools" [level=3] [ref=e73]
- list "Tools" [ref=e74]:
- listitem [ref=e75]:
- link "JSON UI" [ref=e76] [cursor=pointer]:
- /url: /codegen/json-ui
- generic [ref=e77]: data_object
- generic [ref=e78]: JSON UI
- listitem [ref=e79]:
- link "Schema Editor" [ref=e80] [cursor=pointer]:
- /url: /codegen/schema-editor
- generic [ref=e81]: edit_note
- generic [ref=e82]: Schema Editor
- listitem [ref=e83]:
- link "Data Binding" [ref=e84] [cursor=pointer]:
- /url: /codegen/data-binding
- generic [ref=e85]: link
- generic [ref=e86]: Data Binding
- listitem [ref=e87]:
- link "Database" [ref=e88] [cursor=pointer]:
- /url: /codegen/database
- generic [ref=e89]: database
- generic [ref=e90]: Database
- group "Testing" [ref=e91]:
- heading "Testing" [level=3] [ref=e92]
- list "Testing" [ref=e93]:
- listitem [ref=e94]:
- link "Playwright" [ref=e95] [cursor=pointer]:
- /url: /codegen/playwright
- generic [ref=e96]: bug_report
- generic [ref=e97]: Playwright
- listitem [ref=e98]:
- link "Unit Tests" [ref=e99] [cursor=pointer]:
- /url: /codegen/unit-tests
- generic [ref=e100]: science
- generic [ref=e101]: Unit Tests
- listitem [ref=e102]:
- link "Storybook" [ref=e103] [cursor=pointer]:
- /url: /codegen/storybook
- generic [ref=e104]: auto_stories
- generic [ref=e105]: Storybook
- group "System" [ref=e106]:
- heading "System" [level=3] [ref=e107]
- list "System" [ref=e108]:
- listitem [ref=e109]:
- link "Settings" [ref=e110] [cursor=pointer]:
- /url: /codegen/settings
- generic [ref=e111]: settings
- generic [ref=e112]: Settings
- listitem [ref=e113]:
- link "Documentation" [ref=e114] [cursor=pointer]:
- /url: /codegen/docs
- generic [ref=e115]: description
- generic [ref=e116]: Documentation
- listitem [ref=e117]:
- link "Features" [ref=e118] [cursor=pointer]:
- /url: /codegen/features
- generic [ref=e119]: toggle_on
- generic [ref=e120]: Features
- listitem [ref=e121]:
- link "Errors" [ref=e122] [cursor=pointer]:
- /url: /codegen/errors
- generic [ref=e123]: error
- generic [ref=e124]: Errors
- listitem [ref=e125]:
- link "Persistence" [ref=e126] [cursor=pointer]:
- /url: /codegen/persistence
- generic [ref=e127]: storage
- generic [ref=e128]: Persistence
- listitem [ref=e129]:
- link "PWA" [ref=e130] [cursor=pointer]:
- /url: /codegen/pwa
- generic [ref=e131]: install_desktop
- generic [ref=e132]: PWA
- main [ref=e133]:
- paragraph [ref=e137]: Loading projectdashboard...
- alert [ref=e138]

View File

@@ -1,324 +0,0 @@
- generic [ref=e3]:
- banner "Storybook" [ref=e7]:
- heading "Storybook" [level=1] [ref=e8]
- img
- generic [ref=e12]:
- generic [ref=e14]:
- link "Skip to content" [ref=e15] [cursor=pointer]:
- /url: "#storybook-preview-wrapper"
- link "Storybook" [ref=e17] [cursor=pointer]:
- /url: ./
- img "Storybook" [ref=e18]
- switch "Settings" [ref=e23] [cursor=pointer]:
- img [ref=e24]
- generic [ref=e27]: Search for components
- search [ref=e28]:
- combobox "Search for components" [ref=e29]:
- generic:
- img
- searchbox "Search for components" [ref=e30]
- code:
- generic:
- text: K
- button "Tag filters" [ref=e32] [cursor=pointer]:
- img [ref=e33]
- navigation "Stories" [ref=e36]:
- heading "Stories" [level=2] [ref=e37]
- generic [ref=e39]:
- generic [ref=e40]:
- link "Introduction" [ref=e41] [cursor=pointer]:
- /url: /storybook/?path=/docs/introduction--docs
- img [ref=e43]
- text: Introduction
- link "Skip to content" [ref=e161] [cursor=pointer]:
- /url: "#storybook-preview-wrapper"
- generic [ref=e45]:
- button "Collapse" [expanded] [ref=e46] [cursor=pointer]:
- img [ref=e48]
- text: Developer
- button "Expand all" [ref=e50] [cursor=pointer]:
- img [ref=e51]
- link "Styles System" [ref=e54] [cursor=pointer]:
- /url: /storybook/?path=/docs/developer-styles-system--docs
- img [ref=e56]
- text: Styles System
- generic [ref=e58]:
- button "Collapse" [expanded] [ref=e59] [cursor=pointer]:
- img [ref=e61]
- text: Packages
- button "Expand all" [ref=e63] [cursor=pointer]:
- img [ref=e64]
- button "Auto-Discovered" [ref=e67] [cursor=pointer]:
- generic [ref=e68]:
- img [ref=e70]
- img [ref=e72]
- text: Auto-Discovered
- button "JSON Components" [ref=e75] [cursor=pointer]:
- generic [ref=e76]:
- img [ref=e78]
- img [ref=e80]
- text: JSON Components
- button "UI Home" [ref=e83] [cursor=pointer]:
- generic [ref=e84]:
- img [ref=e86]
- img [ref=e88]
- text: UI Home
- button "UI Level 2" [ref=e91] [cursor=pointer]:
- generic [ref=e92]:
- img [ref=e94]
- img [ref=e96]
- text: UI Level 2
- button "UI Level 3" [ref=e99] [cursor=pointer]:
- generic [ref=e100]:
- img [ref=e102]
- img [ref=e104]
- text: UI Level 3
- button "UI Level 4" [ref=e107] [cursor=pointer]:
- generic [ref=e108]:
- img [ref=e110]
- img [ref=e112]
- text: UI Level 4
- generic [ref=e114]:
- button "Collapse" [expanded] [ref=e115] [cursor=pointer]:
- img [ref=e117]
- text: Components
- button "Expand all" [ref=e119] [cursor=pointer]:
- img [ref=e120]
- button "Registry" [ref=e123] [cursor=pointer]:
- generic [ref=e124]:
- img [ref=e126]
- img [ref=e128]
- text: Registry
- generic [ref=e130]:
- button "Collapse" [expanded] [ref=e131] [cursor=pointer]:
- img [ref=e133]
- text: Design System
- button "Expand all" [ref=e135] [cursor=pointer]:
- img [ref=e136]
- button "Tokens" [ref=e139] [cursor=pointer]:
- generic [ref=e140]:
- img [ref=e142]
- img [ref=e144]
- text: Tokens
- generic [ref=e147]:
- region "Toolbar" [ref=e148]:
- heading "Toolbar" [level=2] [ref=e149]
- toolbar [ref=e150]:
- generic [ref=e162]:
- switch "Grid visibility" [ref=e163] [cursor=pointer]:
- img [ref=e164]
- button "Preview background" [ref=e166] [cursor=pointer]:
- img [ref=e167]
- switch "Outline tool" [ref=e170] [cursor=pointer]:
- img [ref=e171]
- button "Enter full screen" [ref=e174] [cursor=pointer]:
- img [ref=e175]
- main "Main preview area" [ref=e151]:
- heading "Main preview area" [level=2] [ref=e152]
- generic [ref=e156]:
- link "Skip to sidebar" [ref=e177] [cursor=pointer]:
- /url: "#introduction--docs"
- iframe [ref=e160]:
- generic [ref=f1e51]:
- heading "MetaBuilder Package Storybook" [level=1] [ref=f1e52]:
- link [ref=f1e53] [cursor=pointer]:
- /url: "#metabuilder-package-storybook"
- text: MetaBuilder Package Storybook
- paragraph [ref=f1e54]:
- text: This Storybook renders
- strong [ref=f1e55]: MetaBuilder packages backed by JSON scripts
- text: from the MetaBuilder platform without running the actual application.
- heading "Quick Start" [level=2] [ref=f1e56]:
- link [ref=f1e57] [cursor=pointer]:
- /url: "#quick-start"
- text: Quick Start
- list [ref=f1e58]:
- listitem [ref=f1e59]:
- strong [ref=f1e60]: Explorer
- text: "- Use the Auto-Discovered Packages → Explorer to browse all packages interactively"
- listitem [ref=f1e61]:
- strong [ref=f1e62]: Component Registry
- text: "- See all available components in Components → Registry"
- listitem [ref=f1e63]:
- strong [ref=f1e64]: Manual Stories
- text: "- Pre-configured stories in JSON package renders"
- heading "Auto-Discovery" [level=2] [ref=f1e65]:
- link [ref=f1e66] [cursor=pointer]:
- /url: "#auto-discovery"
- text: Auto-Discovery
- paragraph [ref=f1e67]:
- text: The storybook automatically discovers packages using
- code [ref=f1e68]: storybook.config.json
- text: ":"
- generic [ref=f1e70]:
- generic [ref=f1e75]: "{ \"discovery\": { \"enabled\": true, \"includedCategories\": [\"ui\", \"admin\", \"gaming\", \"social\", \"editors\"], \"excludedPackages\": [\"shared\", \"testing\"], \"minLevel\": 1, \"maxLevel\": 6 } }"
- button "Copy" [ref=f1e77] [cursor=pointer]
- heading "Context Variants" [level=3] [ref=f1e78]:
- link [ref=f1e79] [cursor=pointer]:
- /url: "#context-variants"
- text: Context Variants
- paragraph [ref=f1e80]: "Test packages with different user contexts:"
- list [ref=f1e81]:
- listitem [ref=f1e82]:
- strong [ref=f1e83]: Guest
- text: "- Level 1 user"
- listitem [ref=f1e84]:
- strong [ref=f1e85]: Admin
- text: "- Level 4 user"
- listitem [ref=f1e86]:
- strong [ref=f1e87]: Admin (Nerd Mode)
- text: "- Level 4 with nerdMode enabled"
- listitem [ref=f1e88]:
- strong [ref=f1e89]: Supergod
- text: "- Level 6 user"
- heading "How It Works" [level=2] [ref=f1e90]:
- link [ref=f1e91] [cursor=pointer]:
- /url: "#how-it-works"
- text: How It Works
- list [ref=f1e92]:
- listitem [ref=f1e93]:
- strong [ref=f1e94]: JSON script packages
- text: in
- code [ref=f1e95]: /packages/*/seed/scripts/
- text: define UI component trees
- listitem [ref=f1e96]:
- strong [ref=f1e97]: Mock data
- text: mirrors the output structure produced by the JSON scripts
- listitem [ref=f1e98]:
- strong [ref=f1e99]: PackageRenderer
- text: (still the runtime entry) converts the component tree to React components
- listitem [ref=f1e100]:
- strong [ref=f1e101]: Component Registry
- text: maps package-defined type names to React implementations
- heading "Package Structure" [level=2] [ref=f1e102]:
- link [ref=f1e103] [cursor=pointer]:
- /url: "#package-structure"
- text: Package Structure
- paragraph [ref=f1e104]: "Each JSON script package follows this structure:"
- generic [ref=f1e106]:
- generic [ref=f1e111]: "packages/ └── {package_name}/ └── seed/ ├── metadata.json # Package info ├── components.json # Component definitions └── scripts/ └── [script-name].json # JSON script definitions following script_schema.json # Must include full function implementations with bodies, # not just metadata declarations (e.g., automation.json)"
- button "Copy" [ref=f1e113] [cursor=pointer]
- heading "JSON Script Output" [level=2] [ref=f1e114]:
- link [ref=f1e115] [cursor=pointer]:
- /url: "#json-script-output"
- text: JSON Script Output
- paragraph [ref=f1e116]: "JSON script functions return component trees like:"
- generic [ref=f1e118]:
- generic [ref=f1e123]:
- text: "{ \"type\": \"Card\", \"props\": { \"className\": \"p-4\" }, \"children\": [ { \"type\": \"Typography\", \"props\": { \"variant\": \"h5\", \"text\": \"Title\" } }, { \"type\": \"Button\", \"props\": { \"children\": \"Click Me\" } } ]"
- text: "}"
- button "Copy" [ref=f1e125] [cursor=pointer]
- heading "Adding New Package Mocks" [level=2] [ref=f1e126]:
- link [ref=f1e127] [cursor=pointer]:
- /url: "#adding-new-package-mocks"
- text: Adding New Package Mocks
- list [ref=f1e128]:
- listitem [ref=f1e129]:
- text: Create a file in
- code [ref=f1e130]: "src/mocks/packages/{package-name}.ts"
- listitem [ref=f1e131]:
- text: Define the
- code [ref=f1e132]: MockPackageDefinition
- text: with metadata and renders
- listitem [ref=f1e133]:
- text: Call
- code [ref=f1e134]: registerMockPackage()
- text: to register it
- listitem [ref=f1e135]:
- text: Import it in
- code [ref=f1e136]: src/mocks/packages/index.ts
- listitem [ref=f1e137]:
- text: Create stories in
- code [ref=f1e138]: src/stories/
- heading "Available Component Types" [level=2] [ref=f1e139]:
- link [ref=f1e140] [cursor=pointer]:
- /url: "#available-component-types"
- text: Available Component Types
- paragraph [ref=f1e141]: "The component registry maps these package types to React:"
- heading "Layout" [level=3] [ref=f1e142]:
- link [ref=f1e143] [cursor=pointer]:
- /url: "#layout"
- text: Layout
- list [ref=f1e144]:
- listitem [ref=f1e145]:
- code [ref=f1e146]: Box
- text: ","
- code [ref=f1e147]: Stack
- text: ","
- code [ref=f1e148]: Flex
- text: ","
- code [ref=f1e149]: Grid
- text: ","
- code [ref=f1e150]: Container
- heading "Surfaces" [level=3] [ref=f1e151]:
- link [ref=f1e152] [cursor=pointer]:
- /url: "#surfaces"
- text: Surfaces
- list [ref=f1e153]:
- listitem [ref=f1e154]:
- code [ref=f1e155]: Card
- text: ","
- code [ref=f1e156]: CardHeader
- text: ","
- code [ref=f1e157]: CardContent
- text: ","
- code [ref=f1e158]: CardActions
- text: ","
- code [ref=f1e159]: Paper
- heading "Typography" [level=3] [ref=f1e160]:
- link [ref=f1e161] [cursor=pointer]:
- /url: "#typography"
- text: Typography
- list [ref=f1e162]:
- listitem [ref=f1e163]:
- code [ref=f1e164]: Typography
- text: "(with variants: h1-h6, body1, body2, caption, overline)"
- heading "Inputs" [level=3] [ref=f1e165]:
- link [ref=f1e166] [cursor=pointer]:
- /url: "#inputs"
- text: Inputs
- list [ref=f1e167]:
- listitem [ref=f1e168]:
- code [ref=f1e169]: Button
- text: "(variants: contained, outlined, text)"
- heading "Display" [level=3] [ref=f1e170]:
- link [ref=f1e171] [cursor=pointer]:
- /url: "#display"
- text: Display
- list [ref=f1e172]:
- listitem [ref=f1e173]:
- code [ref=f1e174]: Icon
- text: ","
- code [ref=f1e175]: Avatar
- text: ","
- code [ref=f1e176]: Badge
- text: ","
- code [ref=f1e177]: Chip
- text: ","
- code [ref=f1e178]: Divider
- text: ","
- code [ref=f1e179]: Alert
- heading "Navigation" [level=3] [ref=f1e180]:
- link [ref=f1e181] [cursor=pointer]:
- /url: "#navigation"
- text: Navigation
- list [ref=f1e182]:
- listitem [ref=f1e183]:
- code [ref=f1e184]: Tabs
- text: ","
- code [ref=f1e185]: Tab
- heading "App-Specific" [level=3] [ref=f1e186]:
- link [ref=f1e187] [cursor=pointer]:
- /url: "#app-specific"
- text: App-Specific
- list [ref=f1e188]:
- listitem [ref=f1e189]:
- code [ref=f1e190]: Level4Header
- text: ","
- code [ref=f1e191]: IntroSection
- text: ","
- code [ref=f1e192]: AppHeader
- text: ","
- code [ref=f1e193]: AppFooter
- text: ","
- code [ref=f1e194]: Sidebar

View File

@@ -1,32 +0,0 @@
- generic [active] [ref=e1]:
- alert [ref=e2]
- generic [ref=e4]:
- banner [ref=e5]:
- generic [ref=e7]:
- generic [ref=e8]:
- button "Toggle navigation menu" [ref=e9]:
- img [ref=e10]
- img [ref=e13]
- text: CodeSnippet
- generic "Disconnected from backend - Using local storage" [ref=e17]:
- 'status "Status: Local" [ref=e18]':
- img [ref=e20]
- generic [ref=e24]: Local
- main [ref=e25]:
- region "Application status alerts" [ref=e27]:
- status [ref=e28]:
- img [ref=e29]
- heading "Workspace ready" [level=5] [ref=e31]
- generic [ref=e32]: Running in local-first mode so you can work offline without a backend.
- alert [ref=e33]:
- img [ref=e34]
- heading "Cloud backend unavailable" [level=5] [ref=e36]
- generic [ref=e37]: No Flask backend detected. Saving and loading will stay on this device until a server URL is configured.
- generic [ref=e39]:
- heading "My Snippets" [level=1] [ref=e40]
- paragraph [ref=e41]: Save, organize, and share your code snippets
- contentinfo [ref=e42]:
- generic [ref=e44]:
- paragraph [ref=e45]: Save, organize, and share your code snippets with beautiful syntax highlighting and live execution
- paragraph [ref=e46]: Supports React preview and Python execution via Pyodide
- region "Notifications alt+T"

View File

@@ -1,225 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [expanded] [ref=e6] [cursor=pointer]:
- generic [ref=e7]: menu
- generic [ref=e8]:
- generic [ref=e9]: code
- heading "CodeForge" [level=1] [ref=e10]
- button "Switch to dark mode" [ref=e12] [cursor=pointer]:
- generic [ref=e13]: dark_mode
- generic [ref=e14]:
- complementary "Navigation sidebar" [ref=e15]:
- paragraph [ref=e17]: Navigation
- navigation "Main navigation" [ref=e18]:
- group "Main" [ref=e19]:
- heading "Main" [level=3] [ref=e20]
- list "Main" [ref=e21]:
- listitem [ref=e22]:
- link "Dashboard" [ref=e23] [cursor=pointer]:
- /url: /codegen
- generic [ref=e24]: dashboard
- generic [ref=e25]: Dashboard
- listitem [ref=e26]:
- link "Code Editor" [ref=e27] [cursor=pointer]:
- /url: /codegen/code
- generic [ref=e28]: code
- generic [ref=e29]: Code Editor
- listitem [ref=e30]:
- link "Components" [ref=e31] [cursor=pointer]:
- /url: /codegen/components
- generic [ref=e32]: widgets
- generic [ref=e33]: Components
- listitem [ref=e34]:
- link "Models" [ref=e35] [cursor=pointer]:
- /url: /codegen/models
- generic [ref=e36]: schema
- generic [ref=e37]: Models
- group "Design" [ref=e38]:
- heading "Design" [level=3] [ref=e39]
- list "Design" [ref=e40]:
- listitem [ref=e41]:
- link "Component Trees" [ref=e42] [cursor=pointer]:
- /url: /codegen/component-trees
- generic [ref=e43]: account_tree
- generic [ref=e44]: Component Trees
- listitem [ref=e45]:
- link "Styling" [ref=e46] [cursor=pointer]:
- /url: /codegen/styling
- generic [ref=e47]: palette
- generic [ref=e48]: Styling
- listitem [ref=e49]:
- link "Sass" [ref=e50] [cursor=pointer]:
- /url: /codegen/sass
- generic [ref=e51]: style
- generic [ref=e52]: Sass
- listitem [ref=e53]:
- link "Atomic Library" [ref=e54] [cursor=pointer]:
- /url: /codegen/atomic-library
- generic [ref=e55]: library_books
- generic [ref=e56]: Atomic Library
- listitem [ref=e57]:
- link "Templates" [ref=e58] [cursor=pointer]:
- /url: /codegen/templates
- generic [ref=e59]: content_copy
- generic [ref=e60]: Templates
- group "Workflows" [ref=e61]:
- heading "Workflows" [level=3] [ref=e62]
- list "Workflows" [ref=e63]:
- listitem [ref=e64]:
- link "Workflows" [ref=e65] [cursor=pointer]:
- /url: /codegen/workflows
- generic [ref=e66]: share
- generic [ref=e67]: Workflows
- listitem [ref=e68]:
- link "Lambdas" [ref=e69] [cursor=pointer]:
- /url: /codegen/lambdas
- generic [ref=e70]: functions
- generic [ref=e71]: Lambdas
- group "Tools" [ref=e72]:
- heading "Tools" [level=3] [ref=e73]
- list "Tools" [ref=e74]:
- listitem [ref=e75]:
- link "JSON UI" [ref=e76] [cursor=pointer]:
- /url: /codegen/json-ui
- generic [ref=e77]: data_object
- generic [ref=e78]: JSON UI
- listitem [ref=e79]:
- link "Schema Editor" [ref=e80] [cursor=pointer]:
- /url: /codegen/schema-editor
- generic [ref=e81]: edit_note
- generic [ref=e82]: Schema Editor
- listitem [ref=e83]:
- link "Data Binding" [ref=e84] [cursor=pointer]:
- /url: /codegen/data-binding
- generic [ref=e85]: link
- generic [ref=e86]: Data Binding
- listitem [ref=e87]:
- link "Database" [ref=e88] [cursor=pointer]:
- /url: /codegen/database
- generic [ref=e89]: database
- generic [ref=e90]: Database
- group "Testing" [ref=e91]:
- heading "Testing" [level=3] [ref=e92]
- list "Testing" [ref=e93]:
- listitem [ref=e94]:
- link "Playwright" [ref=e95] [cursor=pointer]:
- /url: /codegen/playwright
- generic [ref=e96]: bug_report
- generic [ref=e97]: Playwright
- listitem [ref=e98]:
- link "Unit Tests" [ref=e99] [cursor=pointer]:
- /url: /codegen/unit-tests
- generic [ref=e100]: science
- generic [ref=e101]: Unit Tests
- listitem [ref=e102]:
- link "Storybook" [ref=e103] [cursor=pointer]:
- /url: /codegen/storybook
- generic [ref=e104]: auto_stories
- generic [ref=e105]: Storybook
- group "System" [ref=e106]:
- heading "System" [level=3] [ref=e107]
- list "System" [ref=e108]:
- listitem [ref=e109]:
- link "Settings" [ref=e110] [cursor=pointer]:
- /url: /codegen/settings
- generic [ref=e111]: settings
- generic [ref=e112]: Settings
- listitem [ref=e113]:
- link "Documentation" [ref=e114] [cursor=pointer]:
- /url: /codegen/docs
- generic [ref=e115]: description
- generic [ref=e116]: Documentation
- listitem [ref=e117]:
- link "Features" [ref=e118] [cursor=pointer]:
- /url: /codegen/features
- generic [ref=e119]: toggle_on
- generic [ref=e120]: Features
- listitem [ref=e121]:
- link "Errors" [ref=e122] [cursor=pointer]:
- /url: /codegen/errors
- generic [ref=e123]: error
- generic [ref=e124]: Errors
- listitem [ref=e125]:
- link "Persistence" [ref=e126] [cursor=pointer]:
- /url: /codegen/persistence
- generic [ref=e127]: storage
- generic [ref=e128]: Persistence
- listitem [ref=e129]:
- link "PWA" [ref=e130] [cursor=pointer]:
- /url: /codegen/pwa
- generic [ref=e131]: install_desktop
- generic [ref=e132]: PWA
- main [ref=e133]:
- generic [ref=e139]:
- generic [ref=e140]:
- heading "Project Dashboard" [level=1] [ref=e141]
- paragraph [ref=e142]: Overview of your CodeForge project
- generic [ref=e143]:
- generic [ref=e144]:
- generic [ref=e146]:
- generic [ref=e148]: task_alt
- text: Project Completeness
- generic [ref=e149]:
- generic [ref=e151]: 70%
- generic [ref=e153]: Ready to Export
- progressbar [ref=e154]
- paragraph [ref=e156]: Great progress! Consider adding more tests.
- generic [ref=e157]:
- generic [ref=e159]:
- generic [ref=e161]: build_circle
- text: GitHub Build Status
- generic [ref=e162]:
- generic [ref=e163]:
- generic [ref=e164]: Build
- generic [ref=e165]: Passing
- generic [ref=e167]:
- generic [ref=e168]: Type Check
- generic [ref=e169]: Passing
- generic [ref=e171]:
- generic [ref=e172]: Lint
- generic [ref=e173]: Passing
- generic [ref=e175]:
- generic [ref=e176]: E2E Tests
- generic [ref=e177]: Idle
- generic [ref=e179]:
- generic [ref=e181]:
- generic [ref=e182]:
- generic [ref=e183]: Code Files
- generic [ref=e185]: code_blocks
- generic [ref=e186]: "4"
- generic [ref=e187]: files in your project
- generic [ref=e189]:
- generic [ref=e190]:
- generic [ref=e191]: Database Models
- generic [ref=e193]: storage
- generic [ref=e194]: "3"
- generic [ref=e195]: Prisma schemas
- generic [ref=e197]:
- generic [ref=e198]:
- generic [ref=e199]: Components
- generic [ref=e201]: view_in_ar
- generic [ref=e202]: "3"
- generic [ref=e203]: React components
- generic [ref=e205]:
- generic [ref=e206]:
- generic [ref=e207]: Workflows
- generic [ref=e209]: account_tree
- generic [ref=e210]: "0"
- generic [ref=e211]: automation flows
- generic [ref=e213]:
- generic [ref=e214]:
- generic [ref=e215]: API Endpoints
- generic [ref=e217]: science
- generic [ref=e218]: "0"
- generic [ref=e219]: Flask routes
- generic [ref=e221]:
- generic [ref=e222]:
- generic [ref=e223]: Test Suites
- generic [ref=e225]: biotech
- generic [ref=e226]: "0"
- generic [ref=e227]: automated tests
- button "Open Next.js Dev Tools" [ref=e233] [cursor=pointer]:
- img [ref=e234]
- alert [ref=e138]

View File

@@ -1,7 +0,0 @@
- generic [ref=e3]:
- heading "No Preview" [level=1] [ref=e4]
- paragraph [ref=e5]: Sorry, but you either have no stories or none are selected somehow.
- list [ref=e6]:
- listitem [ref=e7]: Please check the Storybook config.
- listitem [ref=e8]: Try reloading the page.
- paragraph [ref=e9]: If the problem persists, check the browser console, or the terminal you've run Storybook from.

View File

@@ -1,49 +0,0 @@
- generic [active] [ref=e1]:
- alert [ref=e2]
- generic [ref=e4]:
- banner [ref=e5]:
- generic [ref=e7]:
- generic [ref=e8]:
- button "Toggle navigation menu" [ref=e9]:
- img [ref=e10]
- img [ref=e13]
- text: CodeSnippet
- generic "Disconnected from backend - Using local storage" [ref=e17]:
- 'status "Status: Local" [ref=e18]':
- img [ref=e20]
- generic [ref=e24]: Local
- main [ref=e25]:
- region "Application status alerts" [ref=e27]:
- status [ref=e28]:
- img [ref=e29]
- heading "Workspace ready" [level=5] [ref=e31]
- generic [ref=e32]: Running in local-first mode so you can work offline without a backend.
- alert [ref=e33]:
- img [ref=e34]
- heading "Cloud backend unavailable" [level=5] [ref=e36]
- generic [ref=e37]: No Flask backend detected. Saving and loading will stay on this device until a server URL is configured.
- generic [ref=e38]:
- generic [ref=e39]:
- heading "My Snippets" [level=1] [ref=e40]
- paragraph [ref=e41]: Save, organize, and share your code snippets
- group "Namespace selector" [ref=e48]:
- generic [ref=e49]:
- img [ref=e50]
- generic [ref=e52]: "Namespace:"
- combobox "Select namespace" [ref=e53]:
- text: default
- img [ref=e55]
- status "No snippets available" [ref=e57]:
- status [ref=e58]: No snippets yet. Start building your code snippet library. Save reusable code for quick access anytime.
- img [ref=e60]
- heading "No snippets yet" [level=2] [ref=e63]
- paragraph [ref=e64]: Start building your code snippet library. Save reusable code for quick access anytime.
- button "Create new snippet from templates" [ref=e65] [cursor=pointer]:
- img [ref=e66]
- text: Create Your First Snippet
- img [ref=e68]
- contentinfo [ref=e42]:
- generic [ref=e44]:
- paragraph [ref=e45]: Save, organize, and share your code snippets with beautiful syntax highlighting and live execution
- paragraph [ref=e46]: Supports React preview and Python execution via Pyodide
- region "Notifications alt+T"

View File

@@ -1,7 +0,0 @@
- generic [ref=e3]:
- heading "No Preview" [level=1] [ref=e4]
- paragraph [ref=e5]: Sorry, but you either have no stories or none are selected somehow.
- list [ref=e6]:
- listitem [ref=e7]: Please check the Storybook config.
- listitem [ref=e8]: Try reloading the page.
- paragraph [ref=e9]: If the problem persists, check the browser console, or the terminal you've run Storybook from.

View File

@@ -1,225 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [expanded] [ref=e6] [cursor=pointer]:
- generic [ref=e7]: menu
- generic [ref=e8]:
- generic [ref=e9]: code
- heading "CodeForge" [level=1] [ref=e10]
- button "Switch to dark mode" [ref=e12] [cursor=pointer]:
- generic [ref=e13]: dark_mode
- generic [ref=e14]:
- complementary "Navigation sidebar" [ref=e15]:
- paragraph [ref=e17]: Navigation
- navigation "Main navigation" [ref=e18]:
- group "Main" [ref=e19]:
- heading "Main" [level=3] [ref=e20]
- list "Main" [ref=e21]:
- listitem [ref=e22]:
- link "Dashboard" [ref=e23] [cursor=pointer]:
- /url: /codegen
- generic [ref=e24]: dashboard
- generic [ref=e25]: Dashboard
- listitem [ref=e26]:
- link "Code Editor" [ref=e27] [cursor=pointer]:
- /url: /codegen/code
- generic [ref=e28]: code
- generic [ref=e29]: Code Editor
- listitem [ref=e30]:
- link "Components" [ref=e31] [cursor=pointer]:
- /url: /codegen/components
- generic [ref=e32]: widgets
- generic [ref=e33]: Components
- listitem [ref=e34]:
- link "Models" [ref=e35] [cursor=pointer]:
- /url: /codegen/models
- generic [ref=e36]: schema
- generic [ref=e37]: Models
- group "Design" [ref=e38]:
- heading "Design" [level=3] [ref=e39]
- list "Design" [ref=e40]:
- listitem [ref=e41]:
- link "Component Trees" [ref=e42] [cursor=pointer]:
- /url: /codegen/component-trees
- generic [ref=e43]: account_tree
- generic [ref=e44]: Component Trees
- listitem [ref=e45]:
- link "Styling" [ref=e46] [cursor=pointer]:
- /url: /codegen/styling
- generic [ref=e47]: palette
- generic [ref=e48]: Styling
- listitem [ref=e49]:
- link "Sass" [ref=e50] [cursor=pointer]:
- /url: /codegen/sass
- generic [ref=e51]: style
- generic [ref=e52]: Sass
- listitem [ref=e53]:
- link "Atomic Library" [ref=e54] [cursor=pointer]:
- /url: /codegen/atomic-library
- generic [ref=e55]: library_books
- generic [ref=e56]: Atomic Library
- listitem [ref=e57]:
- link "Templates" [ref=e58] [cursor=pointer]:
- /url: /codegen/templates
- generic [ref=e59]: content_copy
- generic [ref=e60]: Templates
- group "Workflows" [ref=e61]:
- heading "Workflows" [level=3] [ref=e62]
- list "Workflows" [ref=e63]:
- listitem [ref=e64]:
- link "Workflows" [ref=e65] [cursor=pointer]:
- /url: /codegen/workflows
- generic [ref=e66]: share
- generic [ref=e67]: Workflows
- listitem [ref=e68]:
- link "Lambdas" [ref=e69] [cursor=pointer]:
- /url: /codegen/lambdas
- generic [ref=e70]: functions
- generic [ref=e71]: Lambdas
- group "Tools" [ref=e72]:
- heading "Tools" [level=3] [ref=e73]
- list "Tools" [ref=e74]:
- listitem [ref=e75]:
- link "JSON UI" [ref=e76] [cursor=pointer]:
- /url: /codegen/json-ui
- generic [ref=e77]: data_object
- generic [ref=e78]: JSON UI
- listitem [ref=e79]:
- link "Schema Editor" [ref=e80] [cursor=pointer]:
- /url: /codegen/schema-editor
- generic [ref=e81]: edit_note
- generic [ref=e82]: Schema Editor
- listitem [ref=e83]:
- link "Data Binding" [ref=e84] [cursor=pointer]:
- /url: /codegen/data-binding
- generic [ref=e85]: link
- generic [ref=e86]: Data Binding
- listitem [ref=e87]:
- link "Database" [ref=e88] [cursor=pointer]:
- /url: /codegen/database
- generic [ref=e89]: database
- generic [ref=e90]: Database
- group "Testing" [ref=e91]:
- heading "Testing" [level=3] [ref=e92]
- list "Testing" [ref=e93]:
- listitem [ref=e94]:
- link "Playwright" [ref=e95] [cursor=pointer]:
- /url: /codegen/playwright
- generic [ref=e96]: bug_report
- generic [ref=e97]: Playwright
- listitem [ref=e98]:
- link "Unit Tests" [ref=e99] [cursor=pointer]:
- /url: /codegen/unit-tests
- generic [ref=e100]: science
- generic [ref=e101]: Unit Tests
- listitem [ref=e102]:
- link "Storybook" [ref=e103] [cursor=pointer]:
- /url: /codegen/storybook
- generic [ref=e104]: auto_stories
- generic [ref=e105]: Storybook
- group "System" [ref=e106]:
- heading "System" [level=3] [ref=e107]
- list "System" [ref=e108]:
- listitem [ref=e109]:
- link "Settings" [ref=e110] [cursor=pointer]:
- /url: /codegen/settings
- generic [ref=e111]: settings
- generic [ref=e112]: Settings
- listitem [ref=e113]:
- link "Documentation" [ref=e114] [cursor=pointer]:
- /url: /codegen/docs
- generic [ref=e115]: description
- generic [ref=e116]: Documentation
- listitem [ref=e117]:
- link "Features" [ref=e118] [cursor=pointer]:
- /url: /codegen/features
- generic [ref=e119]: toggle_on
- generic [ref=e120]: Features
- listitem [ref=e121]:
- link "Errors" [ref=e122] [cursor=pointer]:
- /url: /codegen/errors
- generic [ref=e123]: error
- generic [ref=e124]: Errors
- listitem [ref=e125]:
- link "Persistence" [ref=e126] [cursor=pointer]:
- /url: /codegen/persistence
- generic [ref=e127]: storage
- generic [ref=e128]: Persistence
- listitem [ref=e129]:
- link "PWA" [ref=e130] [cursor=pointer]:
- /url: /codegen/pwa
- generic [ref=e131]: install_desktop
- generic [ref=e132]: PWA
- main [ref=e133]:
- generic [ref=e139]:
- generic [ref=e140]:
- heading "Project Dashboard" [level=1] [ref=e141]
- paragraph [ref=e142]: Overview of your CodeForge project
- generic [ref=e143]:
- generic [ref=e144]:
- generic [ref=e146]:
- generic [ref=e148]: task_alt
- text: Project Completeness
- generic [ref=e149]:
- generic [ref=e151]: 70%
- generic [ref=e153]: Ready to Export
- progressbar [ref=e154]
- paragraph [ref=e156]: Great progress! Consider adding more tests.
- generic [ref=e157]:
- generic [ref=e159]:
- generic [ref=e161]: build_circle
- text: GitHub Build Status
- generic [ref=e162]:
- generic [ref=e163]:
- generic [ref=e164]: Build
- generic [ref=e165]: Passing
- generic [ref=e167]:
- generic [ref=e168]: Type Check
- generic [ref=e169]: Passing
- generic [ref=e171]:
- generic [ref=e172]: Lint
- generic [ref=e173]: Passing
- generic [ref=e175]:
- generic [ref=e176]: E2E Tests
- generic [ref=e177]: Idle
- generic [ref=e179]:
- generic [ref=e181]:
- generic [ref=e182]:
- generic [ref=e183]: Code Files
- generic [ref=e185]: code_blocks
- generic [ref=e186]: "4"
- generic [ref=e187]: files in your project
- generic [ref=e189]:
- generic [ref=e190]:
- generic [ref=e191]: Database Models
- generic [ref=e193]: storage
- generic [ref=e194]: "3"
- generic [ref=e195]: Prisma schemas
- generic [ref=e197]:
- generic [ref=e198]:
- generic [ref=e199]: Components
- generic [ref=e201]: view_in_ar
- generic [ref=e202]: "3"
- generic [ref=e203]: React components
- generic [ref=e205]:
- generic [ref=e206]:
- generic [ref=e207]: Workflows
- generic [ref=e209]: account_tree
- generic [ref=e210]: "0"
- generic [ref=e211]: automation flows
- generic [ref=e213]:
- generic [ref=e214]:
- generic [ref=e215]: API Endpoints
- generic [ref=e217]: science
- generic [ref=e218]: "0"
- generic [ref=e219]: Flask routes
- generic [ref=e221]:
- generic [ref=e222]:
- generic [ref=e223]: Test Suites
- generic [ref=e225]: biotech
- generic [ref=e226]: "0"
- generic [ref=e227]: automated tests
- button "Open Next.js Dev Tools" [ref=e233] [cursor=pointer]:
- img [ref=e234]
- alert [ref=e138]

View File

@@ -1,5 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- heading "404" [level=1] [ref=e4]
- heading "This page could not be found." [level=2] [ref=e6]
- alert [ref=e7]

View File

@@ -1,10 +0,0 @@
- generic [ref=e2]:
- banner [ref=e3]:
- heading "EXPLODED DIAGRAMS" [level=1] [ref=e4]
- paragraph [ref=e5]: Modular Technical Illustrations
- navigation [ref=e6]:
- link "Home" [ref=e7] [cursor=pointer]:
- /url: /diagrams
- generic [ref=e8]:
- heading "Categories" [level=2] [ref=e9]
- paragraph [ref=e10]: Loading...

View File

@@ -1,5 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e3]:
- heading "404" [level=1] [ref=e4]
- heading "This page could not be found." [level=2] [ref=e6]
- alert [ref=e7]

View File

@@ -1,10 +0,0 @@
- generic [ref=e2]:
- banner [ref=e3]:
- heading "EXPLODED DIAGRAMS" [level=1] [ref=e4]
- paragraph [ref=e5]: Modular Technical Illustrations
- navigation [ref=e6]:
- link "Home" [ref=e7] [cursor=pointer]:
- /url: /diagrams
- generic [ref=e8]:
- heading "Categories" [level=2] [ref=e9]
- paragraph [ref=e10]: Loading...

View File

@@ -1 +0,0 @@
- alert [ref=e3]

View File

@@ -1,127 +0,0 @@
- generic [active] [ref=e1]:
- alert [ref=e2]
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [ref=e6] [cursor=pointer]:
- img [ref=e7]
- generic [ref=e8]:
- img [ref=e9]
- heading "WorkflowUI" [level=1] [ref=e18]
- generic [ref=e19]:
- button "Notifications" [ref=e21] [cursor=pointer]:
- img [ref=e22]
- generic [ref=e24]: "2"
- button "Switch to dark mode" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e28]:
- complementary "Workflows sidebar" [ref=e29]:
- navigation [ref=e30]:
- generic [ref=e31]:
- heading "Main" [level=3] [ref=e32]
- list "Main navigation" [ref=e33]:
- listitem [ref=e34]:
- link "Dashboard" [ref=e35] [cursor=pointer]:
- /url: /workflowui
- img [ref=e37]
- generic [ref=e39]: Dashboard
- listitem [ref=e40]:
- link "Notifications 2" [ref=e41] [cursor=pointer]:
- /url: /workflowui/notifications
- img [ref=e43]
- generic [ref=e45]: Notifications
- generic [ref=e46]: "2"
- generic [ref=e47]:
- heading "Workflows" [level=3] [ref=e48]
- list "Workflows navigation" [ref=e49]:
- listitem [ref=e50]:
- link "All Workflows" [ref=e51] [cursor=pointer]:
- /url: /workflowui/workflows
- img [ref=e53]
- generic [ref=e55]: All Workflows
- listitem [ref=e56]:
- link "Recent" [ref=e57] [cursor=pointer]:
- /url: /workflowui/workflows/recent
- img [ref=e59]
- generic [ref=e61]: Recent
- listitem [ref=e62]:
- link "Favorites" [ref=e63] [cursor=pointer]:
- /url: /workflowui/workflows/favorites
- img [ref=e65]
- generic [ref=e67]: Favorites
- listitem [ref=e68]:
- link "Templates" [ref=e69] [cursor=pointer]:
- /url: /workflowui/templates
- img [ref=e71]
- generic [ref=e73]: Templates
- generic [ref=e74]:
- heading "System" [level=3] [ref=e75]
- list "System navigation" [ref=e76]:
- listitem [ref=e77]:
- link "Plugins" [ref=e78] [cursor=pointer]:
- /url: /workflowui/plugins
- img [ref=e80]
- generic [ref=e82]: Plugins
- listitem [ref=e83]:
- link "Settings" [ref=e84] [cursor=pointer]:
- /url: /workflowui/settings
- img [ref=e86]
- generic [ref=e88]: Settings
- generic [ref=e89]:
- heading "Help" [level=3] [ref=e90]
- list "Help navigation" [ref=e91]:
- listitem [ref=e92]:
- link "Documentation" [ref=e93] [cursor=pointer]:
- /url: /workflowui/docs
- img [ref=e95]
- generic [ref=e97]: Documentation
- listitem [ref=e98]:
- link "Help & Support" [ref=e99] [cursor=pointer]:
- /url: /workflowui/help
- img [ref=e101]
- generic [ref=e103]: Help & Support
- button "+ New Workflow" [ref=e105] [cursor=pointer]:
- generic [ref=e107]: + New Workflow
- main [ref=e108]:
- generic [ref=e109]:
- generic [ref=e110]:
- generic [ref=e111]:
- img [ref=e113]
- generic [ref=e115]:
- generic [ref=e116]: "23"
- generic [ref=e117]: nodes today
- generic [ref=e118]:
- img [ref=e120]
- generic [ref=e122]:
- generic [ref=e123]: "5"
- generic [ref=e124]: runs today
- generic [ref=e125]:
- img [ref=e127]
- generic [ref=e129]:
- generic [ref=e130]: "1"
- generic [ref=e131]: failed
- generic [ref=e132]:
- img [ref=e134]
- generic [ref=e136]:
- generic [ref=e137]: 1.2h
- generic [ref=e138]: saved today
- generic [ref=e140]:
- generic "First Steps" [ref=e141]:
- img [ref=e142]
- generic "Node Master" [ref=e144]:
- img [ref=e145]
- link "+4 more" [ref=e147] [cursor=pointer]:
- /url: /workflowui/achievements
- generic [ref=e148]:
- generic [ref=e149]:
- heading "Workspaces" [level=1] [ref=e150]
- paragraph [ref=e151]: Organize your projects and workflows
- button "New Workspace" [ref=e152] [cursor=pointer]:
- img [ref=e155]
- generic [ref=e157]: New Workspace
- button "Open my workspace workspace" [ref=e159] [cursor=pointer]:
- generic [ref=e161]: MW
- generic [ref=e162]:
- heading "my workspace" [level=3] [ref=e163]
- paragraph [ref=e164]: No description
- generic [ref=e165]: Created 21/01/1970

View File

@@ -1 +0,0 @@
- 'heading "Application error: a client-side exception has occurred while loading localhost (see the browser console for more information)." [level=2] [ref=e6]'

View File

@@ -1,10 +0,0 @@
- generic [active] [ref=e1]:
- banner [ref=e2]: App Header
- generic [ref=e4]:
- heading "MetaBuilder" [level=3] [ref=e5]
- paragraph [ref=e6]: Data-driven application platform. Configure routes via the admin panel or install a package with a default home page.
- generic [ref=e7]:
- button "Sign In" [ref=e8] [cursor=pointer]: Sign In
- button "DBAL Status" [ref=e9] [cursor=pointer]: DBAL Status
- contentinfo [ref=e10]: App Footer
- alert [ref=e11]

View File

@@ -1,127 +0,0 @@
- generic [active] [ref=e1]:
- alert [ref=e2]
- generic [ref=e3]:
- banner [ref=e4]:
- generic [ref=e5]:
- button "Toggle sidebar" [ref=e6] [cursor=pointer]:
- img [ref=e7]
- generic [ref=e8]:
- img [ref=e9]
- heading "WorkflowUI" [level=1] [ref=e18]
- generic [ref=e19]:
- button "Notifications" [ref=e21] [cursor=pointer]:
- img [ref=e22]
- generic [ref=e24]: "2"
- button "Switch to dark mode" [ref=e25] [cursor=pointer]:
- img [ref=e26]
- generic [ref=e28]:
- complementary "Workflows sidebar" [ref=e29]:
- navigation [ref=e30]:
- generic [ref=e31]:
- heading "Main" [level=3] [ref=e32]
- list "Main navigation" [ref=e33]:
- listitem [ref=e34]:
- link "Dashboard" [ref=e35] [cursor=pointer]:
- /url: /workflowui
- img [ref=e37]
- generic [ref=e39]: Dashboard
- listitem [ref=e40]:
- link "Notifications 2" [ref=e41] [cursor=pointer]:
- /url: /workflowui/notifications
- img [ref=e43]
- generic [ref=e45]: Notifications
- generic [ref=e46]: "2"
- generic [ref=e47]:
- heading "Workflows" [level=3] [ref=e48]
- list "Workflows navigation" [ref=e49]:
- listitem [ref=e50]:
- link "All Workflows" [ref=e51] [cursor=pointer]:
- /url: /workflowui/workflows
- img [ref=e53]
- generic [ref=e55]: All Workflows
- listitem [ref=e56]:
- link "Recent" [ref=e57] [cursor=pointer]:
- /url: /workflowui/workflows/recent
- img [ref=e59]
- generic [ref=e61]: Recent
- listitem [ref=e62]:
- link "Favorites" [ref=e63] [cursor=pointer]:
- /url: /workflowui/workflows/favorites
- img [ref=e65]
- generic [ref=e67]: Favorites
- listitem [ref=e68]:
- link "Templates" [ref=e69] [cursor=pointer]:
- /url: /workflowui/templates
- img [ref=e71]
- generic [ref=e73]: Templates
- generic [ref=e74]:
- heading "System" [level=3] [ref=e75]
- list "System navigation" [ref=e76]:
- listitem [ref=e77]:
- link "Plugins" [ref=e78] [cursor=pointer]:
- /url: /workflowui/plugins
- img [ref=e80]
- generic [ref=e82]: Plugins
- listitem [ref=e83]:
- link "Settings" [ref=e84] [cursor=pointer]:
- /url: /workflowui/settings
- img [ref=e86]
- generic [ref=e88]: Settings
- generic [ref=e89]:
- heading "Help" [level=3] [ref=e90]
- list "Help navigation" [ref=e91]:
- listitem [ref=e92]:
- link "Documentation" [ref=e93] [cursor=pointer]:
- /url: /workflowui/docs
- img [ref=e95]
- generic [ref=e97]: Documentation
- listitem [ref=e98]:
- link "Help & Support" [ref=e99] [cursor=pointer]:
- /url: /workflowui/help
- img [ref=e101]
- generic [ref=e103]: Help & Support
- button "+ New Workflow" [ref=e105] [cursor=pointer]:
- generic [ref=e107]: + New Workflow
- main [ref=e108]:
- generic [ref=e109]:
- generic [ref=e110]:
- generic [ref=e111]:
- img [ref=e113]
- generic [ref=e115]:
- generic [ref=e116]: "23"
- generic [ref=e117]: nodes today
- generic [ref=e118]:
- img [ref=e120]
- generic [ref=e122]:
- generic [ref=e123]: "5"
- generic [ref=e124]: runs today
- generic [ref=e125]:
- img [ref=e127]
- generic [ref=e129]:
- generic [ref=e130]: "1"
- generic [ref=e131]: failed
- generic [ref=e132]:
- img [ref=e134]
- generic [ref=e136]:
- generic [ref=e137]: 1.2h
- generic [ref=e138]: saved today
- generic [ref=e140]:
- generic "First Steps" [ref=e141]:
- img [ref=e142]
- generic "Node Master" [ref=e144]:
- img [ref=e145]
- link "+4 more" [ref=e147] [cursor=pointer]:
- /url: /workflowui/achievements
- generic [ref=e148]:
- generic [ref=e149]:
- heading "Workspaces" [level=1] [ref=e150]
- paragraph [ref=e151]: Organize your projects and workflows
- button "New Workspace" [ref=e152] [cursor=pointer]:
- img [ref=e155]
- generic [ref=e157]: New Workspace
- button "Open my workspace workspace" [ref=e159] [cursor=pointer]:
- generic [ref=e161]: MW
- generic [ref=e162]:
- heading "my workspace" [level=3] [ref=e163]
- paragraph [ref=e164]: No description
- generic [ref=e165]: Created 21/01/1970

View File

@@ -1,10 +0,0 @@
- generic [active] [ref=e1]:
- banner [ref=e2]: App Header
- generic [ref=e4]:
- heading "MetaBuilder" [level=3] [ref=e5]
- paragraph [ref=e6]: Data-driven application platform. Configure routes via the admin panel or install a package with a default home page.
- generic [ref=e7]:
- button "Sign In" [ref=e8] [cursor=pointer]: Sign In
- button "DBAL Status" [ref=e9] [cursor=pointer]: DBAL Status
- contentinfo [ref=e10]: App Footer
- alert [ref=e11]

View File

@@ -1,122 +0,0 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- heading "MetaBuilder" [level=1] [ref=e3]
- paragraph [ref=e4]: Development Stack Portal
- generic [ref=e5]: Applications
- generic [ref=e6]:
- link "W WorkflowUI Visual workflow editor with n8n-style DAG canvas, step library, and JSON workflow execution. /workflowui" [ref=e7] [cursor=pointer]:
- /url: /workflowui
- generic [ref=e8]:
- generic [ref=e9]: W
- heading "WorkflowUI" [level=2] [ref=e10]
- paragraph [ref=e11]: Visual workflow editor with n8n-style DAG canvas, step library, and JSON workflow execution.
- generic [ref=e12]: /workflowui
- link "C CodeForge IDE Low-code application builder with Monaco editor, JSON-driven component architecture. /codegen" [ref=e13] [cursor=pointer]:
- /url: /codegen
- generic [ref=e14]:
- generic [ref=e15]: C
- heading "CodeForge IDE" [level=2] [ref=e16]
- paragraph [ref=e17]: Low-code application builder with Monaco editor, JSON-driven component architecture.
- generic [ref=e18]: /codegen
- link "P Pastebin Code snippet sharing with syntax highlighting, expiration, and privacy controls. /pastebin" [ref=e19] [cursor=pointer]:
- /url: /pastebin
- generic [ref=e20]:
- generic [ref=e21]: P
- heading "Pastebin" [level=2] [ref=e22]
- paragraph [ref=e23]: Code snippet sharing with syntax highlighting, expiration, and privacy controls.
- generic [ref=e24]: /pastebin
- link "E Email Client Full-featured email management with IMAP/SMTP, multi-account support, and search. /emailclient" [ref=e25] [cursor=pointer]:
- /url: /emailclient
- generic [ref=e26]:
- generic [ref=e27]: E
- heading "Email Client" [level=2] [ref=e28]
- paragraph [ref=e29]: Full-featured email management with IMAP/SMTP, multi-account support, and search.
- generic [ref=e30]: /emailclient
- link "D Postgres Dashboard PostgreSQL admin dashboard with query editor, table browser, and performance monitoring. /postgres" [ref=e31] [cursor=pointer]:
- /url: /postgres
- generic [ref=e32]:
- generic [ref=e33]: D
- heading "Postgres Dashboard" [level=2] [ref=e34]
- paragraph [ref=e35]: PostgreSQL admin dashboard with query editor, table browser, and performance monitoring.
- generic [ref=e36]: /postgres
- link "3D Exploded Diagrams Interactive 3D exploded diagram viewer with Three.js and JSCAD integration. /diagrams" [ref=e37] [cursor=pointer]:
- /url: /diagrams
- generic [ref=e38]:
- generic [ref=e39]: 3D
- heading "Exploded Diagrams" [level=2] [ref=e40]
- paragraph [ref=e41]: Interactive 3D exploded diagram viewer with Three.js and JSCAD integration.
- generic [ref=e42]: /diagrams
- link "S Storybook Component library preview with interactive props, documentation, and visual testing. /storybook" [ref=e43] [cursor=pointer]:
- /url: /storybook
- generic [ref=e44]:
- generic [ref=e45]: S
- heading "Storybook" [level=2] [ref=e46]
- paragraph [ref=e47]: Component library preview with interactive props, documentation, and visual testing.
- generic [ref=e48]: /storybook
- link "A Frontend App Main Next.js application with Drizzle ORM, i18n, Clerk auth, and DBAL integration. /app" [ref=e49] [cursor=pointer]:
- /url: /app
- generic [ref=e50]:
- generic [ref=e51]: A
- heading "Frontend App" [level=2] [ref=e52]
- paragraph [ref=e53]: Main Next.js application with Drizzle ORM, i18n, Clerk auth, and DBAL integration.
- generic [ref=e54]: /app
- generic [ref=e55]: Backend Services
- generic [ref=e56]:
- link "API DBAL API C++ database abstraction layer with RESTful CRUD, caching, and search. /api" [ref=e57] [cursor=pointer]:
- /url: /api/health
- generic [ref=e58]:
- generic [ref=e59]: API
- heading "DBAL API" [level=2] [ref=e60]
- paragraph [ref=e61]: C++ database abstraction layer with RESTful CRUD, caching, and search.
- generic [ref=e62]: /api
- link "EM Email Service Flask backend for IMAP/SMTP operations, email sync, and Celery task queue. /email-api" [ref=e63] [cursor=pointer]:
- /url: /email-api/health
- generic [ref=e64]:
- generic [ref=e65]: EM
- heading "Email Service" [level=2] [ref=e66]
- paragraph [ref=e67]: Flask backend for IMAP/SMTP operations, email sync, and Celery task queue.
- generic [ref=e68]: /email-api
- link "SM SMTP Relay Twisted SMTP relay dashboard for email testing and debugging. localhost:8025" [ref=e69] [cursor=pointer]:
- /url: http://localhost:8025
- generic [ref=e70]:
- generic [ref=e71]: SM
- heading "SMTP Relay" [level=2] [ref=e72]
- paragraph [ref=e73]: Twisted SMTP relay dashboard for email testing and debugging.
- generic [ref=e74]: localhost:8025
- generic [ref=e75]: Administration
- generic [ref=e76]:
- link "⚙ Database Settings Manage DBAL adapter configuration, switch backends, and test database connections. /portal/settings.html" [ref=e77] [cursor=pointer]:
- /url: /portal/settings.html
- generic [ref=e78]:
- generic [ref=e79]:
- heading "Database Settings" [level=2] [ref=e80]
- paragraph [ref=e81]: Manage DBAL adapter configuration, switch backends, and test database connections.
- generic [ref=e82]: /portal/settings.html
- link "PMA phpMyAdmin MySQL web administration with table browser, SQL editor, import/export, and user management. /phpmyadmin/" [ref=e83] [cursor=pointer]:
- /url: /phpmyadmin/
- generic [ref=e84]:
- generic [ref=e85]: PMA
- heading "phpMyAdmin" [level=2] [ref=e86]
- paragraph [ref=e87]: MySQL web administration with table browser, SQL editor, import/export, and user management.
- generic [ref=e88]: /phpmyadmin/
- link "ME Mongo Express MongoDB web administration with collection browser, document editor, and query interface. /mongo-express/" [ref=e89] [cursor=pointer]:
- /url: /mongo-express/
- generic [ref=e90]:
- generic [ref=e91]: ME
- heading "Mongo Express" [level=2] [ref=e92]
- paragraph [ref=e93]: MongoDB web administration with collection browser, document editor, and query interface.
- generic [ref=e94]: /mongo-express/
- link "RI RedisInsight Redis GUI with key browser, CLI console, memory analysis, and slow log inspection. /redis-insight/" [ref=e95] [cursor=pointer]:
- /url: /redis-insight/
- generic [ref=e96]:
- generic [ref=e97]: RI
- heading "RedisInsight" [level=2] [ref=e98]
- paragraph [ref=e99]: Redis GUI with key browser, CLI console, memory analysis, and slow log inspection.
- generic [ref=e100]: /redis-insight/
- link "KB Kibana Elasticsearch dashboard with Discover, index management, Dev Tools console, and visualizations. /kibana/" [ref=e101] [cursor=pointer]:
- /url: /kibana/
- generic [ref=e102]:
- generic [ref=e103]: KB
- heading "Kibana" [level=2] [ref=e104]
- paragraph [ref=e105]: Elasticsearch dashboard with Discover, index management, Dev Tools console, and visualizations.
- generic [ref=e106]: /kibana/

View File

@@ -1,122 +0,0 @@
- generic [active] [ref=e1]:
- banner [ref=e2]:
- heading "MetaBuilder" [level=1] [ref=e3]
- paragraph [ref=e4]: Development Stack Portal
- generic [ref=e5]: Applications
- generic [ref=e6]:
- link "W WorkflowUI Visual workflow editor with n8n-style DAG canvas, step library, and JSON workflow execution. /workflowui" [ref=e7] [cursor=pointer]:
- /url: /workflowui
- generic [ref=e8]:
- generic [ref=e9]: W
- heading "WorkflowUI" [level=2] [ref=e10]
- paragraph [ref=e11]: Visual workflow editor with n8n-style DAG canvas, step library, and JSON workflow execution.
- generic [ref=e12]: /workflowui
- link "C CodeForge IDE Low-code application builder with Monaco editor, JSON-driven component architecture. /codegen" [ref=e13] [cursor=pointer]:
- /url: /codegen
- generic [ref=e14]:
- generic [ref=e15]: C
- heading "CodeForge IDE" [level=2] [ref=e16]
- paragraph [ref=e17]: Low-code application builder with Monaco editor, JSON-driven component architecture.
- generic [ref=e18]: /codegen
- link "P Pastebin Code snippet sharing with syntax highlighting, expiration, and privacy controls. /pastebin" [ref=e19] [cursor=pointer]:
- /url: /pastebin
- generic [ref=e20]:
- generic [ref=e21]: P
- heading "Pastebin" [level=2] [ref=e22]
- paragraph [ref=e23]: Code snippet sharing with syntax highlighting, expiration, and privacy controls.
- generic [ref=e24]: /pastebin
- link "E Email Client Full-featured email management with IMAP/SMTP, multi-account support, and search. /emailclient" [ref=e25] [cursor=pointer]:
- /url: /emailclient
- generic [ref=e26]:
- generic [ref=e27]: E
- heading "Email Client" [level=2] [ref=e28]
- paragraph [ref=e29]: Full-featured email management with IMAP/SMTP, multi-account support, and search.
- generic [ref=e30]: /emailclient
- link "D Postgres Dashboard PostgreSQL admin dashboard with query editor, table browser, and performance monitoring. /postgres" [ref=e31] [cursor=pointer]:
- /url: /postgres
- generic [ref=e32]:
- generic [ref=e33]: D
- heading "Postgres Dashboard" [level=2] [ref=e34]
- paragraph [ref=e35]: PostgreSQL admin dashboard with query editor, table browser, and performance monitoring.
- generic [ref=e36]: /postgres
- link "3D Exploded Diagrams Interactive 3D exploded diagram viewer with Three.js and JSCAD integration. /diagrams" [ref=e37] [cursor=pointer]:
- /url: /diagrams
- generic [ref=e38]:
- generic [ref=e39]: 3D
- heading "Exploded Diagrams" [level=2] [ref=e40]
- paragraph [ref=e41]: Interactive 3D exploded diagram viewer with Three.js and JSCAD integration.
- generic [ref=e42]: /diagrams
- link "S Storybook Component library preview with interactive props, documentation, and visual testing. /storybook" [ref=e43] [cursor=pointer]:
- /url: /storybook
- generic [ref=e44]:
- generic [ref=e45]: S
- heading "Storybook" [level=2] [ref=e46]
- paragraph [ref=e47]: Component library preview with interactive props, documentation, and visual testing.
- generic [ref=e48]: /storybook
- link "A Frontend App Main Next.js application with Drizzle ORM, i18n, Clerk auth, and DBAL integration. /app" [ref=e49] [cursor=pointer]:
- /url: /app
- generic [ref=e50]:
- generic [ref=e51]: A
- heading "Frontend App" [level=2] [ref=e52]
- paragraph [ref=e53]: Main Next.js application with Drizzle ORM, i18n, Clerk auth, and DBAL integration.
- generic [ref=e54]: /app
- generic [ref=e55]: Backend Services
- generic [ref=e56]:
- link "API DBAL API C++ database abstraction layer with RESTful CRUD, caching, and search. /api" [ref=e57] [cursor=pointer]:
- /url: /api/health
- generic [ref=e58]:
- generic [ref=e59]: API
- heading "DBAL API" [level=2] [ref=e60]
- paragraph [ref=e61]: C++ database abstraction layer with RESTful CRUD, caching, and search.
- generic [ref=e62]: /api
- link "EM Email Service Flask backend for IMAP/SMTP operations, email sync, and Celery task queue. /email-api" [ref=e63] [cursor=pointer]:
- /url: /email-api/health
- generic [ref=e64]:
- generic [ref=e65]: EM
- heading "Email Service" [level=2] [ref=e66]
- paragraph [ref=e67]: Flask backend for IMAP/SMTP operations, email sync, and Celery task queue.
- generic [ref=e68]: /email-api
- link "SM SMTP Relay Twisted SMTP relay dashboard for email testing and debugging. localhost:8025" [ref=e69] [cursor=pointer]:
- /url: http://localhost:8025
- generic [ref=e70]:
- generic [ref=e71]: SM
- heading "SMTP Relay" [level=2] [ref=e72]
- paragraph [ref=e73]: Twisted SMTP relay dashboard for email testing and debugging.
- generic [ref=e74]: localhost:8025
- generic [ref=e75]: Administration
- generic [ref=e76]:
- link "⚙ Database Settings Manage DBAL adapter configuration, switch backends, and test database connections. /portal/settings.html" [ref=e77] [cursor=pointer]:
- /url: /portal/settings.html
- generic [ref=e78]:
- generic [ref=e79]:
- heading "Database Settings" [level=2] [ref=e80]
- paragraph [ref=e81]: Manage DBAL adapter configuration, switch backends, and test database connections.
- generic [ref=e82]: /portal/settings.html
- link "PMA phpMyAdmin MySQL web administration with table browser, SQL editor, import/export, and user management. /phpmyadmin/" [ref=e83] [cursor=pointer]:
- /url: /phpmyadmin/
- generic [ref=e84]:
- generic [ref=e85]: PMA
- heading "phpMyAdmin" [level=2] [ref=e86]
- paragraph [ref=e87]: MySQL web administration with table browser, SQL editor, import/export, and user management.
- generic [ref=e88]: /phpmyadmin/
- link "ME Mongo Express MongoDB web administration with collection browser, document editor, and query interface. /mongo-express/" [ref=e89] [cursor=pointer]:
- /url: /mongo-express/
- generic [ref=e90]:
- generic [ref=e91]: ME
- heading "Mongo Express" [level=2] [ref=e92]
- paragraph [ref=e93]: MongoDB web administration with collection browser, document editor, and query interface.
- generic [ref=e94]: /mongo-express/
- link "RI RedisInsight Redis GUI with key browser, CLI console, memory analysis, and slow log inspection. /redis-insight/" [ref=e95] [cursor=pointer]:
- /url: /redis-insight/
- generic [ref=e96]:
- generic [ref=e97]: RI
- heading "RedisInsight" [level=2] [ref=e98]
- paragraph [ref=e99]: Redis GUI with key browser, CLI console, memory analysis, and slow log inspection.
- generic [ref=e100]: /redis-insight/
- link "KB Kibana Elasticsearch dashboard with Discover, index management, Dev Tools console, and visualizations. /kibana/" [ref=e101] [cursor=pointer]:
- /url: /kibana/
- generic [ref=e102]:
- generic [ref=e103]: KB
- heading "Kibana" [level=2] [ref=e104]
- paragraph [ref=e105]: Elasticsearch dashboard with Discover, index management, Dev Tools console, and visualizations.
- generic [ref=e106]: /kibana/

View File

@@ -1,51 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e2]:
- banner [ref=e3]:
- generic [ref=e4]:
- img [ref=e5]
- generic [ref=e7]: Postgres Admin Panel
- button "Logout" [ref=e8] [cursor=pointer]:
- img [ref=e10]
- text: Logout
- list [ref=e16]:
- listitem [ref=e17]:
- button "Tables" [ref=e18] [cursor=pointer]:
- img [ref=e20]
- generic [ref=e23]: Tables
- listitem [ref=e24]:
- button "SQL Query" [ref=e25] [cursor=pointer]:
- img [ref=e27]
- generic [ref=e30]: SQL Query
- listitem [ref=e31]:
- button "Query Builder" [ref=e32] [cursor=pointer]:
- img [ref=e34]
- generic [ref=e37]: Query Builder
- listitem [ref=e38]:
- button "Table Manager" [ref=e39] [cursor=pointer]:
- img [ref=e41]
- generic [ref=e44]: Table Manager
- listitem [ref=e45]:
- button "Column Manager" [ref=e46] [cursor=pointer]:
- img [ref=e48]
- generic [ref=e51]: Column Manager
- listitem [ref=e52]:
- button "Constraints" [ref=e53] [cursor=pointer]:
- img [ref=e55]
- generic [ref=e58]: Constraints
- listitem [ref=e59]:
- button "Indexes" [ref=e60] [cursor=pointer]:
- img [ref=e62]
- generic [ref=e65]: Indexes
- main [ref=e66]:
- tabpanel [ref=e68]:
- generic [ref=e70]:
- heading "Database Tables" [level=5] [ref=e71]
- list [ref=e73]:
- listitem [ref=e74]:
- generic [ref=e75]: No tables found
- alert [ref=e76]:
- img [ref=e78]
- generic [ref=e80]: Failed to fetch tables
- button "Close" [ref=e82] [cursor=pointer]:
- img [ref=e83]
- alert [ref=e85]

View File

@@ -1,20 +0,0 @@
- generic [active] [ref=e1]:
- generic [ref=e2]:
- banner [ref=e3]:
- heading "EXPLODED DIAGRAMS" [level=1] [ref=e4]
- paragraph [ref=e5]: Modular Technical Illustrations
- navigation [ref=e6]:
- link "Home" [ref=e7] [cursor=pointer]:
- /url: /diagrams
- generic [ref=e8]:
- heading "Categories" [level=2] [ref=e9]
- generic [ref=e10]:
- link "RC Vehicles Radio controlled cars, trucks, and buggies" [ref=e11] [cursor=pointer]:
- /url: /diagrams/rc
- heading "RC Vehicles" [level=4] [ref=e12]
- paragraph [ref=e13]: Radio controlled cars, trucks, and buggies
- link "Automotive Car and vehicle drivetrain components" [ref=e14] [cursor=pointer]:
- /url: /diagrams/automotive
- heading "Automotive" [level=4] [ref=e15]
- paragraph [ref=e16]: Car and vehicle drivetrain components
- alert [ref=e17]

24
.vscode/settings.json vendored
View File

@@ -1,5 +1,5 @@
{
"cmake.sourceDirectory": "/Users/rmac/Documents/metabuilder/gameengine",
"cmake.sourceDirectory": "/Users/rmac/Documents/GitHub/metabuilder/frontends/qt6",
"chat.mcp.discovery.enabled": {
"claude-desktop": true,
"windsurf": true,
@@ -59,25 +59,5 @@
"https://registry.npmjs.org/*": true
},
"claudeCode.allowDangerouslySkipPermissions": true,
"claudeCode.initialPermissionMode": "bypassPermissions",
"files.watcherExclude": {
"**/node_modules/**": true,
"**/.git/**": true,
"**/build/**": true,
"**/_build/**": true,
"**/dist/**": true,
"**/playwright-report/**": true,
"**/test-results/**": true,
"**/.next/**": true,
"**/coverage/**": true
},
"search.exclude": {
"**/node_modules": true,
"**/build": true,
"**/_build": true,
"**/dist": true,
"**/.git": true,
"**/playwright-report": true,
"**/test-results": true
}
"claudeCode.initialPermissionMode": "bypassPermissions"
}

190
AGENTS.md
View File

@@ -1,190 +0,0 @@
# MetaBuilder — Agent Guide
**Last Updated**: 2026-03-04
Quick-start for AI agents (Claude Code, Copilot, etc.) working on this codebase.
Read CLAUDE.md for the full guide. This file covers agent-specific patterns and shortcuts.
---
## What's Running
```
http://localhost/pastebin # Next.js UI
http://localhost/pastebin-api # Flask auth (register, login, JWT)
http://localhost:8080 # DBAL C++ REST API (entities)
```
**Test accounts**: `demo/demo1234`, `alice/alice1234`, `bob/bob12345`
---
## Architecture in 30 Seconds
```
Browser (Next.js + Redux + IndexedDB)
└── Flask (JWT auth, Python runner) frontends/pastebin/backend/
└── DBAL C++ daemon (REST API) dbal/production/
└── PostgreSQL (prod)
```
**DBAL event flow on user registration**:
```
POST /pastebin/pastebin/User
└── handleCreate() → dispatchAsync("pastebin.User.created")
└── detached thread → on_user_created.json (15 nodes)
└── 2 namespaces + 5 seed snippets created
```
---
## Key Files to Know
| Path | What it is |
|------|-----------|
| `dbal/shared/api/schema/entities/` | JSON entity schemas — SOURCE OF TRUTH (39 entities) |
| `dbal/shared/api/schema/events/event_config.json` | Event → workflow mappings |
| `dbal/shared/api/schema/workflows/` | JSON workflow definitions |
| `dbal/shared/api/schema/auth/auth.json` | JWT + ACL rules |
| `dbal/shared/seeds/database/` | Declarative seed data (JSON, loaded at startup) |
| `dbal/production/src/workflow/` | C++ workflow engine (WfEngine, WfExecutor, steps/) |
| `dbal/production/src/daemon/server_routes.cpp` | Route registration + auto-seed startup |
| `frontends/pastebin/backend/app.py` | Flask JWT auth + Python runner |
| `frontends/pastebin/src/` | Next.js React app |
| `deployment/docker-compose.stack.yml` | Full stack compose |
| `deployment/build-apps.sh` | Build + deploy helper |
---
## Before You Touch Anything
```bash
# Search docs first (SQLite FTS5)
cd docs && python3 docs.py search "topic"
cd txt && python3 reports.py search "topic"
# Check what's already there
ls dbal/shared/api/schema/entities/
ls dbal/shared/seeds/database/
# Logs
docker logs -f metabuilder-dbal
docker logs -f metabuilder-pastebin-backend
```
---
## Deploy Commands
```bash
cd deployment
# Full rebuild + restart
./build-apps.sh --force dbal pastebin
docker compose -f docker-compose.stack.yml up -d
# Flask backend (separate from Next.js)
docker compose -f docker-compose.stack.yml build pastebin-backend
docker compose -f docker-compose.stack.yml up -d pastebin-backend
# dbal-init volume (schema volume container — rebuild when entity JSON changes)
docker compose -f docker-compose.stack.yml build dbal-init
docker compose -f docker-compose.stack.yml up dbal-init
```
---
## Entity Schema Format (JSON)
All schemas live in `dbal/shared/api/schema/entities/*.json`.
```json
{
"name": "MyEntity",
"tenantId": "pastebin",
"package": "pastebin",
"fields": [
{ "name": "id", "type": "uuid", "primary": true },
{ "name": "name", "type": "string", "required": true },
{ "name": "userId", "type": "uuid", "required": true },
{ "name": "tenantId", "type": "string", "required": true },
{ "name": "createdAt", "type": "timestamp", "required": true }
]
}
```
After schema changes: `python3 dbal/shared/tools/codegen/gen_types.py`
---
## Seed Data Format (JSON)
All seed files in `dbal/shared/seeds/database/*.json`. Idempotent — skipped if records exist.
```json
{
"entity": "MyEntity",
"records": [
{ "id": "uuid-here", "name": "Example", "tenantId": "pastebin", "createdAt": 0 }
],
"metadata": { "bootstrap": true }
}
```
For multi-document seeds (array of seed objects): wrap in `[...]` at top level.
**User passwords**: Generate werkzeug hashes inside the container:
```bash
docker exec metabuilder-pastebin-backend python3 -c \
"from werkzeug.security import generate_password_hash; print(generate_password_hash('mypassword'))"
```
---
## Workflow Step Types
| Type | What it does |
|------|-------------|
| `dbal.uuid` | Generates UUID v4, stores via `outputs` |
| `dbal.timestamp` | Current timestamp (ms), stores via `outputs` |
| `dbal.entity.create` | `client.createEntity(entity, data)` |
| `dbal.entity.get` | `client.getEntity(entity, id)` |
| `dbal.entity.list` | `client.listEntities(entity, options)` |
| `dbal.var.set` | `ctx.set(key, value)` |
| `dbal.log` | `spdlog::info(message)` |
Context variable resolution: `"${var_name}"`, `"${event.userId}"`, `"prefix-${name}-suffix"`
---
## Rules (Non-Negotiable)
1. **Multi-tenant always**: Every DBAL query filters by `tenantId`. No exceptions.
2. **JSON not YAML**: All schemas, events, workflows, seeds — pure JSON. yaml-cpp removed.
3. **Seed data in `dbal/shared/seeds/`** — never hardcode in Flask Python or C++.
4. **No hardcoded entity names** — loaded from schema JSON.
5. **Call `ensureClient()` before any DB op in `registerRoutes()`**`dbal_client_` starts null.
6. **`build-apps.sh pastebin` ≠ Flask** — that only rebuilds Next.js. Flask needs `docker compose build pastebin-backend`.
---
## Common Traps
| Trap | Fix |
|------|-----|
| nlohmann/json iterator `it->second` | Use `it.value()` |
| dbal-init volume stale after schema rename | `docker compose build dbal-init && docker compose up dbal-init` |
| `.dockerignore` blocks `dbal/shared/seeds/` | Add `!dbal/shared/seeds/database` |
| Seed segfaults on startup | Missing `ensureClient()` guard |
| Seed runs every restart | `skipIfExists` check broken — verify entity name matches schema |
| Werkzeug scrypt not on host Python | Generate inside running container with `docker exec` |
---
## Pastebin Stack URLs (dev)
| Service | URL | Auth |
|---------|-----|------|
| UI | `http://localhost/pastebin` | JWT cookie |
| Flask auth API | `http://localhost/pastebin-api/api/auth/*` | — |
| DBAL entities | `http://localhost:8080/{tenant}/{package}/{entity}` | Bearer JWT |
| DBAL health | `http://localhost:8080/health` | — |

391
CLAUDE.md
View File

@@ -1,391 +0,0 @@
# MetaBuilder - AI Assistant Guide
**Last Updated**: 2026-03-04 | **Status**: Phase 2 & 3 Complete, Universal Platform in Progress
**Scale**: 27,826+ files across 34 directories | **Philosophy**: 95% JSON config, 5% TS/C++ infrastructure
**Documentation**: Code = Doc (self-documenting Python scripts with argparse)
---
## Code = Doc Principle
All documentation is executable code. No separate markdown docs.
```bash
# Entry points (each with --help)
./metabuilder.py --help # Root project manager
./codegen/codegen.py --help # CodeForge IDE
./pastebin/pastebin.py --help # Pastebin
./gameengine/gameengine.py --help # Game engine
./postgres/postgres.py --help # PostgreSQL dashboard
./mojo/mojo.py --help # Mojo compiler
./deployment/build-base-images.sh --list # Docker base images
# Documentation (SQLite3 + FTS5 full-text search)
cd txt && python3 reports.py search "query" # 212 reports
cd docs && python3 docs.py search "query" # 217 docs, 13 categories
python3 docs.py list --category guides
```
---
## Completed Milestones (All ✅)
- **Mar 4**: DBAL C++ event-driven workflow engine (`pastebin.User.created` → 15-node JSON workflow → seeded namespaces + snippets), full YAML→JSON migration (63 files, yaml-cpp removed), JWT auth + JSON ACL, declarative seed data (`dbal/shared/seeds/database/`), i18n (EN/ES) across all pastebin components, dark/light theme switcher
- **Feb 7**: Game engine CLI args (`--bootstrap`, `--game`), 27/27 tests passing (100%)
- **Feb 6**: 6 new DB backends (total 14), SQLite3 doc migration, Docker dev container, WorkflowUI E2E (92.6%)
- **Feb 5**: WorkflowUI mock DBAL testing, Settings/Help pages, DBAL env var config
- **Feb 4**: SQLiteAdapter generic refactoring, YAML Schema Spec 2.0, Dynamic entity loading (TS+C++), DBAL hooks integration, FakeMUI migration
- **Feb 3**: Visual workflow editor (n8n-style), Dynamic plugin registry (152 nodes)
- **Feb 2**: WorkflowUI migration to root packages (77% file reduction)
- **Feb 1**: CodeQL search, FakeMUI organization, Email components (22)
- **Jan 24**: Dependency fixes, testing library standardization
- **Jan 23**: Email client (Phases 1-5), Mojo compiler, FakeMUI restructuring, dependency remediation
**Details**: Search `cd txt && python3 reports.py search "topic"` for full completion reports.
---
## Directory Index
| Directory | Files | Description |
|-----------|-------|-------------|
| `dbal/` | 495 | Database Abstraction Layer (C++ daemon + shared schemas) |
| `workflow/` | 765 | DAG workflow engine, multi-language plugins |
| `frontends/` | 495 | CLI (C++), Qt6 (QML), Next.js (React) |
| `packages/` | 550 | 62 modular feature packages |
| `fakemui/` | 758 | Material UI clone (145 React + 421 icons) |
| `gameengine/` | 2,737 | SDL3/bgfx 2D/3D game engine |
| `codegen/` | 1,926 | CodeForge IDE (React+Monaco) |
| `pastebin/` | 1,114 | Code snippet sharing (Next.js) |
| `exploded-diagrams/` | 17,565 | Interactive 3D exploded diagrams |
| `schemas/` | 105 | JSON Schema validation |
| `services/` | 29 | Media daemon (FFmpeg/ImageMagick) |
| `postgres/` | 212 | PostgreSQL admin dashboard |
| `mojo/` | 82 | Mojo compiler + language examples |
| `docs/` | 1 DB | SQLite3 (217 docs, 13 categories, FTS5) |
| `txt/` | 1 DB | SQLite3 (212 reports, FTS5, archives) |
| `old/` | 149 | Legacy Spark implementation |
| `.github/` | 52 | GitHub Actions, templates |
*Other standalone: pcbgenerator, packagerepo, cadquerywrapper, sparkos, storybook, dockerterminal, smtprelay, caproverforge, repoforge, emailclient, prisma, deployment, spec, scripts, config, e2e*
---
## Core Principles
### 1. 95% Data, 5% Code
- UI, workflows, pages, business logic = **JSON**
- Entities NEVER hardcoded - loaded from JSON schemas
- Adapters NEVER hardcoded - discovered dynamically
### 2. Schema-First Development
```
dbal/shared/api/schema/entities/ # JSON entities (SOURCE OF TRUTH)
schemas/package-schemas/ # JSON validation schemas (27 total)
dbal/shared/seeds/database/ # Declarative JSON seed data
```
### 3. Multi-Tenant by Default
Every query MUST filter by `tenantId` - no exceptions.
### 4. Data Access Hierarchy
```
1. Redux + redux-persist - Client-side state (IndexedDB)
2. DBAL hooks (fetch) - Server data via C++ DBAL REST API
3. Raw SQL - NEVER
```
### 5. One Lambda Per File
`src/lib/users/createUser.ts` - one function per file.
### 6. JSON Script for Business Logic
Workflows defined in JSON with version 2.2.0 format.
---
## Key Subsystems
### DBAL (`dbal/`)
C++ REST API daemon. Client-side persistence handled by `@metabuilder/redux-persist` (IndexedDB).
```
dbal/
├── production/ # C++ daemon - SQLite, PostgreSQL, MySQL, Drogon HTTP
│ ├── src/config/ # EnvConfig (env vars, NO hardcoded paths)
│ ├── src/workflow/ # Event-driven workflow engine (WfEngine, WfExecutor, 7 step types)
│ ├── src/auth/ # JWT validation + JSON ACL config
│ ├── build-config/# Dockerfile, CMakeLists, conanfile (no yaml-cpp — JSON only)
│ ├── templates/sql/# Jinja2 SQL templates (Inja library)
│ └── .env.example # ~30 config options documented
├── shared/api/schema/
│ ├── entities/ # JSON entity definitions (39 entities, SOURCE OF TRUTH)
│ ├── events/ # event_config.json → workflow mappings
│ ├── workflows/ # on_user_created.json etc.
│ └── auth/ # auth.json (JWT + ACL rules)
└── shared/seeds/database/ # Declarative JSON seed data (auto-loaded at startup)
```
**Workflow Engine**: `pastebin.User.created` → detached thread → `on_user_created.json` → Default + Examples namespaces + 5 snippet templates. Event dispatch wraps `send_success` callback in entity route handler.
**Auto-Seed**: `DBAL_SEED_ON_STARTUP=true``SeedLoaderAction::loadSeeds()` in `registerRoutes()`. Seed files are idempotent (skip if records exist). Must call `ensureClient()` before seeding — `dbal_client_` is null during route registration.
**JWT Auth**: `DBAL_AUTH_CONFIG=/app/schemas/auth/auth.json` — defines which endpoints require auth and what roles can access them.
**Entity Categories**: Core (user, session, workflow, package, ui_page), Access (credential, component_node, page_config), Packages (forum, notification, audit_log, media, irc, streaming), Domain (product, game, artist, video)
**14 Database Backends**:
| Adapter | Backend | Notes |
|---------|---------|-------|
| memory | In-memory | Testing/development |
| sqlite | SQLite | Embedded, generic CRUD via templates |
| postgres | PostgreSQL | Direct connection, no ORM |
| mysql | MySQL | Direct connection |
| mariadb | MariaDB | Reuses mysql adapter |
| cockroachdb | CockroachDB | Reuses postgres adapter |
| mongodb | MongoDB | mongo-cxx-driver, JSON↔BSON |
| redis | Redis | Cache layer (L1/L2 with primary DB) |
| elasticsearch | Elasticsearch | Search layer (full-text, analytics) |
| cassandra | Cassandra | Wide-column store |
| surrealdb | SurrealDB | Multi-model (docs/graphs/KV) |
| supabase | Supabase REST/Direct | PostgreSQL + REST + Realtime + RLS |
| prisma | Prisma | ORM, HTTP bridge |
**Config**: `DBAL_SCHEMA_DIR`, `DBAL_TEMPLATE_DIR`, `DATABASE_URL` (adapter options as query strings)
**Endpoints**: `/health`, `/version`, `/status`, `/{tenant}/{package}/{entity}` (RESTful CRUD)
**Multi-Adapter Patterns**:
- **Redis caching**: `DBAL_CACHE_URL=redis://localhost:6379/0?ttl=300&pattern=read-through`
- **Elasticsearch search**: `DBAL_SEARCH_URL=http://localhost:9200?index=dbal_search&refresh=true`
- Patterns: read-through, write-through, cache-aside, dual-write, CDC, search-first
### Workflow Engine (`workflow/`)
Multi-language: executors (TS, Python, C++), plugins (C++/16 categories, Python, TS, Go, Rust, Mojo), 19 example workflows. Dynamic plugin registry at `/api/plugins` (152 nodes).
### Game Engine (`gameengine/`)
SDL 3.2.20, bgfx 1.129, MaterialX 1.39.1, Assimp, Bullet3, Box2D, EnTT 3.16.0, FFmpeg 8.0.1. 36 service interfaces. CLI: `--bootstrap bootstrap_mac --game seed`.
### CodeForge IDE (`codegen/`)
~420 TSX files (legacy) → 338 JSON definitions (target). See `codegen/CLAUDE.md`.
### FakeMUI (`fakemui/`)
167 components (145 core + 22 email) across 11 categories. Import from `@metabuilder/fakemui`. React/TS, QML (104+), Python (15), 421 icons, 78 SCSS modules.
### React Hooks (`hooks/`)
`@metabuilder/hooks` (30 hooks), `@metabuilder/hooks-utils` (useTableState, useAsyncOperation, useDebounced, useThrottled), `@metabuilder/hooks-forms` (useFormBuilder). Multi-version peer deps (React 18/19, Redux 8/9).
### Redux
12 packages: hooks, hooks-utils, hooks-forms, core-hooks, api-clients, hooks-*, redux-slices, service-adapters, timing-utils. Active in: workflowui, frontends/nextjs, codegen, pastebin.
### Email Client
Phases 1-5 complete (frontend). 4 DBAL schemas, 22 FakeMUI components, 4 Redux slices, 6 hooks, API endpoints. Phases 6-8 TODO: workflow plugins, Flask backend, Docker.
---
## Package System (`packages/`)
62 packages: Admin (7), UI Core (8), Dev Tools (7), Features (6), Testing (4).
```
packages/{packageId}/
├── package.json, components/ui.json, page-config/
├── permissions/roles.json, workflow/*.jsonscript
├── styles/tokens.json, tests/
```
---
## API Routing
```
/api/v1/{tenant}/{package}/{entity}[/{id}[/{action}]]
```
Rate limits: Login 5/min, Register 3/min, List 100/min, Mutations 50/min.
---
## Architecture
```
Frontends (CLI C++ | Qt6 QML | Next.js React)
→ Redux + redux-persist (IndexedDB, client-side state)
→ DBAL C++ daemon (REST API, 14 backends)
→ Database (SQLite dev | PostgreSQL prod)
```
---
## Common Commands
```bash
npm run dev / build / typecheck / lint / test:e2e
npm run build --workspaces
cd deployment && ./build-base-images.sh # Build Docker base images
# Deploy full stack
cd deployment && docker compose -f docker-compose.stack.yml up -d
# Build & deploy specific apps
./build-apps.sh --force dbal pastebin # Next.js frontend only
docker compose -f docker-compose.stack.yml build pastebin-backend # Flask backend
# DBAL logs / seed verification
docker logs -f metabuilder-dbal
docker logs metabuilder-dbal 2>&1 | grep -i "workflow\|seed"
# Force re-seed
curl -X POST http://localhost:8080/admin/seed \
-H "Authorization: Bearer $DBAL_ADMIN_TOKEN" -d '{"force": true}'
```
Pre-commit: `npm run build && npm run typecheck && npm run lint && npm run test:e2e`
---
## Coding Standards
### Code Quality Rules
- One lambda per file, no @ts-ignore, no implicit any, no dead code
- JSDoc on public APIs, self-documenting names
- FULL implementations only - no WIP code on main
- No disabled tests (DISABLED_, @skip)
### No Work-In-Progress Code
- No `-wip`, `-todo`, `-temp` directories
- All code is 100% complete OR not included
- Incomplete work on feature branches only
### UI/Styling
- **workflowui + new projects**: FakeMUI only (`@metabuilder/fakemui`)
- **Legacy projects**: Radix UI + Tailwind acceptable
- **Never**: Direct @mui/material imports in workflowui
### WorkflowUI Components
- Atomic components <100 LOC, SCSS modules, no sx prop
- Categories: layout/, cards/, forms/, navigation/, feedback/
- Import pattern: `@/components/{domain}/{Component}`
### Security Checklist
- Input validation, no XSS (no innerHTML with user data), no SQL injection
- Passwords hashed SHA-512, no secrets committed, multi-tenant tenantId filtering
### Declarative-First
Ask: Could this be JSON config? Could a generic renderer handle this? Is it filtering by tenantId?
---
## Dependency Management
### Conan (C++)
Updated: cpr, lua, sol2, cmake, qt, ninja, sqlite3, fmt, spdlog, shaderc. Run `conan install . --build=missing`.
### npm
Multi-version peer deps. React 18/19, TypeScript 5.9.3, Next.js 14-16, @reduxjs/toolkit 1.9/2.5. Run `npm install` at root.
### Workflow Plugins
- Python: `requirements.txt` (Python 3.9+)
- Go: `go.mod` + `go.work` (Go 1.21+, stdlib only)
- TypeScript: `@metabuilder/workflow: ^3.0.0`
### Known Issues
- postgres dashboard uses @mui/material directly (should migrate to FakeMUI)
- 7 moderate npm vulnerabilities (lodash in @prisma/dev, LOW production risk)
- eslint/vite version conflicts in some workspaces (partially fixed)
---
## AI Assistant Directives
**Must-Follow** (No Exceptions):
1. Read CLAUDE.md first before any work
2. IMPLEMENT, don't delete - fix compilation errors properly
3. Use Explore agent for feasibility checks and planning
4. Plan before coding - list affected files, determine scope
5. CHECK before DELETE - `git show HEAD:path` first
6. Use subagents for complex work
7. Update CLAUDE.md with new gotchas/patterns
8. Reports → `reports.db`, Docs → `docs.db` (SQLite, not markdown files)
9. Git: `git add` on project root first, then commit
10. Use `mv` not `cp` (prevents duplicates)
11. Log long commands: `| tee txt/command-$(date +%Y%m%d-%H%M%S).log`
12. Search SQLite before browsing files
### Gotchas & Lessons Learned
| Gotcha | Prevention |
|--------|-----------|
| Conan profile in Docker mount | Run `conan profile detect` INSIDE cache-mounted RUN |
| Missing types after refactor | Verify all referenced types exist before committing |
| Headers in src/ not include/ | Use relative paths or fix build include dirs |
| No logs for long commands | ALWAYS pipe to txt/*.log |
| Dockerfile `build/` conflict | Use `_build/` |
| Drogon wildcard routes | Check docs for path param syntax |
| `cp` instead of `mv` | ALWAYS use `mv` to relocate |
| Deleting without checking | ALWAYS `git show HEAD:path` first |
| Skipping Explore agent | Always Explore before implementation |
| Version conflicts (eslint, vite) | Check ALL workspaces upfront |
| nlohmann/json includes | Link to ALL targets, not just transitive |
| Docker Compose YAML special chars | Quote env vars: `"DATABASE_URL=:memory:"` |
| nlohmann/json iterators | Use `it.value()` not `it->second` (std::map syntax fails) |
| dbal-init volume stale | Rebuild with `docker compose build dbal-init` when schema file extensions change |
| `.dockerignore` excludes `dbal/` | Whitelist specific subdirs: `!dbal/shared/seeds/database` |
| `build-apps.sh pastebin` ≠ Flask backend | Use `docker compose build pastebin-backend` for Flask |
| `ensureClient()` before startup DB ops | `dbal_client_` is null in `registerRoutes()` — must call `ensureClient()` first |
| Seed data in Flask Python | NEVER — declarative seed data belongs in `dbal/shared/seeds/database/*.json` |
| Werkzeug scrypt on macOS Python | Generate hashes inside running container: `docker exec metabuilder-pastebin-backend python3 -c "..."` |
### Critical Folders to Check Before Any Task
`/redux/`, `/components/`, `/scss/`, `/hooks/`, `/types/`, `/interfaces/`, `/icons/`, `/workflow/`, `/schemas/`, `/packages/`, `/deployment/`, `/docs/docs.db`, `/txt/reports.db`
### Task Workflow
1. Read relevant CLAUDE.md
2. Search SQLite docs: `docs.py search` / `reports.py search`
3. Check if functionality already exists in critical folders
4. Use Explore agent for codebase questions
5. Plan affected files before coding
6. Verify multi-tenant filtering + rate limiting
---
## Definition of Done
A task is complete when:
- **Builds**: Compiles, core functionality works, type safety reasonable
- **Tests**: All pass, new tests added, edge cases covered, multi-tenant verified
- **Deploy**: Docker builds, services healthy, env vars documented, deps install
- **Docs**: CLAUDE.md updated, reports in SQLite, architecture docs updated
- **Security**: Input validation, no XSS/SQLi, passwords hashed, no secrets, rate limited
- **Git**: Clear commit message, co-authored tag, no merge conflicts
**Standards**: IMPLEMENT don't disable. Real solutions over workarounds. TODOs acceptable for future work. Pragmatic over perfect.
**Unacceptable**: Deleting code instead of fixing. Fake implementations. Claiming done when broken.
**Task-Specific**:
- Refactoring: ~100 LOC classes, original functionality preserved, tests pass
- New Adapters: CRUD + bulk + query + metadata ops, connection management, Result<T> errors
- Docker: Multi-stage, BuildKit cache, <500MB runtime, non-root user, health check
- Documentation: Imported to SQLite, categorized, searchable via FTS5
---
## Project Organization
- **Root**: Minimal - config, CI/CD, build, package files only
- **Reports**: `txt/reports.db` - create via `python3 reports.py create "Title" "Content..."`
- **Docs**: `docs/docs.db` - create via `python3 docs.py create "Title" "Content..." --category guides`
- **Rule**: Create directly in SQLite, do NOT create markdown files first
- **File org**: Implementation type first (react/, python/, qml/), component categorization, preserve legacy in archived folders
---
**Status**: Production Ready (Phase 2 Complete)
**Next**: Universal Platform - Core Infrastructure (State Machine, Command Bus, Event Stream, VFS, Frontend Bus)

43
Jenkinsfile vendored
View File

@@ -1,43 +0,0 @@
pipeline {
agent any
tools {
nodejs 'node25'
}
options {
timestamps()
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm ci'
}
}
stage('Lint') {
steps {
sh 'npm run lint'
}
}
stage('Typecheck') {
steps {
sh 'npm run typecheck'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}

View File

@@ -1,199 +0,0 @@
# Quick Reference: MetaBuilder Game Engine
## Latest Work (Session 30)
**Just Completed**:
- ✅ 27 new atomic workflow steps
- ✅ 4 services converted (Audio, Input, Graphics, Scene)
- ✅ 1 dead service deleted (SelectionStateService)
- ✅ All code committed and verified
**Latest Commits**:
```
72520f42c - docs: Session 30 summary
0ff57a22b - chore: Delete SelectionStateService
cc2a594b0 - feat: Convert Audio, Input, Graphics, Scene services
5d8441515 - feat: Implement graphics init workflow steps
```
## Build Commands
```bash
cd /Users/rmac/Documents/metabuilder/gameengine
# Build main app
cmake --build build/Release --target sdl3_app
# Run with default game (seed)
./build/Release/sdl3_app --bootstrap bootstrap_mac --game seed
# Run with specific game
./build/Release/sdl3_app --bootstrap bootstrap_mac --game standalone_cubes
# Run with tracing
./build/Release/sdl3_app --bootstrap bootstrap_mac --game seed --trace
```
## Available Workflow Steps (75+)
### Graphics (10 steps)
- graphics.bgfx.init_viewport
- graphics.bgfx.init_renderer
- graphics.bgfx.init
- graphics.shader.load
- graphics.buffer.create_vertex
- graphics.buffer.create_index
- graphics.frame.begin
- graphics.frame.end
- graphics.draw.submit
- graphics.screenshot.request
### Input (5 steps)
- input.key.pressed
- input.mouse.position
- input.mouse.button.pressed
- input.gamepad.axis
- input.gamepad.button.pressed
### Audio (7 steps)
- audio.play
- audio.pause
- audio.resume
- audio.seek
- audio.set_volume
- audio.stop
- audio.set_looping
### Scene (4+ steps)
- scene.create
- scene.add_geometry
- scene.remove_geometry
- scene.get_bounds
- scene.load
- scene.clear
- scene.update
### Plus 40+ more in:
- Camera (teleport, look_at, build_view_state, set_fov, set_pose)
- Math (add, subtract, multiply, divide, min, max, abs, round, clamp)
- String (concat, split, join, upper, lower, trim, replace, equals, contains)
- Logic (and, or, not, if/then/else, compare)
- Collections (append, count, filter, map, reduce)
- Validation (checkpoint, png validation)
- And many more...
## Architecture
**95% Data-Driven**:
- JSON workflows orchestrate all core systems
- Minimal C++ service code (only integration layer)
- Each step: ~50-100 LOC, testable in isolation
- Dynamic step registration via plugin IDs
**Zero Monolithic Services**:
- Graphics: Complete pipeline via 10 workflow steps
- Input: Full event handling via 5 steps
- Audio: Complete playback control via 7 steps
- Scene: Full 3D management via 4+ steps
## Key Files
**Workflow Definitions**:
```
/gameengine/packages/*/workflows/*.json
- bootstrap_mac/workflows/
- standalone_cubes/workflows/graphics_init_atomic.json
- seed/workflows/demo_gameplay.json
```
**Workflow Step Implementations**:
```
/gameengine/src/services/impl/workflow/
- graphics/ (10 graphics steps)
- workflow_generic_steps/ (5 input + 4 audio steps)
- scene/ (4 scene steps)
- frame/ (40+ frame/game steps)
- workflow_*_step_registrar*.cpp (step discovery)
```
**Main Entry Point**:
```
/gameengine/src/main.cpp
```
## Recent Fixes
1. **Red background issue** (Fixed Feb 11)
- Removed hardcoded color in bgfx initialization
- User confirmed: "pink and flashing thing" renders correctly
2. **Validation tour disabled** (Feb 11)
- Was forcing test checkpoints in gameplay
- Removed from demo_gameplay.json
3. **Dead code cleanup** (Feb 11)
- SelectionStateService deleted (136 LOC)
- No impact on functionality (was orphaned)
## Next Steps (If Continuing)
**High Priority** (2-3 hours each):
1. Shader validation steps (120 LOC)
2. Render coordination steps (80 LOC)
3. Diagnostics steps (100 LOC)
**Medium Priority**:
4. GUI parametric drawing steps (90 LOC)
**Result**: Complete atomic conversion of all non-infrastructure services
## Testing
**Manual Test**:
```bash
./build/Release/sdl3_app --bootstrap bootstrap_mac --game standalone_cubes
# Should see: Pink/orange color, cube animation, window updates
# Expected: 52 FPS rendering
```
**Unit Tests**:
```bash
# Audio step tests exist (369 LOC)
# Located in: gameengine/tests/unit/workflow/test_audio_*.cpp
```
## Performance Notes
- **Build time**: ~2 minutes (full rebuild)
- **Binary size**: 36MB (arm64)
- **Frame rate**: 52 FPS (verified on metal)
- **Memory**: Efficient (atomic-based spy thread ~3-5ns overhead)
## Git Server
**Local Setup**: Hospital bedroom
- Repository size: 8.1GB
- All commits locally safe
- No network dependencies
- Full version history: 60+ commits
## Architecture Philosophy
**95% Data, 5% Code**:
- Configuration: JSON workflows
- Business logic: JSON variable flows
- Infrastructure: C++ (only 5% of code)
- Composition: JSON orchestration of atomic steps
**One Responsibility Per Step**:
- Each workflow step does ONE thing
- Testable in isolation
- Reusable across workflows
- Composable into complex behaviors
---
**Last Updated**: Feb 11, 2026 (Session 30)
**Status**: Production-ready architecture, 95% data-driven
**Git**: All work committed and verified locally

1252
README.md

File diff suppressed because it is too large Load Diff

2957
ROADMAP.md

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
---

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +0,0 @@
{
"status": "failed",
"failedTests": [
"292e21d96a3a4afcf952-9e6b717b184f6f31cb56"
]
}

View File

@@ -1,159 +0,0 @@
# Page snapshot
```yaml
- generic [ref=e1]:
- generic [ref=e2]:
- banner [ref=e3]:
- generic [ref=e4]:
- button "Toggle sidebar" [ref=e5] [cursor=pointer]:
- img [ref=e6]
- generic [ref=e7]:
- img [ref=e8]
- heading "WorkflowUI" [level=1] [ref=e17]
- generic [ref=e18]:
- button "Notifications" [ref=e20] [cursor=pointer]:
- img [ref=e21]
- generic [ref=e23]: "2"
- button "Switch to dark mode" [ref=e24] [cursor=pointer]:
- img [ref=e25]
- generic [ref=e27]:
- complementary "Workflows sidebar" [ref=e28]:
- navigation [ref=e29]:
- generic [ref=e30]:
- heading "Main" [level=3] [ref=e31]
- list "Main navigation" [ref=e32]:
- listitem [ref=e33]:
- link "Dashboard" [ref=e34] [cursor=pointer]:
- /url: /
- img [ref=e36]
- generic [ref=e38]: Dashboard
- listitem [ref=e39]:
- link "Notifications 2" [ref=e40] [cursor=pointer]:
- /url: /notifications
- img [ref=e42]
- generic [ref=e44]: Notifications
- generic [ref=e45]: "2"
- generic [ref=e46]:
- heading "Workflows" [level=3] [ref=e47]
- list "Workflows navigation" [ref=e48]:
- listitem [ref=e49]:
- link "All Workflows" [active] [ref=e50] [cursor=pointer]:
- /url: /workflows
- img [ref=e52]
- generic [ref=e54]: All Workflows
- listitem [ref=e55]:
- link "Recent" [ref=e56] [cursor=pointer]:
- /url: /workflows/recent
- img [ref=e58]
- generic [ref=e60]: Recent
- listitem [ref=e61]:
- link "Favorites" [ref=e62] [cursor=pointer]:
- /url: /workflows/favorites
- img [ref=e64]
- generic [ref=e66]: Favorites
- listitem [ref=e67]:
- link "Templates" [ref=e68] [cursor=pointer]:
- /url: /templates
- img [ref=e70]
- generic [ref=e72]: Templates
- generic [ref=e73]:
- heading "System" [level=3] [ref=e74]
- list "System navigation" [ref=e75]:
- listitem [ref=e76]:
- link "Plugins" [ref=e77] [cursor=pointer]:
- /url: /plugins
- img [ref=e79]
- generic [ref=e81]: Plugins
- listitem [ref=e82]:
- link "Settings" [ref=e83] [cursor=pointer]:
- /url: /settings
- img [ref=e85]
- generic [ref=e87]: Settings
- generic [ref=e88]:
- heading "Help" [level=3] [ref=e89]
- list "Help navigation" [ref=e90]:
- listitem [ref=e91]:
- link "Documentation" [ref=e92] [cursor=pointer]:
- /url: /docs
- img [ref=e94]
- generic [ref=e96]: Documentation
- listitem [ref=e97]:
- link "Help & Support" [ref=e98] [cursor=pointer]:
- /url: /help
- img [ref=e100]
- generic [ref=e102]: Help & Support
- button "+ New Workflow" [ref=e104] [cursor=pointer]:
- generic [ref=e106]: + New Workflow
- main [ref=e107]:
- generic [ref=e108]:
- generic [ref=e109]:
- generic [ref=e110]:
- img [ref=e112]
- generic [ref=e114]:
- generic [ref=e115]: "23"
- generic [ref=e116]: nodes today
- generic [ref=e117]:
- img [ref=e119]
- generic [ref=e121]:
- generic [ref=e122]: "5"
- generic [ref=e123]: runs today
- generic [ref=e124]:
- img [ref=e126]
- generic [ref=e128]:
- generic [ref=e129]: "1"
- generic [ref=e130]: failed
- generic [ref=e131]:
- img [ref=e133]
- generic [ref=e135]:
- generic [ref=e136]: 1.2h
- generic [ref=e137]: saved today
- generic [ref=e139]:
- generic "First Steps" [ref=e140]:
- img [ref=e141]
- generic "Node Master" [ref=e143]:
- img [ref=e144]
- link "+4 more" [ref=e146] [cursor=pointer]:
- /url: /achievements
- generic [ref=e147]:
- generic [ref=e148]:
- heading "Workspaces" [level=1] [ref=e149]
- paragraph [ref=e150]: Organize your projects and workflows
- button "New Workspace" [ref=e151] [cursor=pointer]:
- img [ref=e154]
- generic [ref=e156]: New Workspace
- generic [ref=e157]:
- img [ref=e159]
- heading "No workspaces yet" [level=2] [ref=e161]
- paragraph [ref=e162]: Create your first workspace to organize your projects
- button "Create Your First Workspace" [ref=e163] [cursor=pointer]:
- img [ref=e166]
- generic [ref=e168]: Create Your First Workspace
- generic [ref=e173] [cursor=pointer]:
- button "Open Next.js Dev Tools" [ref=e174]:
- img [ref=e175]
- generic [ref=e178]:
- button "Open issues overlay" [ref=e179]:
- generic [ref=e180]:
- generic [ref=e181]: "0"
- generic [ref=e182]: "1"
- generic [ref=e183]: Issue
- button "Collapse issues badge" [ref=e184]:
- img [ref=e185]
- alert [ref=e187]
- generic "Notifications" [ref=e188]:
- alert [ref=e189]:
- text: ✕Unexpected token '<', "<html> <he"... is not valid JSON
- button "Close notification" [ref=e190] [cursor=pointer]: ×
- alert [ref=e191]:
- text: ✕Unexpected token '<', "<html> <he"... is not valid JSON
- button "Close notification" [ref=e192] [cursor=pointer]: ×
- alert [ref=e193]:
- text: ✕Unexpected token '<', "<html> <he"... is not valid JSON
- button "Close notification" [ref=e194] [cursor=pointer]: ×
- alert [ref=e195]:
- text: ✕Unexpected token '<', "<html> <he"... is not valid JSON
- button "Close notification" [ref=e196] [cursor=pointer]: ×
- alert [ref=e197]:
- text: ✕Unexpected token '<', "<html> <he"... is not valid JSON
- button "Close notification" [ref=e198] [cursor=pointer]: ×
```

View File

@@ -1 +0,0 @@
./gameengine

83
bun.lock Normal file
View File

@@ -0,0 +1,83 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"dependencies": {
"@prisma/client": "^6.19.1",
},
"devDependencies": {
"prisma": "^6.19.1",
},
},
},
"packages": {
"@prisma/client": ["@prisma/client@6.19.1", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"] }, "sha512-4SXj4Oo6HyQkLUWT8Ke5R0PTAfVOKip5Roo+6+b2EDTkFg5be0FnBWiuRJc0BC0sRQIWGMLKW1XguhVfW/z3/A=="],
"@prisma/config": ["@prisma/config@6.19.1", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-bUL/aYkGXLwxVGhJmQMtslLT7KPEfUqmRa919fKI4wQFX4bIFUKiY8Jmio/2waAjjPYrtuDHa7EsNCnJTXxiOw=="],
"@prisma/debug": ["@prisma/debug@6.19.1", "", {}, "sha512-h1JImhlAd/s5nhY/e9qkAzausWldbeT+e4nZF7A4zjDYBF4BZmKDt4y0jK7EZapqOm1kW7V0e9agV/iFDy3fWw=="],
"@prisma/engines": ["@prisma/engines@6.19.1", "", { "dependencies": { "@prisma/debug": "6.19.1", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/fetch-engine": "6.19.1", "@prisma/get-platform": "6.19.1" } }, "sha512-xy95dNJ7DiPf9IJ3oaVfX785nbFl7oNDzclUF+DIiJw6WdWCvPl0LPU0YqQLsrwv8N64uOQkH391ujo3wSo+Nw=="],
"@prisma/engines-version": ["@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "", {}, "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA=="],
"@prisma/fetch-engine": ["@prisma/fetch-engine@6.19.1", "", { "dependencies": { "@prisma/debug": "6.19.1", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/get-platform": "6.19.1" } }, "sha512-mmgcotdaq4VtAHO6keov3db+hqlBzQS6X7tR7dFCbvXjLVTxBYdSJFRWz+dq7F9p6dvWyy1X0v8BlfRixyQK6g=="],
"@prisma/get-platform": ["@prisma/get-platform@6.19.1", "", { "dependencies": { "@prisma/debug": "6.19.1" } }, "sha512-zsg44QUiQAnFUyh6Fbt7c9HjMXHwFTqtrgcX7DAZmRgnkPyYT7Sh8Mn8D5PuuDYNtMOYcpLGg576MLfIORsBYw=="],
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
"c12": ["c12@3.1.0", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="],
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
"citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
"confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="],
"consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
"deepmerge-ts": ["deepmerge-ts@7.1.5", "", {}, "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw=="],
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
"destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
"dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
"effect": ["effect@3.18.4", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA=="],
"empathic": ["empathic@2.0.0", "", {}, "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA=="],
"exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="],
"fast-check": ["fast-check@3.23.2", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="],
"giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": "dist/cli.mjs" }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
"jiti": ["jiti@2.6.1", "", { "bin": "lib/jiti-cli.mjs" }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
"node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
"nypm": ["nypm@0.6.2", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "tinyexec": "^1.0.1" }, "bin": "dist/cli.mjs" }, "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g=="],
"ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
"pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="],
"prisma": ["prisma@6.19.1", "", { "dependencies": { "@prisma/config": "6.19.1", "@prisma/engines": "6.19.1" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": "build/index.js" }, "sha512-XRfmGzh6gtkc/Vq3LqZJcS2884dQQW3UhPo6jNRoiTW95FFQkXFg8vkYEy6og+Pyv0aY7zRQ7Wn1Cvr56XjhQQ=="],
"pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
"tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
}
}

View File

@@ -1,38 +0,0 @@
/**
* ProjectCard Component
* Displays project with metadata
*/
import React from 'react'
import Link from 'next/link'
import type { Project } from '@metabuilder/interfaces/workspace'
import styles from '../../scss/components/cards/project-card.module.scss'
interface ProjectCardProps {
project: Project
[key: string]: any
}
/**
* ProjectCard - Clickable project card with link
*/
export const ProjectCard = ({ project, ...rest }: ProjectCardProps) => {
return (
<Link href={`/project/${project.id}`} className={styles.projectCard} {...rest}>
<div className={styles.cardInner}>
<div
className={styles.media}
style={{ backgroundColor: project.color || 'var(--mat-sys-primary)' }}
/>
<div className={styles.content}>
<h3 className={styles.title}>{project.name}</h3>
<p className={styles.description}>{project.description || 'No description'}</p>
<div className={styles.meta}>
<span>{project.workflowCount || 0} workflows</span>
<span>Updated {new Date(project.updatedAt).toLocaleDateString()}</span>
</div>
</div>
</div>
</Link>
)
}

View File

@@ -1,29 +0,0 @@
/**
* ProjectList Component
* Grid layout for project cards
*/
import React from 'react'
import { ProjectCard } from './ProjectCard'
import type { Project } from '@metabuilder/interfaces/workspace'
interface ProjectListProps {
projects: Project[]
className?: string
[key: string]: any
}
/**
* ProjectList - Grid container for projects
*/
export const ProjectList = ({ projects, className, ...rest }: ProjectListProps) => {
const gridClass = className || 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6'
return (
<div className={gridClass} {...rest}>
{projects.map((project) => (
<ProjectCard key={project.id} project={project} />
))}
</div>
)
}

View File

@@ -1,29 +0,0 @@
/**
* StatCard Component
* Individual stat card with icon and value
*/
import React from 'react'
import { StatIcon } from './StatIcon'
import { StatValue } from './StatValue'
import type { StatItem } from '@metabuilder/interfaces/dashboard'
import styles from '../../scss/components/cards/stat-card.module.scss'
interface StatCardProps {
stat: StatItem
[key: string]: any
}
/**
* StatCard - Composed stat display (icon + value)
*/
export const StatCard = ({ stat, ...rest }: StatCardProps) => {
const className = stat.warning ? `${styles.statCard} ${styles.warning}` : styles.statCard
return (
<div className={className} {...rest}>
<StatIcon icon={stat.icon} color={stat.color} />
<StatValue value={stat.value} label={stat.label} />
</div>
)
}

View File

@@ -1,24 +0,0 @@
/**
* StatIcon Component
* Icon wrapper for stat cards
*/
import React from 'react'
import styles from '../../scss/components/cards/stat-icon.module.scss'
interface StatIconProps {
icon: React.ReactNode
color?: string
[key: string]: any
}
/**
* StatIcon - Displays an icon with styled background
*/
export const StatIcon = ({ icon, color, ...rest }: StatIconProps) => {
return (
<div className={styles.statIcon} style={color ? { color } : undefined} {...rest}>
{icon}
</div>
)
}

View File

@@ -1,25 +0,0 @@
/**
* StatValue Component
* Value and label display for stats
*/
import React from 'react'
import styles from '../../scss/components/cards/stat-value.module.scss'
interface StatValueProps {
value: string | number
label: string
[key: string]: any
}
/**
* StatValue - Displays stat value with label
*/
export const StatValue = ({ value, label, ...rest }: StatValueProps) => {
return (
<div className={styles.statValue} {...rest}>
<span className={styles.value}>{value}</span>
<span className={styles.label}>{label}</span>
</div>
)
}

View File

@@ -1,77 +0,0 @@
// components/cards/TemplateCard.tsx
import React from 'react'
import Link from 'next/link'
import { Card, CardContent, CardActions, Button, Box, Typography } from '../fakemui'
import { TemplateIcon } from './TemplateIcon'
import { TemplateDifficultyBadge } from '../feedback/TemplateDifficultyBadge'
import { TemplateRating } from '../feedback/TemplateRating'
import { Template } from '@metabuilder/interfaces/templates'
import styles from '../../scss/components/cards/template-card.module.scss'
interface TemplateCardProps {
template: Template
[key: string]: any
}
/**
* Template card component - Grid view
* Displays template summary with icon, metadata, and actions
*/
export const TemplateCard = ({ template, ...rest }: TemplateCardProps) => {
return (
<Card
className={styles.templateCard}
data-testid={`template-card-${template.id}`}
role="listitem"
{...rest}
>
{template.metadata.featured && (
<Box className={styles.featuredBadge} aria-label="Featured">
Featured
</Box>
)}
<TemplateIcon
icon={template.icon}
color={template.color}
size="large"
/>
<CardContent className={styles.content}>
<Typography variant="h6" className={styles.title}>
{template.name}
</Typography>
<Typography variant="body2" className={styles.description}>
{template.description}
</Typography>
<Box className={styles.metadata}>
<TemplateDifficultyBadge difficulty={template.difficulty} />
<Box className={styles.metaItem}>
{template.workflows.length} workflow{template.workflows.length !== 1 ? 's' : ''}
</Box>
</Box>
<Box className={styles.stats}>
<TemplateRating rating={template.metadata.rating} />
<Box className={styles.downloads}>
{template.metadata.downloads?.toLocaleString() || 0}
</Box>
</Box>
</CardContent>
<CardActions>
<Button
component={Link}
href={`/templates/${template.id}`}
variant="contained"
fullWidth
>
View Template
</Button>
</CardActions>
</Card>
)
}

View File

@@ -1,35 +0,0 @@
// components/cards/TemplateIcon.tsx
import React from 'react'
import { Box } from '../fakemui'
import styles from '../../scss/components/cards/template-icon.module.scss'
interface TemplateIconProps {
icon: string
color: string
size?: 'small' | 'medium' | 'large'
[key: string]: any
}
/**
* Template icon component
* Displays template icon with background color
*/
export const TemplateIcon = ({
icon,
color,
size = 'medium',
...rest
}: TemplateIconProps) => {
const sizeClass = size === 'large' ? styles.large : size === 'small' ? styles.small : ''
return (
<Box
className={`${styles.templateIcon} ${sizeClass}`}
style={{ backgroundColor: color }}
{...rest}
>
{icon}
</Box>
)
}

View File

@@ -1,73 +0,0 @@
// components/cards/TemplateListItem.tsx
import React from 'react'
import Link from 'next/link'
import { Box, Typography, Button } from '../fakemui'
import { TemplateIcon } from './TemplateIcon'
import { Template } from '@metabuilder/interfaces/templates'
import styles from '../../scss/components/cards/template-list-item.module.scss'
interface TemplateListItemProps {
template: Template
[key: string]: any
}
/**
* Template list item component - List view
* Compact horizontal layout with tags
*/
export const TemplateListItem = ({ template, ...rest }: TemplateListItemProps) => {
const visibleTags = template.tags.slice(0, 3)
const remainingCount = template.tags.length - 3
return (
<Box
className={styles.templateListItem}
data-testid={`template-list-item-${template.id}`}
role="listitem"
{...rest}
>
<TemplateIcon
icon={template.icon}
color={template.color}
size="small"
/>
<Box className={styles.content}>
<Box className={styles.header}>
<Typography variant="h6" className={styles.title}>
{template.name}
</Typography>
{template.metadata.featured && (
<Box className={styles.featuredBadge}> Featured</Box>
)}
</Box>
<Typography variant="body2" className={styles.description}>
{template.description}
</Typography>
<Box className={styles.tags}>
{visibleTags.map((tag) => (
<Box key={tag} className={styles.tag}>
{tag}
</Box>
))}
{remainingCount > 0 && (
<Box className={styles.tag}>+{remainingCount}</Box>
)}
</Box>
</Box>
<Box className={styles.actions}>
<Button
component={Link}
href={`/templates/${template.id}`}
variant="outlined"
>
View
</Button>
</Box>
</Box>
)
}

View File

@@ -1,41 +0,0 @@
/**
* WorkspaceCard Component
* Complete workspace card with icon and content
*/
import React from 'react'
import { WorkspaceIcon } from './WorkspaceIcon'
import { WorkspaceTitle } from './WorkspaceTitle'
import type { Workspace } from '@metabuilder/interfaces/dashboard'
import styles from '../../scss/components/cards/workspace-card.module.scss'
interface WorkspaceCardProps {
workspace: Workspace
onClick?: () => void
[key: string]: any
}
/**
* WorkspaceCard - Interactive workspace card
*/
export const WorkspaceCard = ({ workspace, onClick, ...rest }: WorkspaceCardProps) => {
return (
<article
className={styles.workspaceCard}
onClick={onClick}
onKeyDown={(e) => e.key === 'Enter' && onClick?.()}
tabIndex={0}
role="button"
aria-label={`Open ${workspace.name} workspace`}
data-testid="workspace-card"
{...rest}
>
<WorkspaceIcon name={workspace.name} color={workspace.color} />
<WorkspaceTitle
name={workspace.name}
description={workspace.description}
createdAt={workspace.createdAt}
/>
</article>
)
}

View File

@@ -1,35 +0,0 @@
/**
* WorkspaceIcon Component
* Displays workspace initials/icon
*/
import React from 'react'
import styles from '../../scss/components/cards/workspace-card.module.scss'
interface WorkspaceIconProps {
name: string
color?: string
[key: string]: any
}
/**
* WorkspaceIcon - Workspace initials in colored media area
*/
export const WorkspaceIcon = ({ name, color, ...rest }: WorkspaceIconProps) => {
const initials = name
.split(' ')
.map((w) => w[0])
.join('')
.slice(0, 2)
.toUpperCase()
return (
<div
className={styles.media}
style={{ backgroundColor: color || 'var(--mat-sys-primary)' }}
{...rest}
>
<span className={styles.initials}>{initials}</span>
</div>
)
}

View File

@@ -1,31 +0,0 @@
/**
* WorkspaceTitle Component
* Displays workspace name, description, and metadata
*/
import React from 'react'
import styles from '../../scss/components/cards/workspace-card.module.scss'
interface WorkspaceTitleProps {
name: string
description?: string
createdAt?: string
[key: string]: any
}
/**
* WorkspaceTitle - Workspace text content
*/
export const WorkspaceTitle = ({ name, description, createdAt, ...rest }: WorkspaceTitleProps) => {
return (
<div className={styles.content} {...rest}>
<h3 className={styles.title}>{name}</h3>
<p className={styles.description}>{description || 'No description'}</p>
{createdAt && (
<span className={styles.meta}>
Created {new Date(createdAt).toLocaleDateString()}
</span>
)}
</div>
)
}

View File

@@ -1,11 +0,0 @@
export { ProjectCard } from './ProjectCard';
export { ProjectList } from './ProjectList';
export { StatCard } from './StatCard';
export { StatIcon } from './StatIcon';
export { StatValue } from './StatValue';
export { TemplateCard } from './TemplateCard';
export { TemplateIcon } from './TemplateIcon';
export { TemplateListItem } from './TemplateListItem';
export { WorkspaceCard } from './WorkspaceCard';
export { WorkspaceIcon } from './WorkspaceIcon';
export { WorkspaceTitle } from './WorkspaceTitle';

View File

@@ -1,20 +0,0 @@
import React from 'react'
export interface AutoGridProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
sm?: boolean
lg?: boolean
gap?: string | number
/** Test ID for automated testing */
testId?: string
}
export const AutoGrid: React.FC<AutoGridProps> = ({ children, sm, lg, gap, testId, className = '', ...props }) => (
<div
className={`auto-grid ${sm ? 'auto-grid--sm' : ''} ${lg ? 'auto-grid--lg' : ''} ${gap ? `gap-${gap}` : ''} ${className}`}
data-testid={testId}
{...props}
>
{children}
</div>
)

View File

@@ -1,20 +0,0 @@
import React from 'react'
export interface EditorWrapperProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
sm?: boolean
lg?: boolean
xl?: boolean
/** Test ID for automated testing */
testId?: string
}
export const EditorWrapper: React.FC<EditorWrapperProps> = ({ children, sm, lg, xl, testId, className = '', ...props }) => (
<div
className={`editor-wrapper ${sm ? 'editor-wrapper--sm' : ''} ${lg ? 'editor-wrapper--lg' : ''} ${xl ? 'editor-wrapper--xl' : ''} ${className}`}
data-testid={testId}
{...props}
>
{children}
</div>
)

View File

@@ -1,33 +0,0 @@
import React from 'react'
export interface HeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
children?: React.ReactNode
text?: string
level?: 1 | 2 | 3 | 4 | 5 | 6
variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
/** Test ID for automated testing */
testId?: string
}
/**
* Heading component for section titles
* Maps to Typography variant="h1-h6" or can be used standalone
*/
export const Heading: React.FC<HeadingProps> = ({
children,
text,
level = 2,
variant,
testId,
className = '',
...props
}) => {
const headingLevel = variant ? parseInt(variant.slice(1)) : level
const Tag = `h${headingLevel}` as React.ElementType
return (
<Tag className={`heading heading--level-${headingLevel} ${className}`} data-testid={testId} {...props}>
{text || children}
</Tag>
)
}

View File

@@ -1,192 +0,0 @@
import React from 'react'
import classNames from 'classnames'
import styles from '../../../scss/atoms/label.module.scss'
// Size variants
export type LabelSize = 'sm' | 'md' | 'lg'
// Color variants
export type LabelColor =
| 'primary'
| 'secondary'
| 'error'
| 'success'
| 'warning'
| 'info'
| 'onSurface'
export interface LabelProps extends React.HTMLAttributes<HTMLSpanElement> {
children?: React.ReactNode
/** Size variant: sm (small), md (medium/default), lg (large) */
size?: LabelSize
/** Color variant */
color?: LabelColor
/** Transform text to uppercase */
uppercase?: boolean
/** Show required asterisk indicator */
required?: boolean
/** Enable inline-flex layout for icon alignment */
withIcon?: boolean
/** Associate label with form element */
htmlFor?: string
/** Test ID for automated testing */
testId?: string
}
const sizeClassMap: Record<LabelSize, string | undefined> = {
sm: styles.labelSm,
md: undefined, // default, no extra class needed
lg: styles.labelLg,
}
const colorClassMap: Record<LabelColor, string> = {
primary: styles.labelPrimary,
secondary: styles.labelSecondary,
error: styles.labelError,
success: styles.labelSuccess,
warning: styles.labelWarning,
info: styles.labelInfo,
onSurface: styles.labelOnSurface,
}
export const Label: React.FC<LabelProps> = ({
children,
className,
size = 'md',
color,
uppercase = false,
required = false,
withIcon = false,
testId,
...props
}) => {
const labelClassName = classNames(
styles.label,
sizeClassMap[size],
color && colorClassMap[color],
{
[styles.labelUppercase]: uppercase,
[styles.labelRequired]: required,
[styles.labelWithIcon]: withIcon,
},
className
)
return (
<span className={labelClassName} data-testid={testId} {...props}>
{children}
</span>
)
}
// ============================================================================
// FieldLabel - Form field label component
// ============================================================================
export interface FieldLabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
children?: React.ReactNode
/** Show error styling */
error?: boolean
/** Show focused styling */
focused?: boolean
/** Show required asterisk indicator */
required?: boolean
}
export const FieldLabel: React.FC<FieldLabelProps> = ({
children,
className,
error = false,
focused = false,
required = false,
...props
}) => {
const labelClassName = classNames(
styles.fieldLabel,
{
[styles.fieldLabelError]: error,
[styles.fieldLabelFocused]: focused && !error,
[styles.labelRequired]: required,
},
className
)
return (
<label className={labelClassName} {...props}>
{children}
</label>
)
}
// ============================================================================
// HelperText - Helper text below form fields
// ============================================================================
export interface HelperTextProps extends React.HTMLAttributes<HTMLSpanElement> {
children?: React.ReactNode
/** Show error styling */
error?: boolean
}
export const HelperText: React.FC<HelperTextProps> = ({
children,
className,
error = false,
...props
}) => {
const helperClassName = classNames(
styles.helperText,
{
[styles.helperTextError]: error,
},
className
)
return (
<span className={helperClassName} {...props}>
{children}
</span>
)
}
// ============================================================================
// CounterText - Character counter text
// ============================================================================
export interface CounterTextProps extends React.HTMLAttributes<HTMLSpanElement> {
children?: React.ReactNode
/** Current character count */
count?: number
/** Maximum character limit */
maxLength?: number
/** Show error styling (typically when count > maxLength) */
error?: boolean
}
export const CounterText: React.FC<CounterTextProps> = ({
children,
className,
count,
maxLength,
error = false,
...props
}) => {
const counterClassName = classNames(
styles.counterText,
{
[styles.counterTextError]: error || (count !== undefined && maxLength !== undefined && count > maxLength),
},
className
)
// If count and maxLength provided, render formatted counter
const content = count !== undefined && maxLength !== undefined
? `${count}/${maxLength}`
: children
return (
<span className={counterClassName} {...props}>
{content}
</span>
)
}

View File

@@ -1,206 +0,0 @@
import React from 'react'
import classNames from 'classnames'
import styles from '../../../scss/atoms/panel.module.scss'
// ============================================================================
// Panel Component - Material Design 3
// ============================================================================
export type PanelVariant = 'default' | 'elevated' | 'outlined'
export type PanelFixedPosition = 'br' | 'bl' | 'tr' | 'tl'
export type PanelHeaderVariant = 'primary' | 'secondary' | 'tertiary' | 'surface'
export interface PanelProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
/** Panel visual style */
variant?: PanelVariant
/** Fixed position on screen */
fixedPosition?: PanelFixedPosition
/** Enable collapsible behavior */
collapsible?: boolean
/** Collapsed state (requires collapsible=true) */
collapsed?: boolean
/** Test ID for automated testing */
testId?: string
}
export const Panel: React.FC<PanelProps> = ({
children,
className,
variant = 'default',
fixedPosition,
collapsible = false,
collapsed = false,
testId,
...props
}) => {
const panelClass = classNames(
// Base or variant class
{
[styles.panel]: variant === 'default' && !fixedPosition,
[styles.panelElevated]: variant === 'elevated',
[styles.panelOutlined]: variant === 'outlined',
},
// Fixed position classes
{
[styles.panelFixedBr]: fixedPosition === 'br',
[styles.panelFixedBl]: fixedPosition === 'bl',
[styles.panelFixedTr]: fixedPosition === 'tr',
[styles.panelFixedTl]: fixedPosition === 'tl',
},
// Collapsible state classes
{
[styles.panelCollapsible]: collapsible,
[styles.panelCollapsed]: collapsible && collapsed,
},
className
)
return (
<div className={panelClass} data-testid={testId} role="region" {...props}>
{children}
</div>
)
}
// ============================================================================
// PanelHeader Component
// ============================================================================
export interface PanelHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
/** Header color variant */
variant?: PanelHeaderVariant
/** Make header clickable (for collapsible panels) */
clickable?: boolean
}
export const PanelHeader: React.FC<PanelHeaderProps> = ({
children,
className,
variant = 'primary',
clickable = false,
...props
}) => {
const headerClass = classNames(
{
[styles.panelHeader]: variant === 'primary',
[styles.panelHeaderSecondary]: variant === 'secondary',
[styles.panelHeaderTertiary]: variant === 'tertiary',
[styles.panelHeaderSurface]: variant === 'surface',
[styles.panelHeaderClickable]: clickable,
},
className
)
return (
<div className={headerClass} {...props}>
{children}
</div>
)
}
// ============================================================================
// PanelTitle Component
// ============================================================================
export interface PanelTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
children?: React.ReactNode
/** Heading level for accessibility */
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
}
export const PanelTitle: React.FC<PanelTitleProps> = ({
children,
className,
as: Component = 'h3',
...props
}) => {
return (
<Component className={classNames(styles.panelTitle, className)} {...props}>
{children}
</Component>
)
}
// ============================================================================
// PanelBody Component
// ============================================================================
export type PanelBodyVariant = 'default' | 'noPadding' | 'scroll'
export interface PanelBodyProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
/** Body padding/scroll variant */
variant?: PanelBodyVariant
}
export const PanelBody: React.FC<PanelBodyProps> = ({
children,
className,
variant = 'default',
...props
}) => {
const bodyClass = classNames(
{
[styles.panelBody]: variant === 'default',
[styles.panelBodyNoPadding]: variant === 'noPadding',
[styles.panelBodyScroll]: variant === 'scroll',
},
className
)
return (
<div className={bodyClass} {...props}>
{children}
</div>
)
}
// ============================================================================
// PanelFooter Component
// ============================================================================
export interface PanelFooterProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
/** Show action buttons aligned right */
actions?: boolean
}
export const PanelFooter: React.FC<PanelFooterProps> = ({
children,
className,
actions = false,
...props
}) => {
const footerClass = classNames(
actions ? styles.panelFooterActions : styles.panelFooter,
className
)
return (
<div className={footerClass} {...props}>
{children}
</div>
)
}
// ============================================================================
// PanelSection Component
// ============================================================================
export interface PanelSectionProps extends React.HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode
}
export const PanelSection: React.FC<PanelSectionProps> = ({
children,
className,
...props
}) => {
return (
<div className={classNames(styles.panelSection, className)} {...props}>
{children}
</div>
)
}

Some files were not shown because too many files have changed in this diff Show More