@telemetryos/cli 1.12.0 → 1.13.0
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 +26 -0
- package/dist/commands/claude-code.d.ts +2 -0
- package/dist/commands/claude-code.js +29 -0
- package/dist/commands/init.js +22 -9
- package/dist/index.js +2 -0
- package/dist/services/create-project.d.ts +13 -0
- package/dist/services/create-project.js +188 -0
- package/dist/services/project-config.d.ts +3 -0
- package/dist/services/project-config.js +3 -0
- package/dist/services/run-server.js +48 -25
- package/dist/utils/template.d.ts +2 -0
- package/dist/utils/template.js +30 -0
- package/package.json +2 -2
- package/templates/{vite-react-typescript → claude-code}/CLAUDE.md +10 -3
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-architecture/SKILL.md +138 -61
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-debugging/SKILL.md +2 -2
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-media-api/SKILL.md +3 -3
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-multi-mode/SKILL.md +97 -4
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-requirements/SKILL.md +70 -5
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-store-sync/SKILL.md +4 -2
- package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-weather-api/SKILL.md +7 -6
- package/templates/claude-code/_claude/skills/tos-web-ui-design/SKILL.md +373 -0
- package/templates/vite-react-typescript/_gitignore +4 -2
- package/templates/vite-react-typescript/telemetry.config.json +2 -1
- package/templates/vite-react-typescript-web/_gitignore +32 -0
- package/templates/vite-react-typescript-web/assets/telemetryos-wordmark.svg +11 -0
- package/templates/vite-react-typescript-web/assets/tos-app.svg +12 -0
- package/templates/vite-react-typescript-web/index.html +15 -0
- package/templates/vite-react-typescript-web/package.json +24 -0
- package/templates/vite-react-typescript-web/src/App.tsx +25 -0
- package/templates/vite-react-typescript-web/src/hooks/store.ts +8 -0
- package/templates/vite-react-typescript-web/src/index.css +24 -0
- package/templates/vite-react-typescript-web/src/index.tsx +11 -0
- package/templates/vite-react-typescript-web/src/views/Render.css +67 -0
- package/templates/vite-react-typescript-web/src/views/Render.tsx +44 -0
- package/templates/vite-react-typescript-web/src/views/Settings.tsx +72 -0
- package/templates/vite-react-typescript-web/src/views/Web.css +105 -0
- package/templates/vite-react-typescript-web/src/views/Web.tsx +52 -0
- package/templates/vite-react-typescript-web/telemetry.config.json +16 -0
- package/templates/vite-react-typescript-web/tsconfig.json +19 -0
- package/templates/vite-react-typescript-web/vite.config.ts +18 -0
- /package/templates/{vite-react-typescript → claude-code}/AGENTS.md +0 -0
- /package/templates/{vite-react-typescript → claude-code}/_claude/settings.local.json +0 -0
- /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-proxy-fetch/SKILL.md +0 -0
- /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-render-kiosk-design/SKILL.md +0 -0
- /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-render-signage-design/SKILL.md +0 -0
- /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-render-ui-design/SKILL.md +0 -0
- /package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-settings-ui/SKILL.md +0 -0
|
@@ -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 & 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
|
+
})
|
|
File without changes
|
|
File without changes
|
/package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-proxy-fetch/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/{vite-react-typescript → claude-code}/_claude/skills/tos-settings-ui/SKILL.md
RENAMED
|
File without changes
|