Project Structure

Templates, generated file layout, and build configuration

Project Structure

The TelemetryOS Developer App scaffolds complete, production-ready applications from the New Project dialog. Generated projects follow TelemetryOS conventions — mount points are wired up, the SDK is pre-configured, AI agent integration is installed, and the development environment is ready to run.

Creating a Project

From the Developer App's Welcome screen, click New Project (or File > New Project, Cmd+N). Fill in:

  • Project Name — lowercase letters, numbers, and hyphens. Input is auto-converted to kebab-case (e.g. My Weather Appmy-weather-app).
  • Template — see Templates below.
  • Description — a short description, shown in Studio.

Click Create. The Developer App:

  1. Creates a project directory under your configured Default Projects Directory (set in Preferences).
  2. Renders the chosen template into the directory, substituting your name, version, and description.
  3. Installs npm dependencies.
  4. Initializes a Git repository with an initial commit.
  5. Opens the project in a new window, starts the dev server, and shows the app on the canvas.

Templates

Two templates are available from the New Project dialog:

Render + Settings (default)

Internal name: vite-react-typescript. React + TypeScript + Vite, pre-configured with the TelemetryOS SDK. Includes a render mount point (shown on devices) and a settings mount point (shown in the Studio sidebar). Most applications use this template.

Render + Settings + Web

Internal name: vite-react-typescript-web. Same as the default, plus a Web mount point for browser-accessible interfaces — staff dashboards, public kiosks, companion mobile portals, etc. Automatically enables useSpaRouting so React Router handles sub-paths on the Web view.

Generated Structure

A new Render + Settings project looks like this:

my-weather-app/
├── .claude/
│   └── settings.local.json   # Claude Code permissions (pre-approved)
├── .mcp.json                 # MCP server config (points to Developer App)
├── .gitignore
├── CLAUDE.md                 # Project context for AI coding agents
├── index.html
├── package.json              # Dependencies and scripts
├── public/
│   └── assets/
│       ├── tos-app.svg       # Logo (referenced by telemetry.config.json)
│       └── thumbnail.png     # Thumbnail used in Studio
├── src/
│   ├── App.tsx               # Routes between views based on URL path
│   ├── index.tsx             # Entry point — calls configure() before React renders
│   ├── index.css
│   ├── themes.ts
│   ├── hooks/
│   │   └── store.ts          # Typed store hooks
│   └── views/
│       ├── Render.tsx        # Display component shown on devices
│       ├── Render.css
│       ├── Settings.tsx      # Configuration UI shown in Studio sidebar
│       └── Settings.css
├── telemetry.config.json     # TelemetryOS platform configuration
├── tsconfig.json             # TypeScript configuration
└── vite.config.ts            # Build configuration

The Render + Settings + Web template adds src/views/Web.tsx and Web.css.

AI Agent Integration

Every generated project ships with three files that configure AI coding agents:

  • .mcp.json — connects to the Developer App's MCP server on http://localhost:2025 so the agent can take screenshots, read/write store data, read logs, control the canvas, and reload.
  • .claude/settings.local.json — pre-approves the permissions the agent needs so there are no permission prompts during normal work.
  • CLAUDE.md — project context: mount points, store scopes, build commands.

Open the project directory in Claude Code while the Developer App has the project open, and MCP connects automatically. For other agents (Codex, Cursor, Windsurf), rename CLAUDE.md to AGENTS.md as needed.

Configuration

The generated telemetry.config.json:

{
  "name": "my-weather-app",
  "description": "A telemetryOS application",
  "logoPath": "public/assets/tos-app.svg",
  "thumbnailPath": "public/assets/thumbnail.png",
  "version": "2026.4.0",
  "mountPoints": {
    "render": "/render",
    "settings": "/settings"
  },
  "devServer": {
    "runCommand": "npm install && vite --port $PORT",
    "url": "http://localhost:$PORT",
    "readyPattern": "VITE.*ready in"
  }
}

The mountPoints paths correspond to routes in src/App.tsx. The $PORT variable is replaced at runtime by the Developer App with an available port. The leading npm install in runCommand is a safety net — the Developer App runs npm install during scaffolding, but repeating it on each dev-server start keeps things working after git pulls and branch switches.

See Configuration for the full reference.

Build Configuration

The generated vite.config.ts is pre-configured. The Developer App builds via npm run build, which runs tsc && vite build:

// package.json
{
  "scripts": {
    "build": "tsc && vite build"
  }
}

Production builds land in dist/ and include telemetry.config.json at the root. This is what the platform deploys to devices.

Developer App Actions

The Developer App manages project lifecycle through its menus. Key actions:

ActionMenuShortcut
Open an existing projectFile > Open ProjectCmd+O
Scaffold a new projectFile > New ProjectCmd+N
Bump version (CalVer patch)File > Bump VersionCmd+Shift+V
Archive as .tar.gzFile > ArchiveCmd+Shift+A
Archive without version bumpFile > Archive without Version BumpAlt+Cmd+Shift+A
Restart dev serverTools > Restart Dev ServerCmd+Alt+R
Clear locally persisted mock dataTools > Delete Stub DataCmd+D
Reveal in Finder / ExplorerTools > Reveal in FinderCmd+F
Open project in code editorTools > Open in [Editor]Cmd+E
Open a terminal in the projectTools > Open Project in TerminalCmd+T

See Developer App for a complete tour.

Adding Components

Workers

Add a background worker by creating the worker file and updating telemetry.config.json:

// src/workers/sync.ts
import { configure, store } from '@telemetryos/sdk';

configure();

async function syncData() {
  try {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    await store().application.set('latest-data', data);
  } catch (error) {
    console.error('Sync failed:', error);
  }
  setTimeout(syncData, 60000);
}

syncData();
{
  "backgroundWorkers": {
    "sync": "workers/sync.js"
  }
}

Bundle workers into the build output with the @telemetryos/vite-plugin-application-workers plugin. See Workers.

Containers

Add a Docker container for backend services:

{
  "containers": {
    "api-server": { "image": "myapp/api:latest", "port": 3000 }
  }
}

The container key becomes a hostname accessible from your application code: proxy().fetch('http://api-server:3000/data'). Containers only run on physical devices, not in the Developer App's simulated environment. See Containers.


What’s Next