@telemetryos/cli 1.12.0 → 1.13.1

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/commands/claude-code.d.ts +2 -0
  3. package/dist/commands/claude-code.js +29 -0
  4. package/dist/commands/init.js +22 -9
  5. package/dist/index.js +2 -0
  6. package/dist/services/create-project.d.ts +13 -0
  7. package/dist/services/create-project.js +188 -0
  8. package/dist/services/project-config.d.ts +3 -0
  9. package/dist/services/project-config.js +3 -0
  10. package/dist/services/run-server.js +63 -26
  11. package/dist/utils/template.d.ts +2 -0
  12. package/dist/utils/template.js +30 -0
  13. package/package.json +3 -3
  14. package/templates/{vite-react-typescript → claude-code}/CLAUDE.md +15 -3
  15. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-architecture/SKILL.md +140 -63
  16. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-debugging/SKILL.md +6 -7
  17. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-media-api/SKILL.md +3 -3
  18. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-multi-mode/SKILL.md +97 -4
  19. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-requirements/SKILL.md +70 -5
  20. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-store-sync/SKILL.md +4 -2
  21. package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-weather-api/SKILL.md +7 -6
  22. package/templates/claude-code/_claude/skills/tos-web-ui-design/SKILL.md +373 -0
  23. package/templates/vite-react-typescript/_gitignore +4 -2
  24. package/templates/vite-react-typescript/public/assets/telemetryos-wordmark.svg +11 -0
  25. package/templates/vite-react-typescript/public/assets/tos-app.svg +12 -0
  26. package/templates/vite-react-typescript/src/index.tsx +1 -1
  27. package/templates/vite-react-typescript/src/views/Render.tsx +1 -2
  28. package/templates/vite-react-typescript/telemetry.config.json +2 -1
  29. package/templates/vite-react-typescript-web/_gitignore +32 -0
  30. package/templates/vite-react-typescript-web/index.html +15 -0
  31. package/templates/vite-react-typescript-web/package.json +24 -0
  32. package/templates/vite-react-typescript-web/src/App.tsx +25 -0
  33. package/templates/vite-react-typescript-web/src/hooks/store.ts +8 -0
  34. package/templates/vite-react-typescript-web/src/index.css +24 -0
  35. package/templates/vite-react-typescript-web/src/index.tsx +11 -0
  36. package/templates/vite-react-typescript-web/src/views/Render.css +67 -0
  37. package/templates/vite-react-typescript-web/src/views/Render.tsx +44 -0
  38. package/templates/vite-react-typescript-web/src/views/Settings.tsx +72 -0
  39. package/templates/vite-react-typescript-web/src/views/Web.css +105 -0
  40. package/templates/vite-react-typescript-web/src/views/Web.tsx +52 -0
  41. package/templates/vite-react-typescript-web/telemetry.config.json +16 -0
  42. package/templates/vite-react-typescript-web/tsconfig.json +19 -0
  43. package/templates/vite-react-typescript-web/vite.config.ts +18 -0
  44. /package/templates/{vite-react-typescript → claude-code}/AGENTS.md +0 -0
  45. /package/templates/{vite-react-typescript → claude-code}/_claude/settings.local.json +0 -0
  46. /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-proxy-fetch/SKILL.md +0 -0
  47. /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-render-kiosk-design/SKILL.md +0 -0
  48. /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-render-signage-design/SKILL.md +0 -0
  49. /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-render-ui-design/SKILL.md +0 -0
  50. /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-settings-ui/SKILL.md +0 -0
  51. /package/templates/{vite-react-typescript → vite-react-typescript-web}/assets/telemetryos-wordmark.svg +0 -0
  52. /package/templates/{vite-react-typescript → vite-react-typescript-web}/assets/tos-app.svg +0 -0
