Skip to content
Open
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
68 changes: 34 additions & 34 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
{
"name": "mujoco-robot-demo",
"version": "1.0.0",
"private": true,
"description": "Open-source robot teleoperation demo using MuJoCo physics simulation",
"scripts": {
"copy-mujoco": "mkdir -p public/mujoco-js/dist && cp -r node_modules/mujoco-js/dist/* public/mujoco-js/dist/",
"postinstall": "npm run copy-mujoco",
"dev": "next dev --webpack",
"build": "npm run copy-mujoco && next build --webpack",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"@types/three": "^0.181.0",
"fflate": "^0.8.2",
"mujoco-js": "^0.0.7",
"next": "^16.1.0",
"react": "19.2.1",
"react-dom": "19.2.1",
"three": "^0.181.1"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "^16.1.0",
"ignore-loader": "^0.1.2",
"tailwindcss": "^4",
"typescript": "^5"
}
}
{
"name": "mujoco-robot-demo",
"version": "1.0.0",
"private": true,
"description": "Open-source robot teleoperation demo using MuJoCo physics simulation",
"scripts": {
"copy-mujoco": "node scripts/copy-mujoco.mjs",
"postinstall": "npm run copy-mujoco",
"dev": "next dev --webpack",
"build": "npm run copy-mujoco && next build --webpack",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"@types/three": "^0.181.0",
"fflate": "^0.8.2",
"mujoco-js": "^0.0.7",
"next": "^16.1.0",
"react": "19.2.1",
"react-dom": "19.2.1",
"three": "^0.181.1"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "^16.1.0",
"ignore-loader": "^0.1.2",
"tailwindcss": "^4",
"typescript": "^5"
}
}
154 changes: 77 additions & 77 deletions src/app/api/tasks/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,77 @@
import { NextRequest, NextResponse } from 'next/server';
import { promises as fs } from 'fs';
import path from 'path';

type Task = {
id: number;
name: string;
description: string;
difficulty_stars: number;
expected_duration: number;
success_rate: number;
thumbnail: string;
time_limit: number | null;
mjcf_xml: string | null;
checker_config: Record<string, any> | null;
initial_state: Record<string, any> | null;
steps: { order: number; description: string }[] | null;
rarity: string | null;
base_points: number | null;
category: string | null;
};

type TasksData = {
tasks: Task[];
};

export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
const taskId = parseInt(id, 10);

if (isNaN(taskId)) {
return NextResponse.json(
{ error: 'Invalid task ID' },
{ status: 400 }
);
}

// Read tasks from local JSON file
const tasksFilePath = path.join(process.cwd(), 'public', 'data', 'tasks.json');
const tasksFileContent = await fs.readFile(tasksFilePath, 'utf-8');
const tasksData: TasksData = JSON.parse(tasksFileContent);

// Find the task by ID
const task = tasksData.tasks.find(t => t.id === taskId);

if (!task) {
return NextResponse.json(
{ error: 'Task not found' },
{ status: 404 }
);
}

// If task has mjcf_xml path, read the XML content
if (task.mjcf_xml && !task.mjcf_xml.startsWith('<')) {
try {
const xmlPath = path.join(process.cwd(), 'public', 'mujoco-assets', task.mjcf_xml);
const xmlContent = await fs.readFile(xmlPath, 'utf-8');
task.mjcf_xml = xmlContent;
} catch (error) {
console.error(`[API] Failed to read XML file for task ${taskId}:`, error);
// Keep the original path if file read fails
}
}

return NextResponse.json(task);
} catch (error) {
console.error('[API] Error fetching task:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
import { NextRequest, NextResponse } from 'next/server';
import { promises as fs } from 'fs';
import path from 'path';
type Task = {
id: number;
name: string;
description: string;
difficulty_stars: number;
expected_duration: number;
success_rate: number;
thumbnail: string;
time_limit: number | null;
mjcf_xml: string | null;
checker_config: Record<string, unknown> | null;
initial_state: Record<string, unknown> | null;
steps: { order: number; description: string }[] | null;
rarity: string | null;
base_points: number | null;
category: string | null;
};
type TasksData = {
tasks: Task[];
};
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const { id } = await params;
const taskId = parseInt(id, 10);
if (isNaN(taskId)) {
return NextResponse.json(
{ error: 'Invalid task ID' },
{ status: 400 }
);
}
// Read tasks from local JSON file
const tasksFilePath = path.join(process.cwd(), 'public', 'data', 'tasks.json');
const tasksFileContent = await fs.readFile(tasksFilePath, 'utf-8');
const tasksData: TasksData = JSON.parse(tasksFileContent);
// Find the task by ID
const task = tasksData.tasks.find(t => t.id === taskId);
if (!task) {
return NextResponse.json(
{ error: 'Task not found' },
{ status: 404 }
);
}
// If task has mjcf_xml path, read the XML content
if (task.mjcf_xml && !task.mjcf_xml.startsWith('<')) {
try {
const xmlPath = path.join(process.cwd(), 'public', 'mujoco-assets', task.mjcf_xml);
const xmlContent = await fs.readFile(xmlPath, 'utf-8');
task.mjcf_xml = xmlContent;
} catch (error) {
console.error(`[API] Failed to read XML file for task ${taskId}:`, error);
// Keep the original path if file read fails
}
}
return NextResponse.json(task);
} catch (error) {
console.error('[API] Error fetching task:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
Loading