create-termui-app 0.1.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/dist/index.js ADDED
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { resolve, join } from "path";
5
+ import { mkdirSync, writeFileSync, existsSync } from "fs";
6
+ import { getBuiltinThemeNames } from "@termuijs/tss";
7
+
8
+ // src/prompts.ts
9
+ import { createInterface } from "readline";
10
+ var rl = () => createInterface({ input: process.stdin, output: process.stdout });
11
+ async function textPrompt(question, defaultValue) {
12
+ return new Promise((resolve2) => {
13
+ const r = rl();
14
+ const suffix = defaultValue ? ` (${defaultValue})` : "";
15
+ r.question(` ${question}${suffix}: `, (answer) => {
16
+ r.close();
17
+ resolve2(answer.trim() || defaultValue || "");
18
+ });
19
+ });
20
+ }
21
+ async function selectPrompt(question, options) {
22
+ console.log(`
23
+ ${question}`);
24
+ for (let i = 0; i < options.length; i++) {
25
+ console.log(` ${i + 1}) ${options[i]}`);
26
+ }
27
+ const answer = await textPrompt("Enter number", "1");
28
+ const idx = parseInt(answer) - 1;
29
+ return Math.max(0, Math.min(idx, options.length - 1));
30
+ }
31
+ async function multiSelectPrompt(question, options, defaults = []) {
32
+ console.log(`
33
+ ${question} (comma-separated numbers, or 'all')`);
34
+ for (let i = 0; i < options.length; i++) {
35
+ const def = defaults[i] ? "\u2713" : " ";
36
+ console.log(` ${i + 1}) [${def}] ${options[i]}`);
37
+ }
38
+ const answer = await textPrompt("Enter numbers", defaults.some((d) => d) ? "keep defaults" : "all");
39
+ if (answer === "all") return options.map(() => true);
40
+ if (answer === "keep defaults" || answer === "") return defaults.length ? defaults : options.map(() => true);
41
+ const selected = answer.split(",").map((s) => parseInt(s.trim()) - 1);
42
+ return options.map((_, i) => selected.includes(i));
43
+ }
44
+
45
+ // src/templates.ts
46
+ import { getBuiltinTheme } from "@termuijs/tss";
47
+ function generateProject(config) {
48
+ const files = [];
49
+ files.push({
50
+ path: "package.json",
51
+ content: JSON.stringify({
52
+ name: config.name,
53
+ version: "0.1.0",
54
+ private: true,
55
+ type: "module",
56
+ scripts: {
57
+ dev: "tsx --watch src/index.tsx",
58
+ build: "tsup src/index.tsx --format esm",
59
+ start: "node dist/index.js"
60
+ },
61
+ dependencies: {
62
+ "@termuijs/core": "latest",
63
+ "@termuijs/widgets": "latest",
64
+ "@termuijs/ui": "latest",
65
+ "@termuijs/jsx": "latest",
66
+ "@termuijs/tss": "latest",
67
+ ...config.features.dataProviders ? { "@termuijs/data": "latest" } : {},
68
+ ...config.features.router ? { "@termuijs/router": "latest" } : {}
69
+ },
70
+ devDependencies: {
71
+ tsx: "^4.0.0",
72
+ tsup: "^8.0.0",
73
+ typescript: "^5.3.0"
74
+ }
75
+ }, null, 2) + "\n"
76
+ });
77
+ files.push({
78
+ path: "tsconfig.json",
79
+ content: JSON.stringify({
80
+ compilerOptions: {
81
+ target: "ES2022",
82
+ module: "ESNext",
83
+ moduleResolution: "bundler",
84
+ jsx: "react-jsx",
85
+ jsxImportSource: "@termuijs/jsx",
86
+ strict: true,
87
+ esModuleInterop: true,
88
+ outDir: "dist",
89
+ rootDir: "src"
90
+ },
91
+ include: ["src"]
92
+ }, null, 2) + "\n"
93
+ });
94
+ files.push({
95
+ path: "termui.config.ts",
96
+ content: `import { defineConfig } from '@termuijs/core';
97
+
98
+ export default defineConfig({
99
+ theme: '${config.theme}',
100
+ ${config.features.hotReload ? "hotReload: true," : ""}
101
+ ${config.features.router ? "router: { dir: './screens' }," : ""}
102
+ });
103
+ `
104
+ });
105
+ const themeSrc = getBuiltinTheme(config.theme);
106
+ if (themeSrc) {
107
+ files.push({ path: `themes/${config.theme}.tss`, content: themeSrc.trim() + "\n" });
108
+ }
109
+ switch (config.template) {
110
+ case "dashboard":
111
+ files.push(...generateDashboardTemplate(config));
112
+ break;
113
+ case "interactive-tool":
114
+ files.push(...generateInteractiveTemplate(config));
115
+ break;
116
+ case "cli-wrapper":
117
+ files.push(...generateCliWrapperTemplate(config));
118
+ break;
119
+ default:
120
+ files.push(...generateEmptyTemplate(config));
121
+ }
122
+ return files;
123
+ }
124
+ function generateEmptyTemplate(config) {
125
+ return [{
126
+ path: "src/index.tsx",
127
+ content: `import { app } from '@termuijs/quick';
128
+ import { Text, Box } from '@termuijs/ui';
129
+
130
+ app('${config.name}')
131
+ .rows(
132
+ // Add your widgets here
133
+ )
134
+ .run();
135
+ `
136
+ }];
137
+ }
138
+ function generateDashboardTemplate(config) {
139
+ return [{
140
+ path: "src/index.tsx",
141
+ content: `import { app, gauge, table, sparkline } from '@termuijs/quick';
142
+ ${config.features.dataProviders ? "import { cpu, memory, disk, processes } from '@termuijs/data';" : ""}
143
+
144
+ app('\u26A1 ${config.name}')
145
+ .rows(
146
+ // Row 1: Gauges
147
+ app.cols(
148
+ gauge('CPU', () => ${config.features.dataProviders ? "cpu.percent / 100" : "0.5"}),
149
+ gauge('MEM', () => ${config.features.dataProviders ? "memory.percent / 100" : "0.3"}),
150
+ gauge('DSK', () => ${config.features.dataProviders ? "disk.percent / 100" : "0.7"}),
151
+ ),
152
+ // Row 2: Table
153
+ table('Processes', {
154
+ columns: ['Name', 'PID', 'CPU%', 'MEM%'],
155
+ data: () => ${config.features.dataProviders ? `processes.top(10).map(p => ({
156
+ Name: p.name.slice(0, 18),
157
+ PID: p.pid,
158
+ 'CPU%': p.cpu.toFixed(1),
159
+ 'MEM%': p.mem.toFixed(1),
160
+ }))` : `[{ Name: 'example', PID: 1234, 'CPU%': '5.0', 'MEM%': '2.1' }]`},
161
+ }),
162
+ )
163
+ .run();
164
+ `
165
+ }];
166
+ }
167
+ function generateInteractiveTemplate(config) {
168
+ return [{
169
+ path: "src/index.tsx",
170
+ content: `import { app } from '@termuijs/quick';
171
+ import { Form, Select, Toast, ConfirmDialog } from '@termuijs/ui';
172
+
173
+ // Interactive tool with forms, selects, and toasts
174
+ app('\u{1F527} ${config.name}')
175
+ .rows(
176
+ // Add your interactive components here
177
+ )
178
+ .run();
179
+ `
180
+ }];
181
+ }
182
+ function generateCliWrapperTemplate(config) {
183
+ return [{
184
+ path: "src/index.tsx",
185
+ content: `import { app, text, logView } from '@termuijs/quick';
186
+ import { exec } from 'node:child_process';
187
+
188
+ // CLI wrapper \u2014 runs a command and displays output
189
+ const logs: string[] = [];
190
+
191
+ app('\u{1F4DF} ${config.name}')
192
+ .rows(
193
+ text('Command output will appear below'),
194
+ logView('Output', () => logs),
195
+ )
196
+ .run();
197
+ `
198
+ }];
199
+ }
200
+
201
+ // src/index.ts
202
+ var TEMPLATES = ["Empty (start from scratch)", "Dashboard (real-time data)", "Interactive Tool (forms, prompts)", "CLI Wrapper (wrap existing CLI)"];
203
+ var TEMPLATE_KEYS = ["empty", "dashboard", "interactive-tool", "cli-wrapper"];
204
+ var FEATURES = ["Screen Router", "Data Providers", "Hot Reload"];
205
+ async function main() {
206
+ console.log();
207
+ console.log(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
208
+ console.log(" \u2502 create-termui-app \u2502");
209
+ console.log(" \u2502 The React/Next.js for CLI apps \u2502");
210
+ console.log(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
211
+ console.log();
212
+ let projectName = process.argv[2];
213
+ if (!projectName) {
214
+ projectName = await textPrompt("Project name", "my-termui-app");
215
+ }
216
+ const templateIdx = await selectPrompt("What kind of app?", TEMPLATES);
217
+ const template = TEMPLATE_KEYS[templateIdx];
218
+ const themes = getBuiltinThemeNames();
219
+ const themeIdx = await selectPrompt("Choose a theme", themes.map((t) => t.charAt(0).toUpperCase() + t.slice(1)));
220
+ const theme = themes[themeIdx];
221
+ const featureDefaults = [false, template === "dashboard", true];
222
+ const featureFlags = await multiSelectPrompt("Features to include", FEATURES, featureDefaults);
223
+ const config = {
224
+ name: projectName,
225
+ template,
226
+ theme,
227
+ features: {
228
+ router: featureFlags[0],
229
+ dataProviders: featureFlags[1],
230
+ hotReload: featureFlags[2]
231
+ }
232
+ };
233
+ const projectDir = resolve(process.cwd(), projectName);
234
+ if (existsSync(projectDir)) {
235
+ console.log(`
236
+ \u26A0 Directory "${projectName}" already exists. Files may be overwritten.
237
+ `);
238
+ }
239
+ console.log(`
240
+ Creating ${projectName}...`);
241
+ const files = generateProject(config);
242
+ for (const file of files) {
243
+ const fullPath = join(projectDir, file.path);
244
+ const dir = fullPath.substring(0, fullPath.lastIndexOf("/"));
245
+ mkdirSync(dir, { recursive: true });
246
+ writeFileSync(fullPath, file.content, "utf-8");
247
+ console.log(` \u2713 ${file.path}`);
248
+ }
249
+ console.log();
250
+ console.log(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
251
+ console.log(" \u2502 \u2705 Project created successfully! \u2502");
252
+ console.log(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
253
+ console.log();
254
+ console.log(` Next steps:`);
255
+ console.log(` cd ${projectName}`);
256
+ console.log(` npm install`);
257
+ console.log(` npm run dev`);
258
+ console.log();
259
+ }
260
+ main().catch((err) => {
261
+ console.error("Error:", err.message);
262
+ process.exit(1);
263
+ });
264
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/prompts.ts","../src/templates.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────\n// create-termui-app — Interactive CLI scaffolding tool\n// ─────────────────────────────────────────────────────\n\nimport { resolve, join } from 'node:path';\nimport { mkdirSync, writeFileSync, existsSync } from 'node:fs';\nimport { getBuiltinThemeNames } from '@termuijs/tss';\nimport { textPrompt, selectPrompt, multiSelectPrompt } from './prompts.js';\nimport { generateProject, type ProjectConfig } from './templates.js';\n\nconst TEMPLATES = ['Empty (start from scratch)', 'Dashboard (real-time data)', 'Interactive Tool (forms, prompts)', 'CLI Wrapper (wrap existing CLI)'];\nconst TEMPLATE_KEYS = ['empty', 'dashboard', 'interactive-tool', 'cli-wrapper'] as const;\nconst FEATURES = ['Screen Router', 'Data Providers', 'Hot Reload'];\n\nasync function main() {\n console.log();\n console.log(' ┌──────────────────────────────────┐');\n console.log(' │ create-termui-app │');\n console.log(' │ The React/Next.js for CLI apps │');\n console.log(' └──────────────────────────────────┘');\n console.log();\n\n // ── Get project name from args or prompt ──\n let projectName = process.argv[2];\n if (!projectName) {\n projectName = await textPrompt('Project name', 'my-termui-app');\n }\n\n // ── Template selection ──\n const templateIdx = await selectPrompt('What kind of app?', TEMPLATES);\n const template = TEMPLATE_KEYS[templateIdx];\n\n // ── Theme selection ──\n const themes = getBuiltinThemeNames();\n const themeIdx = await selectPrompt('Choose a theme', themes.map(t => t.charAt(0).toUpperCase() + t.slice(1)));\n const theme = themes[themeIdx];\n\n // ── Feature selection ──\n const featureDefaults = [false, template === 'dashboard', true]; // Router off, Data on for dashboard, HotReload on\n const featureFlags = await multiSelectPrompt('Features to include', FEATURES, featureDefaults);\n\n const config: ProjectConfig = {\n name: projectName,\n template,\n theme,\n features: {\n router: featureFlags[0],\n dataProviders: featureFlags[1],\n hotReload: featureFlags[2],\n },\n };\n\n // ── Generate project ──\n const projectDir = resolve(process.cwd(), projectName);\n if (existsSync(projectDir)) {\n console.log(`\\n ⚠ Directory \"${projectName}\" already exists. Files may be overwritten.\\n`);\n }\n\n console.log(`\\n Creating ${projectName}...`);\n\n const files = generateProject(config);\n\n for (const file of files) {\n const fullPath = join(projectDir, file.path);\n const dir = fullPath.substring(0, fullPath.lastIndexOf('/'));\n mkdirSync(dir, { recursive: true });\n writeFileSync(fullPath, file.content, 'utf-8');\n console.log(` ✓ ${file.path}`);\n }\n\n console.log();\n console.log(' ┌──────────────────────────────────┐');\n console.log(' │ ✅ Project created successfully! │');\n console.log(' └──────────────────────────────────┘');\n console.log();\n console.log(` Next steps:`);\n console.log(` cd ${projectName}`);\n console.log(` npm install`);\n console.log(` npm run dev`);\n console.log();\n}\n\nmain().catch(err => {\n console.error('Error:', err.message);\n process.exit(1);\n});\n","// ─────────────────────────────────────────────────────\n// Minimal interactive prompts (no external deps)\n// ─────────────────────────────────────────────────────\n\nimport { createInterface } from 'node:readline';\n\nconst rl = () => createInterface({ input: process.stdin, output: process.stdout });\n\nexport async function textPrompt(question: string, defaultValue?: string): Promise<string> {\n return new Promise(resolve => {\n const r = rl();\n const suffix = defaultValue ? ` (${defaultValue})` : '';\n r.question(` ${question}${suffix}: `, answer => {\n r.close();\n resolve(answer.trim() || defaultValue || '');\n });\n });\n}\n\nexport async function selectPrompt(question: string, options: string[]): Promise<number> {\n console.log(`\\n ${question}`);\n for (let i = 0; i < options.length; i++) {\n console.log(` ${i + 1}) ${options[i]}`);\n }\n const answer = await textPrompt('Enter number', '1');\n const idx = parseInt(answer) - 1;\n return Math.max(0, Math.min(idx, options.length - 1));\n}\n\nexport async function confirmPrompt(question: string, defaultValue = true): Promise<boolean> {\n const suffix = defaultValue ? '(Y/n)' : '(y/N)';\n const answer = await textPrompt(`${question} ${suffix}`);\n if (!answer) return defaultValue;\n return answer.toLowerCase().startsWith('y');\n}\n\nexport async function multiSelectPrompt(question: string, options: string[], defaults: boolean[] = []): Promise<boolean[]> {\n console.log(`\\n ${question} (comma-separated numbers, or 'all')`);\n for (let i = 0; i < options.length; i++) {\n const def = defaults[i] ? '✓' : ' ';\n console.log(` ${i + 1}) [${def}] ${options[i]}`);\n }\n const answer = await textPrompt('Enter numbers', defaults.some(d => d) ? 'keep defaults' : 'all');\n if (answer === 'all') return options.map(() => true);\n if (answer === 'keep defaults' || answer === '') return defaults.length ? defaults : options.map(() => true);\n const selected = answer.split(',').map(s => parseInt(s.trim()) - 1);\n return options.map((_, i) => selected.includes(i));\n}\n","// ─────────────────────────────────────────────────────\n// Project Templates — generates files for new apps\n// ─────────────────────────────────────────────────────\n\nimport { getBuiltinTheme } from '@termuijs/tss';\n\nexport interface ProjectConfig {\n name: string;\n template: 'empty' | 'dashboard' | 'interactive-tool' | 'cli-wrapper';\n theme: string;\n features: {\n router: boolean;\n dataProviders: boolean;\n hotReload: boolean;\n };\n}\n\nexport interface GeneratedFile {\n path: string;\n content: string;\n}\n\nexport function generateProject(config: ProjectConfig): GeneratedFile[] {\n const files: GeneratedFile[] = [];\n\n // ── package.json ──\n files.push({\n path: 'package.json',\n content: JSON.stringify({\n name: config.name,\n version: '0.1.0',\n private: true,\n type: 'module',\n scripts: {\n dev: 'tsx --watch src/index.tsx',\n build: 'tsup src/index.tsx --format esm',\n start: 'node dist/index.js',\n },\n dependencies: {\n '@termuijs/core': 'latest',\n '@termuijs/widgets': 'latest',\n '@termuijs/ui': 'latest',\n '@termuijs/jsx': 'latest',\n '@termuijs/tss': 'latest',\n ...(config.features.dataProviders ? { '@termuijs/data': 'latest' } : {}),\n ...(config.features.router ? { '@termuijs/router': 'latest' } : {}),\n },\n devDependencies: {\n tsx: '^4.0.0',\n tsup: '^8.0.0',\n typescript: '^5.3.0',\n },\n }, null, 2) + '\\n',\n });\n\n // ── tsconfig.json ──\n files.push({\n path: 'tsconfig.json',\n content: JSON.stringify({\n compilerOptions: {\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'bundler',\n jsx: 'react-jsx',\n jsxImportSource: '@termuijs/jsx',\n strict: true,\n esModuleInterop: true,\n outDir: 'dist',\n rootDir: 'src',\n },\n include: ['src'],\n }, null, 2) + '\\n',\n });\n\n // ── termui.config.ts ──\n files.push({\n path: 'termui.config.ts',\n content: `import { defineConfig } from '@termuijs/core';\n\nexport default defineConfig({\n theme: '${config.theme}',\n ${config.features.hotReload ? \"hotReload: true,\" : ''}\n ${config.features.router ? \"router: { dir: './screens' },\" : ''}\n});\n`,\n });\n\n // ── Theme file ──\n const themeSrc = getBuiltinTheme(config.theme);\n if (themeSrc) {\n files.push({ path: `themes/${config.theme}.tss`, content: themeSrc.trim() + '\\n' });\n }\n\n // ── Template-specific files ──\n switch (config.template) {\n case 'dashboard':\n files.push(...generateDashboardTemplate(config));\n break;\n case 'interactive-tool':\n files.push(...generateInteractiveTemplate(config));\n break;\n case 'cli-wrapper':\n files.push(...generateCliWrapperTemplate(config));\n break;\n default:\n files.push(...generateEmptyTemplate(config));\n }\n\n return files;\n}\n\nfunction generateEmptyTemplate(config: ProjectConfig): GeneratedFile[] {\n return [{\n path: 'src/index.tsx',\n content: `import { app } from '@termuijs/quick';\nimport { Text, Box } from '@termuijs/ui';\n\napp('${config.name}')\n .rows(\n // Add your widgets here\n )\n .run();\n`,\n }];\n}\n\nfunction generateDashboardTemplate(config: ProjectConfig): GeneratedFile[] {\n return [{\n path: 'src/index.tsx',\n content: `import { app, gauge, table, sparkline } from '@termuijs/quick';\n${config.features.dataProviders ? \"import { cpu, memory, disk, processes } from '@termuijs/data';\" : ''}\n\napp('⚡ ${config.name}')\n .rows(\n // Row 1: Gauges\n app.cols(\n gauge('CPU', () => ${config.features.dataProviders ? 'cpu.percent / 100' : '0.5'}),\n gauge('MEM', () => ${config.features.dataProviders ? 'memory.percent / 100' : '0.3'}),\n gauge('DSK', () => ${config.features.dataProviders ? 'disk.percent / 100' : '0.7'}),\n ),\n // Row 2: Table\n table('Processes', {\n columns: ['Name', 'PID', 'CPU%', 'MEM%'],\n data: () => ${config.features.dataProviders\n ? `processes.top(10).map(p => ({\n Name: p.name.slice(0, 18),\n PID: p.pid,\n 'CPU%': p.cpu.toFixed(1),\n 'MEM%': p.mem.toFixed(1),\n }))`\n : `[{ Name: 'example', PID: 1234, 'CPU%': '5.0', 'MEM%': '2.1' }]`},\n }),\n )\n .run();\n`,\n }];\n}\n\nfunction generateInteractiveTemplate(config: ProjectConfig): GeneratedFile[] {\n return [{\n path: 'src/index.tsx',\n content: `import { app } from '@termuijs/quick';\nimport { Form, Select, Toast, ConfirmDialog } from '@termuijs/ui';\n\n// Interactive tool with forms, selects, and toasts\napp('🔧 ${config.name}')\n .rows(\n // Add your interactive components here\n )\n .run();\n`,\n }];\n}\n\nfunction generateCliWrapperTemplate(config: ProjectConfig): GeneratedFile[] {\n return [{\n path: 'src/index.tsx',\n content: `import { app, text, logView } from '@termuijs/quick';\nimport { exec } from 'node:child_process';\n\n// CLI wrapper — runs a command and displays output\nconst logs: string[] = [];\n\napp('📟 ${config.name}')\n .rows(\n text('Command output will appear below'),\n logView('Output', () => logs),\n )\n .run();\n`,\n }];\n}\n"],"mappings":"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","names":["resolve"]}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "create-termui-app",
3
+ "version": "0.1.0",
4
+ "description": "Scaffold a new TermUI app — the create-react-app for terminals",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-termui-app": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "dependencies": {
14
+ "@termuijs/tss": "0.1.0"
15
+ },
16
+ "devDependencies": {
17
+ "tsup": "^8.0.0",
18
+ "typescript": "^5.3.0"
19
+ },
20
+ "keywords": [
21
+ "terminal",
22
+ "tui",
23
+ "cli",
24
+ "scaffold",
25
+ "create-app",
26
+ "generator"
27
+ ],
28
+ "license": "MIT",
29
+ "scripts": {
30
+ "build": "tsup",
31
+ "dev": "tsup --watch"
32
+ }
33
+ }