Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 20
- name: Install Node deps
working-directory: LumenIO/clients/web
run: npm install
- name: Run vitest
working-directory: LumenIO/clients/web
run: npm test
- name: Run playwright
working-directory: LumenIO/clients/web
run: npx playwright install --with-deps && npx playwright test
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Python deps
working-directory: LumenIO/hub
run: pip install -r requirements.txt
- name: Run pytest
working-directory: LumenIO/hub
run: pytest
79 changes: 79 additions & 0 deletions .github/workflows/matrix-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: LumenIO Matrix CI

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
core:
name: Core Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: |
cd LumenIO/packages/lumenio-core
pip install -e .
pytest tests/

variants:
name: Variant Tests
runs-on: ${{ matrix.os }}
needs: core
strategy:
matrix:
variant: [pc, mobile, pcproj, mobileproj, standalone, wearables]
os: [ubuntu-latest]
include:
- variant: pc
sensors: webcam,keyboard,mouse
e2e: desktop
- variant: mobile
sensors: camera,gyro,touch,accelerometer
e2e: mobile
- variant: pcproj
sensors: webcam,keyboard,mouse,projector
e2e: desktop-projector
- variant: mobileproj
sensors: camera,gyro,touch,accelerometer,projector
e2e: mobile-projector
- variant: standalone
sensors: camera,lidar,projector,compute
e2e: embedded
- variant: wearables
sensors: imu,camera,haptic,display
e2e: wearable
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Core
run: |
cd LumenIO/packages/lumenio-core
pip install -e .
- name: Test Variant ${{ matrix.variant }}
run: |
cd LumenIO/packages/lumenio-${{ matrix.variant }}
pip install -e .
pytest tests/unit/
- name: E2E Tests ${{ matrix.variant }}
run: |
cd LumenIO/packages/lumenio-${{ matrix.variant }}
npm install
npx playwright install
npx playwright test --project=${{ matrix.e2e }}

integration:
name: Cross-Variant Integration
runs-on: ubuntu-latest
needs: variants
steps:
- uses: actions/checkout@v4
- run: |
python LumenIO/scripts/validate_contracts.py
python LumenIO/scripts/version_compatibility_check.py
37 changes: 37 additions & 0 deletions LumenIO/VERSIONING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# LumenIO Versioning & Release Policy

## Core (LumenIO-Core)
- Semantic Versioning: MAJOR.MINOR.PATCH
- MAJOR: Breaking contract changes
- MINOR: Backward-compatible features
- PATCH: Bug fixes

## Variants
- Depend on Core with ranges like `^0.1.0`
- Version independently
- Must pass Core contract tests

## Release Process
1. Core release
2. Update variant core ranges
3. Matrix CI validates all combinations
4. Integration tests ensure compatibility

## CHANGELOG Format
```
## [Version] - YYYY-MM-DD
### Core
- Added: ...
- Changed: ...
- Fixed: ...
### Variant Updates
- PC: ...
- Mobile: ...
### Breaking Changes
- ...
```