@@ -0,0 +1,11 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ import './index.css'
4
+
5
+ import { createRoot } from 'react-dom/client'
6
+ import { App } from './App'
7
+ import { configure } from '@telemetryos/sdk'
8
+
9
+ configure('{{name}}')
10
+
11
+ createRoot(document.querySelector('#app')!).render(<App />)
@@ -0,0 +1,67 @@
1
+ .render {
2
+ flex: 1;
3
+ display: flex;
4
+ flex-direction: column;
5
+ align-items: center;
6
+ justify-content: space-between;
7
+ gap: 2rem;
8
+ padding: 3rem;
9
+ color: hsl(210 40% 88%);
10
+ background: hsl(212 28% 10%);
11
+ overflow: hidden;
12
+ }
13
+
14
+ .render__logo {
15
+ width: 30rem;
16
+ max-width: 50%;
17
+ }
18
+
19
+ .render__hero {
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+ gap: 2rem;
24
+ }
25
+
26
+ .render__hero-title {
27
+ font-size: 5rem;
28
+ font-weight: 600;
29
+ text-align: center;
30
+ }
31
+
32
+ .render__hero-subtitle {
33
+ font-size: 3rem;
34
+ text-align: center;
35
+ }
36
+
37
+ .render__docs-information {
38
+ display: flex;
39
+ flex-direction: column;
40
+ align-items: center;
41
+ gap: 2rem;
42
+ }
43
+
44
+ .render__docs-information-title {
45
+ font-size: 2rem;
46
+ font-weight: 600;
47
+ text-align: center;
48
+ }
49
+
50
+ .render__docs-information-text {
51
+ font-size: 2rem;
52
+ max-width: 60rem;
53
+ text-align: center;
54
+ }
55
+
56
+ .render__docs-information-button {
57
+ display: flex;
58
+ align-items: center;
59
+ background: rgb(248, 180, 53);
60
+ text-transform: uppercase;
61
+ font-size: 2rem;
62
+ text-decoration: none;
63
+ color: black;
64
+ font-weight: bold;
65
+ padding: 1rem 2rem;
66
+ border-radius: 1rem;
67
+ }
@@ -0,0 +1,44 @@
1
+ import { useUiScaleToSetRem } from '@telemetryos/sdk/react'
2
+ import wordMarkPath from '../../assets/telemetryos-wordmark.svg'
3
+ import { useSubtitleStoreState, useUiScaleStoreState } from '../hooks/store'
4
+ import './Render.css'
5
+
6
+ export function Render() {
7
+ const [, uiScale] = useUiScaleStoreState()
8
+ useUiScaleToSetRem(uiScale)
9
+ const [isLoading, subtitle] = useSubtitleStoreState()
10
+
11
+ return (
12
+ <div className="render">
13
+ <img src={wordMarkPath} alt="TelemetryOS" className="render__logo" />
14
+ <div className="render__hero">
15
+ {uiScale < 1.5 && (
16
+ <div className="render__hero-title">Welcome to TelemetryOS SDK</div>
17
+ )}
18
+ <div className="render__hero-subtitle">{isLoading ? 'Loading...' : subtitle}</div>
19
+ </div>
20
+ <div className="render__docs-information">
21
+ {uiScale < 1.2 && (
22
+ <>
23
+ <div className="render__docs-information-title">
24
+ To get started, edit the Render.tsx and Settings.tsx files
25
+ </div>
26
+ <div className="render__docs-information-text">
27
+ Visit our documentation on building applications to learn more
28
+ </div>
29
+ </>
30
+ )}
31
+ {uiScale < 1.35 && (
32
+ <a
33
+ className="render__docs-information-button"
34
+ href="https://docs.telemetryos.com/docs/sdk-getting-started"
35
+ target="_blank"
36
+ rel="noreferrer"
37
+ >
38
+ Documentation
39
+ </a>
40
+ )}
41
+ </div>
42
+ </div>
43
+ )
44
+ }
@@ -0,0 +1,72 @@
1
+ import {
2
+ SettingsContainer,
3
+ SettingsDivider,
4
+ SettingsField,
5
+ SettingsHeading,
6
+ SettingsInputFrame,
7
+ SettingsLabel,
8
+ SettingsSliderFrame,
9
+ } from '@telemetryos/sdk/react'
10
+ import { useSubtitleStoreState, useUiScaleStoreState, useWelcomeMessageStoreState } from '../hooks/store'
11
+
12
+ export function Settings() {
13
+ const [isLoadingUiScale, uiScale, setUiScale] = useUiScaleStoreState(5)
14
+ const [isLoadingSubtitle, subtitle, setSubtitle] = useSubtitleStoreState(250)
15
+ const [isLoadingWelcome, welcomeMessage, setWelcomeMessage] = useWelcomeMessageStoreState(250)
16
+
17
+ return (
18
+ <SettingsContainer>
19
+
20
+ <SettingsHeading>Render</SettingsHeading>
21
+
22
+ <SettingsField>
23
+ <SettingsLabel>UI Scale</SettingsLabel>
24
+ <SettingsSliderFrame>
25
+ <input
26
+ type="range"
27
+ min={1}
28
+ max={3}
29
+ step={0.01}
30
+ disabled={isLoadingUiScale}
31
+ value={uiScale}
32
+ onChange={(e) => setUiScale(parseFloat(e.target.value))}
33
+ />
34
+ <span>{uiScale}x</span>
35
+ </SettingsSliderFrame>
36
+ </SettingsField>
37
+
38
+ <SettingsDivider />
39
+
40
+ <SettingsField>
41
+ <SettingsLabel>Subtitle Text</SettingsLabel>
42
+ <SettingsInputFrame>
43
+ <input
44
+ type="text"
45
+ placeholder='Some text for the subtitle...'
46
+ value={subtitle}
47
+ onChange={(e) => setSubtitle(e.target.value)}
48
+ disabled={isLoadingSubtitle}
49
+ />
50
+ </SettingsInputFrame>
51
+ </SettingsField>
52
+
53
+ <SettingsDivider />
54
+
55
+ <SettingsHeading>Web</SettingsHeading>
56
+
57
+ <SettingsField>
58
+ <SettingsLabel>Welcome Message</SettingsLabel>
59
+ <SettingsInputFrame>
60
+ <input
61
+ type="text"
62
+ placeholder='A welcome message for the web view...'
63
+ value={welcomeMessage}
64
+ onChange={(e) => setWelcomeMessage(e.target.value)}
65
+ disabled={isLoadingWelcome}
66
+ />
67
+ </SettingsInputFrame>
68
+ </SettingsField>
69
+
70
+ </SettingsContainer>
71
+ )
72
+ }
@@ -0,0 +1,105 @@
1
+ /* Web Mount Point View */
2
+
3
+ html:has(.web) {
4
+ font-size: 16px;
5
+ }
6
+
7
+ .web {
8
+ display: flex;
9
+ flex-direction: column;
10
+ align-items: center;
11
+ justify-content: center;
12
+ min-height: 100vh;
13
+ background: #0f172a;
14
+ color: #cbd5e1;
15
+ font-family: 'Rubik', system-ui, sans-serif;
16
+ }
17
+
18
+ /* Loading */
19
+ .web--loading {
20
+ align-items: center;
21
+ justify-content: center;
22
+ }
23
+
24
+ .web__loading-text {
25
+ font-size: 1.5rem;
26
+ color: #64748b;
27
+ animation: web-pulse 1.5s ease-in-out infinite;
28
+ }
29
+
30
+ @keyframes web-pulse {
31
+ 0%, 100% { opacity: 0.5; }
32
+ 50% { opacity: 1; }
33
+ }
34
+
35
+ /* Container */
36
+ .web__container {
37
+ width: 100%;
38
+ max-width: 640px;
39
+ padding: 3rem 2rem;
40
+ text-align: center;
41
+ }
42
+
43
+ .web__title {
44
+ font-size: 2.5rem;
45
+ font-weight: 700;
46
+ margin: 0 0 1.5rem;
47
+ color: #f8fafc;
48
+ }
49
+
50
+ .web__description {
51
+ font-size: 1rem;
52
+ line-height: 1.6;
53
+ color: #94a3b8;
54
+ margin: 0 0 1rem;
55
+ }
56
+
57
+ /* Info grid */
58
+ .web__info {
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: 0.5rem;
62
+ margin: 2rem 0;
63
+ }
64
+
65
+ .web__info-item {
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: space-between;
69
+ padding: 0.75rem 1.25rem;
70
+ background: #1e293b;
71
+ border: 1px solid #334155;
72
+ border-radius: 0.5rem;
73
+ }
74
+
75
+ .web__info-label {
76
+ font-size: 0.875rem;
77
+ font-weight: 600;
78
+ color: #64748b;
79
+ text-transform: uppercase;
80
+ letter-spacing: 0.05em;
81
+ }
82
+
83
+ .web__info-value {
84
+ font-size: 0.875rem;
85
+ color: #f8fafc;
86
+ }
87
+
88
+ /* Docs link */
89
+ .web__docs-link {
90
+ display: inline-block;
91
+ margin-top: 1rem;
92
+ padding: 0.75rem 2rem;
93
+ background: rgb(248, 180, 53);
94
+ color: black;
95
+ font-size: 1rem;
96
+ font-weight: 700;
97
+ text-decoration: none;
98
+ text-transform: uppercase;
99
+ border-radius: 0.5rem;
100
+ transition: background 0.15s;
101
+ }
102
+
103
+ .web__docs-link:hover {
104
+ background: rgb(234, 166, 39);
105
+ }
@@ -0,0 +1,52 @@
1
+ import { useWelcomeMessageStoreState } from '../hooks/store'
2
+ import './Web.css'
3
+
4
+ export function Web() {
5
+ const [isLoading, welcomeMessage] = useWelcomeMessageStoreState()
6
+
7
+ if (isLoading) {
8
+ return (
9
+ <div className="web web--loading">
10
+ <div className="web__loading-text">Loading...</div>
11
+ </div>
12
+ )
13
+ }
14
+
15
+ return (
16
+ <div className="web">
17
+ <div className="web__container">
18
+ <h1 className="web__title">{welcomeMessage}</h1>
19
+ <p className="web__description">
20
+ This is the <strong>Web mount point</strong> — a browser-accessible interface
21
+ that runs outside the device display and admin settings.
22
+ </p>
23
+ <p className="web__description">
24
+ The welcome message above is stored in the application-scoped store.
25
+ Change it in Settings to see it update here.
26
+ </p>
27
+ <div className="web__info">
28
+ <div className="web__info-item">
29
+ <span className="web__info-label">Store Access</span>
30
+ <span className="web__info-value">Application &amp; Dynamic Namespace</span>
31
+ </div>
32
+ <div className="web__info-item">
33
+ <span className="web__info-label">Runs In</span>
34
+ <span className="web__info-value">Any Browser</span>
35
+ </div>
36
+ <div className="web__info-item">
37
+ <span className="web__info-label">Use Cases</span>
38
+ <span className="web__info-value">Staff Desks, Public Forms, Dashboards</span>
39
+ </div>
40
+ </div>
41
+ <a
42
+ className="web__docs-link"
43
+ href="https://docs.telemetryos.com/docs/sdk-getting-started"
44
+ target="_blank"
45
+ rel="noreferrer"
46
+ >
47
+ Documentation
48
+ </a>
49
+ </div>
50
+ </div>
51
+ )
52
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "{{name}}",
3
+ "description": "{{description}}",
4
+ "logoPath": "assets/tos-app.svg",
5
+ "version": "{{version}}",
6
+ "useSpaRouting": true,
7
+ "mountPoints": {
8
+ "render": "/render",
9
+ "settings": "/settings",
10
+ "web": "/{{name}}"
11
+ },
12
+ "devServer": {
13
+ "runCommand": "vite --port 3000",
14
+ "url": "http://localhost:3000"
15
+ }
16
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "alwaysStrict": true,
4
+ "declaration": true,
5
+ "strict": true,
6
+ "lib": ["DOM", "ESNext"],
7
+ "target": "ES2019",
8
+ "moduleResolution": "bundler",
9
+ "allowSyntheticDefaultImports": true,
10
+ "esModuleInterop": true,
11
+ "isolatedModules": true,
12
+ "resolveJsonModule": true,
13
+ "jsx": "react-jsx",
14
+ "skipLibCheck": true,
15
+ "outDir": "./dist",
16
+ "rootDir": "./src"
17
+ },
18
+ "include": ["./src"]
19
+ }
@@ -0,0 +1,18 @@
1
+ import typescript from '@rollup/plugin-typescript'
2
+ import react from '@vitejs/plugin-react'
3
+ import { defineConfig } from 'vite'
4
+
5
+ export default defineConfig({
6
+ plugins: [
7
+ typescript(),
8
+ react(),
9
+ {
10
+ name: 'suppress-urls',
11
+ configureServer(server) {
12
+ return () => {
13
+ server.printUrls = () => { }
14
+ }
15
+ },
16
+ },
17
+ ],
18
+ })