@telemetryos/cli 1.16.1 → 1.17.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @telemetryos/cli
2
2
 
3
+ ## 1.17.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fix the way iframes are refreshed
8
+ - Updated dependencies
9
+ - @telemetryos/development-application-host-ui@1.17.1
10
+
11
+ ## 1.17.0
12
+
13
+ ### Minor Changes
14
+
15
+ - Add frame options
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+ - @telemetryos/development-application-host-ui@1.17.0
21
+
3
22
  ## 1.16.1
4
23
 
5
24
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telemetryos/cli",
3
- "version": "1.16.1",
3
+ "version": "1.17.1",
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,7 +25,7 @@
25
25
  "license": "",
26
26
  "repository": "github:TelemetryTV/Application-API",
27
27
  "dependencies": {
28
- "@telemetryos/development-application-host-ui": "^1.16.1",
28
+ "@telemetryos/development-application-host-ui": "^1.17.1",
29
29
  "@types/serve-handler": "^6.1.4",
30
30
  "commander": "^14.0.0",
31
31
  "ignore": "^6.0.2",
@@ -1,13 +0,0 @@
1
- import { Command } from 'commander';
2
- export type ArchiveCallbacks = {
3
- onLog?: (line: string) => void;
4
- onStateChange?: (state: string) => void;
5
- onComplete?: (data: {
6
- filename: string;
7
- }) => void;
8
- onError?: (error: Error) => void;
9
- };
10
- export declare const archiveCommand: Command;
11
- export declare function handleArchiveCommand(projectPath: string, options: {
12
- output?: string;
13
- }, callbacks?: ArchiveCallbacks): Promise<void>;
@@ -1,49 +0,0 @@
1
- import { Command } from 'commander';
2
- import path from 'path';
3
- import { loadProjectConfig } from '../services/project-config.js';
4
- import { createArchive } from '../services/archiver.js';
5
- import { ansi } from '../utils/ansi.js';
6
- export const archiveCommand = new Command('archive')
7
- .alias('zip')
8
- .description('Create a project archive for manual upload')
9
- .argument('[project-path]', 'Path to the project directory. Defaults to current working directory', process.cwd())
10
- .option('-o, --output <path>', 'Output directory for the archive')
11
- .action(handleArchiveCommand);
12
- export async function handleArchiveCommand(projectPath, options, callbacks) {
13
- var _a, _b, _c, _d, _e;
14
- projectPath = path.resolve(process.cwd(), projectPath);
15
- const logMessage = (callbacks === null || callbacks === void 0 ? void 0 : callbacks.onLog) || ((msg) => console.log(msg));
16
- try {
17
- // Step 1: Load project config
18
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStateChange) === null || _a === void 0 ? void 0 : _a.call(callbacks, 'loading');
19
- logMessage(`\n${ansi.cyan}Loading project configuration...${ansi.reset}`);
20
- const config = await loadProjectConfig(projectPath);
21
- logMessage(` Project: ${ansi.bold}${config.name || path.basename(projectPath)}${ansi.reset}`);
22
- if (config.version) {
23
- logMessage(` Version: ${config.version}`);
24
- }
25
- // Step 2: Create archive directly in out/
26
- (_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStateChange) === null || _b === void 0 ? void 0 : _b.call(callbacks, 'archiving');
27
- logMessage(`\n${ansi.cyan}Archiving project...${ansi.reset}`);
28
- const outDir = options.output
29
- ? path.resolve(process.cwd(), options.output)
30
- : path.join(projectPath, 'out');
31
- const { filename } = await createArchive(projectPath, outDir, (msg) => {
32
- logMessage(` ${ansi.dim}${msg}${ansi.reset}`);
33
- });
34
- // Step 3: Report success
35
- (_c = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStateChange) === null || _c === void 0 ? void 0 : _c.call(callbacks, 'success');
36
- logMessage(`\n${ansi.green}${ansi.bold}Archive created!${ansi.reset}`);
37
- logMessage(`\n ${ansi.dim}${outDir}/${filename}${ansi.reset}`);
38
- logMessage('');
39
- (_d = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onComplete) === null || _d === void 0 ? void 0 : _d.call(callbacks, { filename });
40
- }
41
- catch (error) {
42
- const err = error;
43
- logMessage(`\n${ansi.red}Error: ${err.message}${ansi.reset}\n`);
44
- (_e = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onError) === null || _e === void 0 ? void 0 : _e.call(callbacks, err);
45
- if (!callbacks) {
46
- process.exit(1);
47
- }
48
- }
49
- }
@@ -1,2 +0,0 @@
1
- import { type Plugin } from '@opencode-ai/plugin';
2
- export declare const MathToolsPlugin: Plugin;
@@ -1,18 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin';
2
- export const MathToolsPlugin = async (ctx) => {
3
- return {
4
- tool: {
5
- multiply: tool({
6
- description: 'Multiply two numbers',
7
- args: {
8
- a: tool.schema.number().describe('First number'),
9
- b: tool.schema.number().describe('Second number'),
10
- },
11
- async execute(args, context) {
12
- const result = args.a * args.b;
13
- return result.toString();
14
- },
15
- }),
16
- },
17
- };
18
- };
@@ -1,5 +0,0 @@
1
- export type Config = {
2
- apiToken?: string;
3
- };
4
- export declare function loadConfig(): Promise<Config | null>;
5
- export declare function saveConfig(config: Config): Promise<void>;
@@ -1,23 +0,0 @@
1
- import { mkdir, readFile, writeFile } from 'fs/promises';
2
- import { homedir } from 'os';
3
- import path from 'path';
4
- function getConfigDir() {
5
- const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(homedir(), '.config');
6
- return path.join(xdgConfig, 'telemetryos-cli');
7
- }
8
- function getConfigPath() {
9
- return path.join(getConfigDir(), 'config.json');
10
- }
11
- export async function loadConfig() {
12
- try {
13
- const content = await readFile(getConfigPath(), 'utf-8');
14
- return JSON.parse(content);
15
- }
16
- catch {
17
- return null;
18
- }
19
- }
20
- export async function saveConfig(config) {
21
- await mkdir(getConfigDir(), { recursive: true });
22
- await writeFile(getConfigPath(), JSON.stringify(config, null, 2));
23
- }
@@ -1,12 +0,0 @@
1
- export type GenerateApplicationOptions = {
2
- name: string;
3
- description: string;
4
- author: string;
5
- version: string;
6
- template: string;
7
- projectPath: string;
8
- progressFn: (createdFilePath: string) => void;
9
- };
10
- export declare function generateApplication(options: GenerateApplicationOptions): Promise<void>;
11
- export declare function checkDirectoryConflicts(projectPath: string): Promise<string[]>;
12
- export declare function removeConflictingFiles(projectPath: string, conflicts: string[]): Promise<void>;
@@ -1,206 +0,0 @@
1
- import { spawn, execSync } from 'child_process';
2
- import fs from 'fs/promises';
3
- import path from 'path';
4
- import { ansi } from '../utils/ansi.js';
5
- const ignoredTemplateFiles = ['.DS_Store', 'thumbs.db', 'node_modules', '.git', 'dist'];
6
- const templatesDir = path.join(import.meta.dirname, '../../templates');
7
- const dotfileNames = ['_gitignore', '_claude'];
8
- // Files that can exist in a directory without being considered conflicts
9
- const safeExistingFiles = [
10
- '.DS_Store',
11
- '.git',
12
- '.gitignore',
13
- '.gitattributes',
14
- '.idea',
15
- '.vscode',
16
- 'Thumbs.db',
17
- 'LICENSE',
18
- 'README.md',
19
- ];
20
- export async function generateApplication(options) {
21
- const { name, description, author, version, template, projectPath, progressFn } = options;
22
- await fs.mkdir(projectPath, { recursive: true });
23
- // Initialize git repo early (before template dependencies that may have git hooks)
24
- const gitInitialized = tryGitInit(projectPath);
25
- if (gitInitialized) {
26
- console.log('\nInitialized a git repository');
27
- }
28
- await copyDir(path.join(templatesDir, template), projectPath, {
29
- name,
30
- version,
31
- description,
32
- author,
33
- }, progressFn);
34
- // Install latest versions of @telemetryos/sdk and @telemetryos/cli
35
- console.log('\nInstalling dependencies...');
36
- await installPackages(projectPath);
37
- // Create initial commit after all files are in place
38
- if (gitInitialized) {
39
- await tryGitCommit(projectPath);
40
- }
41
- printSuccessMessage(name, projectPath);
42
- }
43
- async function installPackages(projectPath) {
44
- // Install SDK as a regular dependency
45
- await new Promise((resolve, reject) => {
46
- const sdkInstall = spawn('npm', ['install', '@telemetryos/sdk'], {
47
- cwd: projectPath,
48
- stdio: 'inherit',
49
- shell: true,
50
- });
51
- sdkInstall.on('close', (code) => {
52
- if (code === 0) {
53
- resolve();
54
- }
55
- else {
56
- reject(new Error(`npm install @telemetryos/sdk failed with code ${code}`));
57
- }
58
- });
59
- sdkInstall.on('error', (error) => {
60
- reject(error);
61
- });
62
- });
63
- // Install CLI as a dev dependency
64
- await new Promise((resolve, reject) => {
65
- const cliInstall = spawn('npm', ['install', '-D', '@telemetryos/cli'], {
66
- cwd: projectPath,
67
- stdio: 'inherit',
68
- shell: true,
69
- });
70
- cliInstall.on('close', (code) => {
71
- if (code === 0) {
72
- resolve();
73
- }
74
- else {
75
- reject(new Error(`npm install -D @telemetryos/cli failed with code ${code}`));
76
- }
77
- });
78
- cliInstall.on('error', (error) => {
79
- reject(error);
80
- });
81
- });
82
- }
83
- function isInGitRepository(cwd) {
84
- try {
85
- execSync('git rev-parse --is-inside-work-tree', { cwd, stdio: 'ignore' });
86
- return true;
87
- }
88
- catch {
89
- return false;
90
- }
91
- }
92
- function tryGitInit(projectPath) {
93
- try {
94
- execSync('git --version', { stdio: 'ignore' });
95
- if (isInGitRepository(projectPath)) {
96
- return false;
97
- }
98
- execSync('git init', { cwd: projectPath, stdio: 'ignore' });
99
- return true;
100
- }
101
- catch {
102
- return false;
103
- }
104
- }
105
- async function tryGitCommit(projectPath) {
106
- try {
107
- execSync('git add -A', { cwd: projectPath, stdio: 'ignore' });
108
- execSync('git commit -m "Initialize project using TelemetryOS CLI"', {
109
- cwd: projectPath,
110
- stdio: 'ignore',
111
- });
112
- console.log('Created initial commit');
113
- return true;
114
- }
115
- catch {
116
- // Commit failed (e.g., git user not configured)
117
- // Remove .git directory to avoid half-initialized state
118
- console.log('Git commit not created');
119
- console.log('Removing .git directory...');
120
- try {
121
- await fs.rm(path.join(projectPath, '.git'), { recursive: true, force: true });
122
- }
123
- catch {
124
- // Ignore cleanup errors
125
- }
126
- return false;
127
- }
128
- }
129
- export async function checkDirectoryConflicts(projectPath) {
130
- try {
131
- const entries = await fs.readdir(projectPath);
132
- return entries.filter((file) => !safeExistingFiles.includes(file));
133
- }
134
- catch (error) {
135
- // Directory doesn't exist, no conflicts
136
- if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
137
- return [];
138
- }
139
- throw error;
140
- }
141
- }
142
- export async function removeConflictingFiles(projectPath, conflicts) {
143
- for (const file of conflicts) {
144
- const filePath = path.join(projectPath, file);
145
- try {
146
- const stat = await fs.stat(filePath);
147
- if (stat.isDirectory()) {
148
- await fs.rm(filePath, { recursive: true, force: true });
149
- }
150
- else {
151
- await fs.unlink(filePath);
152
- }
153
- }
154
- catch (error) {
155
- // Ignore errors for files that may have already been removed
156
- console.error(`Warning: Could not remove ${file}: ${error instanceof Error ? error.message : error}`);
157
- }
158
- }
159
- }
160
- function printSuccessMessage(name, projectPath) {
161
- // Calculate relative path from cwd for cleaner display
162
- const relativePath = path.relative(process.cwd(), projectPath);
163
- const displayPath = relativePath || '.';
164
- console.log(`
165
- ${ansi.green}Success!${ansi.reset} Created ${ansi.bold}${name}${ansi.reset} at ${ansi.cyan}${displayPath}${ansi.reset}
166
-
167
- Inside that directory, you can run:
168
-
169
- ${ansi.cyan}npm run dev${ansi.reset}
170
- Starts the development server
171
-
172
- ${ansi.cyan}npm run build${ansi.reset}
173
- Builds the app for production
174
-
175
- You may begin with:
176
-
177
- ${ansi.cyan}cd ${displayPath}${ansi.reset}
178
- ${ansi.cyan}npm run dev${ansi.reset}
179
-
180
- `);
181
- }
182
- async function copyDir(source, destination, replacements, progressFn) {
183
- const dirListing = await fs.readdir(source);
184
- for (const dirEntry of dirListing) {
185
- if (ignoredTemplateFiles.includes(dirEntry))
186
- continue;
187
- const sourcePath = path.join(source, dirEntry);
188
- const destinationPath = path.join(destination, dotfileNames.includes(dirEntry) ? `.${dirEntry.slice(1)}` : dirEntry);
189
- const stats = await fs.stat(sourcePath);
190
- if (stats.isDirectory()) {
191
- await fs.mkdir(destinationPath, { recursive: true });
192
- await copyDir(sourcePath, destinationPath, replacements, progressFn);
193
- }
194
- else if (stats.isFile()) {
195
- await copyFile(sourcePath, destinationPath, replacements, progressFn);
196
- }
197
- }
198
- }
199
- async function copyFile(source, destination, replacements, progressFn) {
200
- let contents = await fs.readFile(source, 'utf-8');
201
- for (const [key, value] of Object.entries(replacements)) {
202
- contents = contents.replace(new RegExp(`{{${key}}}`, 'g'), value);
203
- }
204
- await fs.writeFile(destination, contents, 'utf-8');
205
- progressFn(destination);
206
- }
@@ -1,44 +0,0 @@
1
- export type ApplicationKind = 'git' | 'github' | 'uploaded' | null;
2
- export type Application = {
3
- id: string;
4
- title: string;
5
- description: string;
6
- kind: ApplicationKind;
7
- baseImage: string;
8
- buildWorkingPath?: string;
9
- buildScript?: string;
10
- buildOutputPath?: string;
11
- buildEnvironmentVariables?: Record<string, string>;
12
- versions?: ApplicationVersion[];
13
- createdAt?: string;
14
- updatedAt?: string;
15
- };
16
- export type ApplicationVersion = {
17
- name?: string;
18
- version?: string;
19
- applicationId: string;
20
- buildId: string;
21
- applicationSpecifier: string;
22
- publishedAt: string;
23
- };
24
- export type ApplicationBuild = {
25
- id: string;
26
- applicationId: string;
27
- index: number;
28
- state: 'pending' | 'building' | 'success' | 'failure' | 'failed' | 'cancelled';
29
- logs: string[];
30
- scheduledAt?: string;
31
- startedAt?: string;
32
- finishedAt?: string;
33
- };
34
- export type CreateApplicationRequest = {
35
- kind: 'uploaded';
36
- title: string;
37
- description?: string;
38
- baseImage: string;
39
- baseImageRegistryAuth: string;
40
- buildWorkingPath: string;
41
- buildScript: string;
42
- buildOutputPath: string;
43
- buildEnvironmentVariables?: Record<string, string>;
44
- };
package/dist/types/api.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,19 +0,0 @@
1
- export type ValidationResult = {
2
- valid: true;
3
- } | {
4
- valid: false;
5
- errors: string[];
6
- };
7
- /**
8
- * Validates a project name against npm naming conventions.
9
- */
10
- export declare function validateProjectName(name: string): ValidationResult;
11
- /**
12
- * Formats validation errors for CLI display.
13
- */
14
- export declare function formatValidationErrors(errors: string[]): string;
15
- /**
16
- * Validator for Inquirer prompts.
17
- * Returns true if valid, or an error message string if invalid.
18
- */
19
- export declare function validateProjectNameForPrompt(input: string): string | true;
@@ -1,44 +0,0 @@
1
- import validateNpmPackageName from 'validate-npm-package-name';
2
- /**
3
- * Validates a project name against npm naming conventions.
4
- */
5
- export function validateProjectName(name) {
6
- const result = validateNpmPackageName(name);
7
- if (result.validForNewPackages) {
8
- return { valid: true };
9
- }
10
- const problems = [];
11
- if (result.errors) {
12
- problems.push(...result.errors);
13
- }
14
- if (result.warnings) {
15
- problems.push(...result.warnings);
16
- }
17
- return {
18
- valid: false,
19
- errors: problems.length > 0 ? problems : ['Invalid package name'],
20
- };
21
- }
22
- /**
23
- * Formats validation errors for CLI display.
24
- */
25
- export function formatValidationErrors(errors) {
26
- if (errors.length === 1) {
27
- return `Invalid project name: ${errors[0]}`;
28
- }
29
- return `Invalid project name:\n${errors.map((e) => ` - ${e}`).join('\n')}`;
30
- }
31
- /**
32
- * Validator for Inquirer prompts.
33
- * Returns true if valid, or an error message string if invalid.
34
- */
35
- export function validateProjectNameForPrompt(input) {
36
- if (!input || input.trim().length === 0) {
37
- return 'Project name cannot be empty';
38
- }
39
- const result = validateProjectName(input.trim());
40
- if (result.valid) {
41
- return true;
42
- }
43
- return formatValidationErrors(result.errors);
44
- }