## Compatibility Matrix
| Core | PC | Mobile | PCProj | MobileProj | Standalone | Wearables |
|------|----|--------|--------|------------|------------|-----------|
|0.1.x|✓|✓|✓|✓|✓|✓|
80 changes: 80 additions & 0 deletions LumenIO/bootstrap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<project>
<brand>
<name>LumenIO</name>
<description>Gesture-first multi-device programming interface ecosystem</description>
<repository>https://github.com/testingground/testingground.github.io</repository>
</brand>
<core>
<name>LumenIO-Core</name>
<description>Shared contracts, schemas, gesture FSM, calibration, agents</description>
<version>0.1.0</version>
<modules>
<module>contracts</module>
<module>schemas</module>
<module>gestures</module>
<module>calibration</module>
<module>agents</module>
<module>common</module>
</modules>
</core>
<variants>
<variant>
<name>LumenIO-PC</name>
<target>desktop</target>
<sensors>webcam,keyboard,mouse</sensors>
<core_version>^0.1.0</core_version>
</variant>
<variant>
<name>LumenIO-Mobile</name>
<target>mobile</target>
<sensors>camera,gyro,touch,accelerometer</sensors>
<core_version>^0.1.0</core_version>
</variant>
<variant>
<name>LumenIO-PCProj</name>
<target>desktop+projector</target>
<sensors>webcam,projector,keyboard,mouse</sensors>
<core_version>^0.1.0</core_version>
</variant>
<variant>
<name>LumenIO-MobileProj</name>
<target>mobile+projector</target>
<sensors>camera,projector,gyro,touch,accelerometer</sensors>
<core_version>^0.1.0</core_version>
</variant>
<variant>
<name>LumenIO-Standalone</name>
<target>embedded</target>
<sensors>camera,lidar,projector,compute</sensors>
<core_version>^0.1.0</core_version>
</variant>
<variant>
<name>LumenIO-Wearables</name>
<target>wearable</target>
<sensors>imu,camera,haptic,display</sensors>
<core_version>^0.1.0</core_version>
</variant>
</variants>
<dependencies>
<dep>Python 3.11+</dep>
<dep>FastAPI + aiortc</dep>
<dep>OpenCV</dep>
<dep>MediaPipe/TFLite</dep>
<dep>Blender Python API</dep>
<dep>WebRTC/WebGPU/WebXR</dep>
<dep>Node 20</dep>
<dep>Vite/Vitest/Playwright</dep>
</dependencies>
<authors>
<author role="cipher">LLM/NN Prompt Engineer</author>
<author role="forge">Mech/Electrical/Industrial Engineer</author>
</authors>
<preferences>
<codex_mode>CODE_FIRST_MINIMAL</codex_mode>
<versioning>semver_core_pinned_variants</versioning>
</preferences>
<handoff>
<directory>LumenIO</directory>
<file>bootstrap.xml</file>
</handoff>
</project>
6 changes: 6 additions & 0 deletions LumenIO/clients/web/e2e/app.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { test, expect } from '@playwright/test';

test('renders greeting', async ({ page }) => {
await page.setContent('<div id="app">Hello LumenIO</div>');
await expect(page.locator('#app')).toHaveText('Hello LumenIO');
});
11 changes: 11 additions & 0 deletions LumenIO/clients/web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>LumenIO</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
19 changes: 19 additions & 0 deletions LumenIO/clients/web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "lumenio-web-client",
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "vitest run",
"test:e2e": "playwright test"
},
"devDependencies": {
"@playwright/test": "^1.43.0",
"vite": "^5.2.0",
"vitest": "^1.5.0"
},
"engines": {
"node": ">=20"
}
}
3 changes: 3 additions & 0 deletions LumenIO/clients/web/src/greet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function greet(name) {
return `Hello ${name}`;
}
3 changes: 3 additions & 0 deletions LumenIO/clients/web/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { greet } from './greet.js';

document.getElementById('app').textContent = greet('LumenIO');
8 changes: 8 additions & 0 deletions LumenIO/clients/web/test/greet.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { describe, it, expect } from 'vitest';
import { greet } from '../src/greet.js';

describe('greet', () => {
it('greets by name', () => {
expect(greet('World')).toBe('Hello World');
});
});
5 changes: 5 additions & 0 deletions LumenIO/clients/web/vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
test: {
include: ['test/**/*.test.js']
}
};
1 change: 1 addition & 0 deletions LumenIO/hub/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Hub package."""
7 changes: 7 additions & 0 deletions LumenIO/hub/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from fastapi import FastAPI

app = FastAPI()

@app.get('/ping')
async def ping():
return {'msg': 'pong'}
4 changes: 4 additions & 0 deletions LumenIO/hub/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fastapi
uvicorn
httpx
jsonschema
10 changes: 10 additions & 0 deletions LumenIO/hub/tests/test_ping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import pytest
from httpx import AsyncClient
from main import app

@pytest.mark.asyncio
async def test_ping():
async with AsyncClient(app=app, base_url='http://test') as ac:
res = await ac.get('/ping')
assert res.status_code == 200
assert res.json() == {'msg': 'pong'}
9 changes: 9 additions & 0 deletions LumenIO/hub/tests/test_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import json
from jsonschema import validate
from pathlib import Path

def test_gesture_schema():
schema_path = Path(__file__).resolve().parent.parent.parent / 'schemas' / 'gesture.json'
schema = json.loads(schema_path.read_text())
sample = {'type': 'wave', 'confidence': 0.9}
validate(instance=sample, schema=schema)
Loading
Loading