Skip to main content

Three Subtypes in Detail

The three subtypes are mutually exclusive — each application belongs to only one:

Subtypeconfig.ini Required FieldsKey Identifier
iframe (Internal Open)type, path"type": "iframe", "open_path": false
External Open (New Tab)path"open_path": true (do not include type field)
No UI ServiceNo page-related fieldsDo not include path, open_path, or type fields

Mutual Exclusion Rule: type and open_path must not appear together — iframe uses "type": "iframe"; external open uses "open_path": true; no UI uses neither. Mixing them will result in undefined behavior and rejection during review.

WebUI Internal Open (iframe Embedding)

For applications where the backend is a local executable service, the frontend is a static WebUI, opened within the TOS desktop as an embedded iframe.

Directory Structure:

/usr/local/<app_id>/
├── config.ini
├── bin/
│ └── <binary_name>
├── <app_id>.lang
├── webui.bz2 # 【Required】Frontend page archive
├── images/
│ └── icons/
│ └── <icon_file>.svg
├── init.d/
│ └── <system_id>.service
├── <app_id>.env # 【Optional】Environment variable configuration file
└── depends/ # 【Optional】Dependency file directory
├── bin/ # Executable files
├── lib/ # Dynamic libraries (.so)
├── etc/ # Configuration files
├── data/ # Runtime data (databases/cache/state)
└── logs/ # Logs

config.ini Minimal Configuration:

{
"id": "<app_id>",
"icon": "/images/icons/<icon_file>.svg",
"exec": true,
"version": "<app_version>",
"category": ["Utilities"],
"platform": "x86_64",
"system_id": "<system_id>",
"package": "<deb_package_name>",
"application_type": "deb",
"path": "/<app_id>/",
"type": "iframe"
}

Core Requirements:

  1. The type field must be "iframe".
  2. The path field format is "/<app_id>/".
  3. webui.bz2 is a fixed filename and must not be changed to any other name.
  4. The deb package must contain an executable program, located at /usr/local/<app_id>/bin/<binary_name>.
  5. The config.ini.package field specification must strictly conform to the Debian package package specification.
  6. The backend service provides HTTP interfaces externally via Unix Socket and must listen on /var/api/<app_id>.sock on startup.
  7. /var/api must be auto-created if it does not exist; old socket files must be cleaned up before startup.
  8. Socket file permissions must allow platform proxy access.
  9. Frontend requests to backend interfaces must go through the platform proxy path, with the fixed format /v2/proxy/<app_id>.
  10. Frontend requests must carry the platform authentication headers, including X-Csrf-Token and Cookie in the request headers.

Socket File Specification:

  • Permission mode: 0660 (owner and group read/write)
  • Owner: <appid>:<appid> (matches the service user)
  • Supports HTTP keep-alive connections
  • Supports at least 100 concurrent connections
  • Idle connection timeout: 30 seconds
  1. Frontend requests to backend interfaces must go through the platform proxy path: /v2/proxy/<app_id>/<api_name>.
  2. Frontend requests must carry the platform authentication headers.

CORS and Preflight Request Configuration: The backend must handle CORS preflight requests (OPTIONS method) for the platform proxy. Allow the following:

  • Origin: TOS Web origin
  • Methods: GET, POST, PUT, DELETE, OPTIONS
  • Headers: Content-Type, X-Csrf-Token, Cookie
  • Credentials: true

WebUI External Open (New Tab)

For applications where the backend is a local executable service, the frontend is a static WebUI, opened in a new browser tab.

Directory Structure:

/usr/local/<app_id>/
├── config.ini
├── bin/
│ └── <binary_name>
├── <app_id>.lang
├── webui.bz2 # 【Required】Frontend page archive
├── images/
│ └── icons/
│ └── <icon_file>.svg
├── nginx/
│ └── <app_id>.conf # 【Required】Nginx configuration file
├── init.d/
│ └── <system_id>.service
├── <app_id>.env # 【Optional】Environment variable configuration file
└── depends/ # 【Optional】Dependency file directory
├── bin/ # Executable files
├── lib/ # Dynamic libraries (.so)
├── etc/ # Configuration files
├── data/ # Runtime data (databases/cache/state)
└── logs/ # Logs

