@telemetryos/cli 1.13.0 → 1.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @telemetryos/cli
2
2
 
3
+ ## 1.13.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Widen applicationSpecifier pattern to accept dev specifiers
8
+ - Updated dependencies
9
+ - @telemetryos/development-application-host-ui@1.13.2
10
+
11
+ ## 1.13.1
12
+
13
+ ### Patch Changes
14
+
15
+ - - **SDK client refactor:** Removed `applicationName` from the client and `configure()` API (still accepted for backwards compatibility). The SDK now resolves `applicationSpecifier` from URL search params first with subdomain fallback, validates it as a 40-char hex hash, and adds `deviceId` from URL params. Store scoping updated accordingly. Fixed a listener leak when calling `configure()` multiple times.
16
+ - **Template assets moved to `public/`:** SDK template assets (logo, thumbnail) moved from `assets/` to `public/assets/` so Vite includes them in the build output automatically. Dev server updated to resolve from `public/` first.
17
+ - **Documentation updates for v1.13.0:** Added docs for web mount point, Navigation API, `tos claude-code` command, `vite-react-typescript-web` template, `playlist.getDuration()`, `SettingsMediaSelect` component, and custom logo support. Fixed scope availability, store scope guidance for web mount points, and various inconsistencies.
18
+
19
+ - Updated dependencies
20
+ - @telemetryos/development-application-host-ui@1.13.1
21
+
3
22
  ## 1.13.0
4
23
 
5
24
  ### Minor Changes
@@ -1,5 +1,5 @@
1
1
  import { spawn } from 'child_process';
2
- import { readFile } from 'fs/promises';
2
+ import { access, readFile } from 'fs/promises';
3
3
  import { fileURLToPath } from 'url';
4
4
  import http from 'http';
5
5
  import path from 'path';
@@ -188,16 +188,30 @@ async function serveImageFile(res, projectPath, filePath, label) {
188
188
  res.end(`No ${label} configured`);
189
189
  return;
190
190
  }