config.ini Minimal Configuration:

{
"id": "<app_id>",
"icon": "/images/icons/<icon_file>.svg",
"exec": true,
"version": "<app_version>",
"category": ["Utilities"],
"platform": "x86_64",
"system_id": "<system_id>",
"package": "<deb_package_name>",
"application_type": "deb",
"path": "http://${ip}:8686",
"open_path": true
}

Core Requirements:

  1. open_path must be true.
  2. The path field must correspond to the nginx configuration file route and resolve to the externally provided HTTP interface.
  3. The application package must include an nginx configuration file <app_id>.conf, whose filename must correspond to config.ini.id.
  4. The backend directly listens on <listen_port> to provide HTTP interfaces.
  5. The deb package must contain an executable program, located at /usr/local/<app_id>/bin/<binary_name>.
  6. The config.ini.package field specification must strictly conform to the Debian package package specification.

Port Listening Rules:

  • Must listen on 0.0.0.0 (all network interfaces); listening only on 127.0.0.1 is forbidden. Listening only on the loopback address prevents external access.
  • Must not occupy system reserved ports (22, 80, 443, 8181, 5050)
  • Recommended port range: 8000-19999

Nginx Configuration File Template:

Create at /usr/local/<app_id>/nginx/<app_id>.conf:

location /<app_id>/ {
proxy_pass http://127.0.0.1:<listen_port>/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

Nginx Configuration Management Requirements:

  • Configuration file permissions: 644 (owner read/write, group and others read-only)
  • Configuration file must be placed at /usr/local/<app_id>/nginx/<app_id>.conf
  • The platform Nginx include directive loads configurations in alphabetical order; port conflicts between applications are resolved by using unique ports — two applications cannot share the same port
  • Log rotation: Nginx access/error logs are managed by the platform; do not write your own nginx logs
  • Must not include server {} blocks; only use location /<app_id>/ {} blocks

No UI Service

For background service applications without an interface.

Directory Structure:

/usr/local/<app_id>/
├── config.ini
├── bin/
│ └── <binary_name>
├── <app_id>.lang
├── images/
│ └── icons/
│ └── <icon_file>.svg
├── init.d/
│ └── <system_id>.service
├── <app_id>.env # 【Optional】Environment variable configuration file
└── depends/ # 【Optional】Dependency file directory
├── bin/ # Executable files
├── lib/ # Dynamic libraries (.so)
├── etc/ # Configuration files
├── data/ # Runtime data (databases/cache/state)
└── logs/ # Logs

config.ini Minimal Configuration:

{
"id": "<app_id>",
"icon": "/images/icons/<icon_file>.svg",
"exec": true,
"version": "<app_version>",
"category": ["Utilities"],
"platform": "x86_64",
"system_id": "<system_id>",
"package": "<deb_package_name>",
"application_type": "deb"
}

Core Requirements:

  1. No UI applications do not need frontend-related fields such as path, type, open_path, resize, maxmin, width, height.
  2. The webui.bz2 frontend archive is not required.
  3. The nginx/ directory is not required.
  4. The deb package must contain an executable program, located at /usr/local/<app_id>/bin/<binary_name>.
  5. The config.ini.package field specification must strictly conform to the Debian package package specification.

Status Reporting Requirements: No UI applications must report their running status so that the platform can detect failures:

  • The systemd service unit Type should be simple or forking
  • Use systemd's ExecStartPost to confirm successful startup
  • The App Center displays "Running"/"Stopped"/"Abnormal" based on the systemd service status
  • On failure, systemd auto-restart (configured in the service file) handles recovery