191
- try {
192
- const fullPath = path.resolve(projectPath, filePath);
193
- if (!fullPath.startsWith(path.resolve(projectPath) + path.sep) &&
194
- fullPath !== path.resolve(projectPath)) {
195
- res.statusCode = 403;
196
- res.setHeader('Content-Type', 'text/plain; charset=utf-8');
197
- res.end('Forbidden: path escapes project root');
198
- return;
191
+ const projectRoot = path.resolve(projectPath);
192
+ const validatePath = (fullPath) => fullPath.startsWith(projectRoot + path.sep) || fullPath === projectRoot;
193
+ // Try public/ first (Vite convention), then project root (backward compat)
194
+ const publicPath = path.resolve(projectPath, 'public', filePath);
195
+ const rootPath = path.resolve(projectPath, filePath);
196
+ let resolvedPath;
197
+ if (validatePath(publicPath)) {
198
+ try {
199
+ await access(publicPath);
200
+ resolvedPath = publicPath;
199
201
  }
200
- const imageData = await readFile(fullPath);
202
+ catch { }
203
+ }
204
+ if (!resolvedPath && validatePath(rootPath)) {
205
+ resolvedPath = rootPath;
206
+ }
207
+ if (!resolvedPath) {
208
+ res.statusCode = 403;
209
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
210
+ res.end('Forbidden: path escapes project root');
211
+ return;
212
+ }
213
+ try {
214
+ const imageData = await readFile(resolvedPath);
201
215
  const ext = path.extname(filePath).toLowerCase();
202
216
  const contentType = IMAGE_MIME_TYPES[ext] || 'application/octet-stream';
203
217
  res.setHeader('Content-Type', contentType);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telemetryos/cli",
3
- "version": "1.13.0",
3
+ "version": "1.13.2",
4
4
  "description": "The official TelemetryOS application CLI package. Use it to build applications that run on the TelemetryOS platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,13 +25,13 @@
25
25
  "license": "",
26
26
  "repository": "github:TelemetryTV/Application-API",
27
27
  "dependencies": {
28
- "@telemetryos/development-application-host-ui": "^1.13.0",
28
+ "@telemetryos/development-application-host-ui": "^1.13.2",
29
29
  "@types/serve-handler": "^6.1.4",
30
30
  "commander": "^14.0.0",
31
31
  "ignore": "^6.0.2",
32
32
  "inquirer": "^12.9.6",
33
33
  "serve-handler": "^6.1.6",
34
- "tar": "^7.4.3",
34
+ "tar": "^7.5.9",
35
35
  "zod": "^4.1.12"
36
36
  },
37
37
  "devDependencies": {
@@ -35,6 +35,9 @@ Instance store hooks sync Settings ↔ Render. Application store hooks are acces
35
35
  ## Project Structure
36
36
 
37
37
  ```
38
+ public/
39
+ └── assets/ # Static assets copied to dist/ during build
40
+ └── tos-app.svg # App logo (referenced by telemetry.config.json logoPath)
38
41
  src/
39
42
  ├── index.tsx # Entry point (configure SDK here)
40
43
  ├── App.tsx # Mount point routing
@@ -48,6 +51,8 @@ src/
48
51
  └── store.ts # Store state hooks
49
52
  ```
50
53
 
54
+ > **Note:** Files in `public/` are copied as-is to `dist/` by Vite (without the `public/` prefix). The `logoPath` and `thumbnailPath` in `telemetry.config.json` must reference the output path (e.g., `"assets/tos-app.svg"`, not `"public/assets/tos-app.svg"`).
55
+
51
56
  ## Core Pattern
52
57
 
53
58
  ### Store Hooks (Settings ↔ Render sync)
@@ -353,8 +353,8 @@ return <WeatherDisplay city={city} />
353
353
  ### Verify SDK Configuration
354
354
 
355
355
  ```typescript
356
- // In index.tsx - name must match telemetry.config.json
357
- configure('my-app')
356
+ // In index.tsx
357
+ configure()
358
358
  ```
359
359
 
360
360
  ### Check Store Values
@@ -18,7 +18,7 @@ Common errors, their causes, and solutions.
18
18
  // index.tsx - MUST call configure before React renders
19
19
  import { configure } from '@telemetryos/sdk'
20
20
 
21
- configure('my-app') // Name must match telemetry.config.json
21
+ configure()
22
22
 
23
23
  ReactDOM.createRoot(document.getElementById('root')!).render(<App />)
24
24
  ```
@@ -26,7 +26,6 @@ ReactDOM.createRoot(document.getElementById('root')!).render(<App />)
26
26
  **Check:**
27
27
  - Is `configure()` called in index.tsx?
28
28
  - Is it called BEFORE ReactDOM.createRoot()?
29
- - Does the name match `telemetry.config.json`?
30
29
 
31
30
  ---
32
31
 
@@ -188,13 +187,13 @@ useEffect(() => {
188
187
  4. **SDK configured**
189
188
  ```typescript
190
189
  // index.tsx
191
- configure('app-name') // Before React renders
190
+ configure() // Before React renders
192
191
  ```
193
192
 
194
- 5. **telemetry.config.json matches**
193
+ 5. **telemetry.config.json has correct app name and mount points**
195
194
  ```json
196
195
  {
197
- "name": "app-name", // Must match configure()
196
+ "name": "app-name",
198
197
  "mountPoints": {
199
198
  "render": "/render",
200
199
  "settings": "/settings"
@@ -6,6 +6,6 @@ import { createRoot } from 'react-dom/client'
6
6
  import { App } from './App'
7
7
  import { configure } from '@telemetryos/sdk'
8
8
 
9
- configure('{{name}}')
9
+ configure()
10
10
 
11
11
  createRoot(document.querySelector('#app')!).render(<App />)
@@ -1,5 +1,4 @@
1
1
  import { useUiScaleToSetRem } from '@telemetryos/sdk/react'
2
- import wordMarkPath from '../../assets/telemetryos-wordmark.svg'
3
2
  import { useSubtitleStoreState, useUiScaleStoreState } from '../hooks/store'
4
3
  import './Render.css'
5
4
 
@@ -10,7 +9,7 @@ export function Render() {
10
9
 
11
10
  return (
12
11
  <div className="render">
13
- <img src={wordMarkPath} alt="TelemetryOS" className="render__logo" />
12
+ <img src="/assets/telemetryos-wordmark.svg" alt="TelemetryOS" className="render__logo" />
14
13
  <div className="render__hero">
15
14
  {uiScale < 1.5 && (
16
15
  <div className="render__hero-title">Welcome to TelemetryOS SDK</div>