task-o-matic 0.0.13 → 0.0.15
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/cli/display/progress.d.ts +15 -2
- package/dist/cli/display/progress.d.ts.map +1 -1
- package/dist/cli/display/progress.js +72 -4
- package/dist/commands/benchmark.d.ts.map +1 -1
- package/dist/commands/benchmark.js +11 -3
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +60 -12
- package/dist/commands/prd.js +7 -1
- package/dist/commands/tasks/delete.d.ts.map +1 -1
- package/dist/commands/tasks/delete.js +2 -1
- package/dist/commands/tasks/document/add.d.ts.map +1 -1
- package/dist/commands/tasks/document/add.js +5 -4
- package/dist/commands/tasks/document/get.d.ts.map +1 -1
- package/dist/commands/tasks/document/get.js +2 -1
- package/dist/commands/tasks/list.js +2 -2
- package/dist/commands/tasks/next.js +4 -4
- package/dist/commands/tasks/plan/set.d.ts.map +1 -1
- package/dist/commands/tasks/plan/set.js +11 -3
- package/dist/commands/tasks/show.d.ts.map +1 -1
- package/dist/commands/tasks/show.js +2 -1
- package/dist/commands/tasks/status.d.ts.map +1 -1
- package/dist/commands/tasks/status.js +4 -3
- package/dist/commands/tasks/update.d.ts.map +1 -1
- package/dist/commands/tasks/update.js +7 -1
- package/dist/lib/ai-service/ai-operations.d.ts +1 -1
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/base-operations.d.ts +22 -0
- package/dist/lib/ai-service/base-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/base-operations.js +29 -1
- package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
- package/dist/lib/ai-service/model-provider.js +37 -6
- package/dist/lib/ai-service/task-operations.d.ts +2 -1
- package/dist/lib/ai-service/task-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/task-operations.js +135 -173
- package/dist/lib/benchmark/registry.d.ts.map +1 -1
- package/dist/lib/benchmark/registry.js +6 -10
- package/dist/lib/better-t-stack-cli.d.ts +36 -21
- package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
- package/dist/lib/better-t-stack-cli.js +212 -33
- package/dist/lib/bootstrap/cli-bootstrap.d.ts +14 -0
- package/dist/lib/bootstrap/cli-bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap/cli-bootstrap.js +325 -0
- package/dist/lib/bootstrap/index.d.ts +4 -0
- package/dist/lib/bootstrap/index.d.ts.map +1 -0
- package/dist/lib/bootstrap/index.js +19 -0
- package/dist/lib/bootstrap/medusa-bootstrap.d.ts +14 -0
- package/dist/lib/bootstrap/medusa-bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap/medusa-bootstrap.js +218 -0
- package/dist/lib/bootstrap/opentui-bootstrap.d.ts +11 -0
- package/dist/lib/bootstrap/opentui-bootstrap.d.ts.map +1 -0
- package/dist/lib/bootstrap/opentui-bootstrap.js +342 -0
- package/dist/lib/config-validation.d.ts +215 -0
- package/dist/lib/config-validation.d.ts.map +1 -0
- package/dist/lib/config-validation.js +246 -0
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +37 -5
- package/dist/lib/storage/file-system.d.ts.map +1 -1
- package/dist/lib/storage/file-system.js +81 -21
- package/dist/lib/task-execution-core.d.ts.map +1 -1
- package/dist/lib/task-execution-core.js +3 -2
- package/dist/services/prd.d.ts +17 -0
- package/dist/services/prd.d.ts.map +1 -1
- package/dist/services/prd.js +67 -60
- package/dist/services/tasks.d.ts +317 -3
- package/dist/services/tasks.d.ts.map +1 -1
- package/dist/services/tasks.js +531 -185
- package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
- package/dist/services/workflow-ai-assistant.js +19 -6
- package/dist/test/lib/ai-service/task-operations.test.d.ts +2 -0
- package/dist/test/lib/ai-service/task-operations.test.d.ts.map +1 -0
- package/dist/test/lib/ai-service/task-operations.test.js +362 -0
- package/dist/test/mocks/mock-ai-operations.d.ts +15 -0
- package/dist/test/mocks/mock-ai-operations.d.ts.map +1 -0
- package/dist/test/mocks/mock-ai-operations.js +107 -0
- package/dist/test/mocks/mock-context-builder.d.ts +10 -0
- package/dist/test/mocks/mock-context-builder.d.ts.map +1 -0
- package/dist/test/mocks/mock-context-builder.js +81 -0
- package/dist/test/mocks/mock-model-provider.d.ts +7 -0
- package/dist/test/mocks/mock-model-provider.d.ts.map +1 -0
- package/dist/test/mocks/mock-model-provider.js +21 -0
- package/dist/test/mocks/mock-service-factory.d.ts +11 -0
- package/dist/test/mocks/mock-service-factory.d.ts.map +1 -0
- package/dist/test/mocks/mock-service-factory.js +61 -0
- package/dist/test/mocks/mock-storage.d.ts +50 -0
- package/dist/test/mocks/mock-storage.d.ts.map +1 -0
- package/dist/test/mocks/mock-storage.js +145 -0
- package/dist/test/services/task-service.test.d.ts +2 -0
- package/dist/test/services/task-service.test.d.ts.map +1 -0
- package/dist/test/services/task-service.test.js +352 -0
- package/dist/test/test-mock-setup.d.ts +26 -0
- package/dist/test/test-mock-setup.d.ts.map +1 -0
- package/dist/test/test-mock-setup.js +41 -0
- package/dist/test/test-setup.d.ts +9 -0
- package/dist/test/test-setup.d.ts.map +1 -0
- package/dist/test/test-setup.js +44 -0
- package/dist/test/test-utils.d.ts +22 -0
- package/dist/test/test-utils.d.ts.map +1 -0
- package/dist/test/test-utils.js +37 -0
- package/dist/test/utils/ai-operation-utility.test.d.ts +2 -0
- package/dist/test/utils/ai-operation-utility.test.d.ts.map +1 -0
- package/dist/test/utils/ai-operation-utility.test.js +290 -0
- package/dist/test/utils/error-handling.test.d.ts +2 -0
- package/dist/test/utils/error-handling.test.d.ts.map +1 -0
- package/dist/test/utils/error-handling.test.js +231 -0
- package/dist/types/index.d.ts +36 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/results.d.ts +60 -6
- package/dist/types/results.d.ts.map +1 -1
- package/dist/utils/ai-operation-utility.d.ts +142 -0
- package/dist/utils/ai-operation-utility.d.ts.map +1 -0
- package/dist/utils/ai-operation-utility.js +288 -0
- package/dist/utils/ai-service-factory.d.ts +10 -0
- package/dist/utils/ai-service-factory.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.js +19 -1
- package/dist/utils/cli-validators.d.ts +2 -2
- package/dist/utils/cli-validators.d.ts.map +1 -1
- package/dist/utils/cli-validators.js +7 -6
- package/dist/utils/error-utils.d.ts +70 -0
- package/dist/utils/error-utils.d.ts.map +1 -0
- package/dist/utils/error-utils.js +104 -0
- package/dist/utils/file-utils.d.ts +49 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +82 -0
- package/dist/utils/id-generator.d.ts +92 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +146 -0
- package/dist/utils/model-executor-parser.d.ts +1 -1
- package/dist/utils/model-executor-parser.d.ts.map +1 -1
- package/dist/utils/model-executor-parser.js +3 -2
- package/dist/utils/stack-formatter.d.ts +2 -1
- package/dist/utils/stack-formatter.d.ts.map +1 -1
- package/dist/utils/stack-formatter.js +8 -2
- package/dist/utils/storage-utils.d.ts +49 -0
- package/dist/utils/storage-utils.d.ts.map +1 -0
- package/dist/utils/storage-utils.js +80 -0
- package/dist/utils/streaming-utils.d.ts +38 -0
- package/dist/utils/streaming-utils.d.ts.map +1 -0
- package/dist/utils/streaming-utils.js +56 -0
- package/dist/utils/task-o-matic-error.d.ts +206 -0
- package/dist/utils/task-o-matic-error.d.ts.map +1 -0
- package/dist/utils/task-o-matic-error.js +304 -0
- package/docs/agents/cli.md +58 -149
- package/package.json +2 -2
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.bootstrapMedusaProject = bootstrapMedusaProject;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const crypto_1 = require("crypto");
|
|
13
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
14
|
+
async function bootstrapMedusaProject(options) {
|
|
15
|
+
try {
|
|
16
|
+
console.log(chalk_1.default.blue(`\n🚀 Bootstrapping MedusaJS project: ${options.projectName}`));
|
|
17
|
+
// Create project directory
|
|
18
|
+
if (!(0, fs_1.existsSync)(options.projectPath)) {
|
|
19
|
+
(0, fs_1.mkdirSync)(options.projectPath, { recursive: true });
|
|
20
|
+
console.log(chalk_1.default.green(` ✓ Created project directory`));
|
|
21
|
+
}
|
|
22
|
+
// Build create-medusa-app command with correct package runner
|
|
23
|
+
const versionFlag = options.version ? `@${options.version}` : "@latest";
|
|
24
|
+
const dbFlag = options.database === "postgres"
|
|
25
|
+
? "--db-type postgres"
|
|
26
|
+
: "--db-type sqlite";
|
|
27
|
+
const skipInstallFlag = options.skipInstall ? "--skip-install" : "";
|
|
28
|
+
// Respect package manager for the runner
|
|
29
|
+
const packageRunner = options.packageManager === "npm"
|
|
30
|
+
? "npx"
|
|
31
|
+
: options.packageManager === "pnpm"
|
|
32
|
+
? "pnpm dlx"
|
|
33
|
+
: "bunx";
|
|
34
|
+
// Use the project path as the target directory
|
|
35
|
+
const createCmd = `${packageRunner} create-medusa-app${versionFlag} ${options.projectPath} ${dbFlag} ${skipInstallFlag} --skip-db --no-browser`;
|
|
36
|
+
console.log(chalk_1.default.cyan(`\n 📦 Running create-medusa-app with ${options.packageManager}...`));
|
|
37
|
+
await execAsync(createCmd, { cwd: process.cwd() });
|
|
38
|
+
console.log(chalk_1.default.green(` ✓ MedusaJS project scaffolded`));
|
|
39
|
+
// Generate environment file
|
|
40
|
+
const envContent = generateEnvFile(options);
|
|
41
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, ".env"), envContent);
|
|
42
|
+
console.log(chalk_1.default.green(` ✓ Created .env file`));
|
|
43
|
+
// Generate README
|
|
44
|
+
const readmeContent = generateReadme(options);
|
|
45
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, "README.md"), readmeContent);
|
|
46
|
+
console.log(chalk_1.default.green(` ✓ Created README.md`));
|
|
47
|
+
// Install dependencies if not skipped
|
|
48
|
+
if (!options.skipInstall) {
|
|
49
|
+
console.log(chalk_1.default.cyan(`\n 📦 Installing dependencies with ${options.packageManager}...`));
|
|
50
|
+
const installCmd = options.packageManager === "npm"
|
|
51
|
+
? "npm install"
|
|
52
|
+
: options.packageManager === "pnpm"
|
|
53
|
+
? "pnpm install"
|
|
54
|
+
: "bun install";
|
|
55
|
+
await execAsync(installCmd, { cwd: options.projectPath });
|
|
56
|
+
console.log(chalk_1.default.green(` ✓ Dependencies installed`));
|
|
57
|
+
}
|
|
58
|
+
// Setup database if not skipped
|
|
59
|
+
if (!options.skipDb) {
|
|
60
|
+
console.log(chalk_1.default.cyan(`\n 🗄️ Setting up database...`));
|
|
61
|
+
try {
|
|
62
|
+
const packageRunner = options.packageManager === "npm"
|
|
63
|
+
? "npx"
|
|
64
|
+
: options.packageManager === "pnpm"
|
|
65
|
+
? "pnpm dlx"
|
|
66
|
+
: "bunx";
|
|
67
|
+
await execAsync(`${packageRunner} medusa db:setup`, {
|
|
68
|
+
cwd: options.projectPath,
|
|
69
|
+
});
|
|
70
|
+
console.log(chalk_1.default.green(` ✓ Database setup complete`));
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const packageRunner = options.packageManager === "npm"
|
|
74
|
+
? "npx"
|
|
75
|
+
: options.packageManager === "pnpm"
|
|
76
|
+
? "pnpm dlx"
|
|
77
|
+
: "bunx";
|
|
78
|
+
console.log(chalk_1.default.yellow(` ⚠️ Database setup skipped (run '${packageRunner} medusa db:setup' manually)`));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
success: true,
|
|
83
|
+
message: `MedusaJS project "${options.projectName}" created successfully!`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
message: `Failed to bootstrap MedusaJS project: ${message}`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function generateEnvFile(options) {
|
|
95
|
+
const database = options.database || "sqlite";
|
|
96
|
+
const databaseUrl = database === "postgres"
|
|
97
|
+
? "postgres://postgres:postgres@localhost:5432/medusa-store"
|
|
98
|
+
: "sqlite://./medusa.db";
|
|
99
|
+
// Generate secure random secrets
|
|
100
|
+
const jwtSecret = (0, crypto_1.randomBytes)(32).toString("hex");
|
|
101
|
+
const cookieSecret = (0, crypto_1.randomBytes)(32).toString("hex");
|
|
102
|
+
return `# Database Configuration
|
|
103
|
+
DATABASE_URL=${databaseUrl}
|
|
104
|
+
|
|
105
|
+
# Authentication Secrets (auto-generated)
|
|
106
|
+
JWT_SECRET=${jwtSecret}
|
|
107
|
+
COOKIE_SECRET=${cookieSecret}
|
|
108
|
+
|
|
109
|
+
# CORS Configuration (adjust for your frontend)
|
|
110
|
+
STORE_CORS=http://localhost:8000
|
|
111
|
+
ADMIN_CORS=http://localhost:7001,http://localhost:7000
|
|
112
|
+
|
|
113
|
+
# Server Configuration
|
|
114
|
+
PORT=9000
|
|
115
|
+
|
|
116
|
+
# Redis (optional - uncomment for production)
|
|
117
|
+
# REDIS_URL=redis://localhost:6379
|
|
118
|
+
|
|
119
|
+
# Worker Mode (shared = single process, server = API only, worker = background jobs only)
|
|
120
|
+
WORKER_MODE=shared
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
function generateReadme(options) {
|
|
124
|
+
const database = options.database || "sqlite";
|
|
125
|
+
return `# ${options.projectName}
|
|
126
|
+
|
|
127
|
+
MedusaJS e-commerce backend generated by task-o-matic
|
|
128
|
+
|
|
129
|
+
## Getting Started
|
|
130
|
+
|
|
131
|
+
### Prerequisites
|
|
132
|
+
|
|
133
|
+
${database === "postgres"
|
|
134
|
+
? `- PostgreSQL database running
|
|
135
|
+
- Update \`DATABASE_URL\` in \`.env\` with your database credentials`
|
|
136
|
+
: `- SQLite (no additional setup required)`}
|
|
137
|
+
|
|
138
|
+
### Installation
|
|
139
|
+
|
|
140
|
+
\`\`\`bash
|
|
141
|
+
${options.packageManager} install
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
### Database Setup
|
|
145
|
+
|
|
146
|
+
\`\`\`bash
|
|
147
|
+
# Run migrations and seed data
|
|
148
|
+
${options.packageManager === "npm"
|
|
149
|
+
? "npx"
|
|
150
|
+
: options.packageManager === "pnpm"
|
|
151
|
+
? "pnpm dlx"
|
|
152
|
+
: "bunx"} medusa db:setup
|
|
153
|
+
\`\`\`
|
|
154
|
+
|
|
155
|
+
### Development
|
|
156
|
+
|
|
157
|
+
\`\`\`bash
|
|
158
|
+
# Start development server
|
|
159
|
+
${options.packageManager} run dev
|
|
160
|
+
|
|
161
|
+
# The API will be available at http://localhost:9000
|
|
162
|
+
# Admin dashboard at http://localhost:9000/app
|
|
163
|
+
\`\`\`
|
|
164
|
+
|
|
165
|
+
### Build
|
|
166
|
+
|
|
167
|
+
\`\`\`bash
|
|
168
|
+
# Build for production
|
|
169
|
+
${options.packageManager} run build
|
|
170
|
+
|
|
171
|
+
# Start production server
|
|
172
|
+
${options.packageManager} start
|
|
173
|
+
\`\`\`
|
|
174
|
+
|
|
175
|
+
## Project Structure
|
|
176
|
+
|
|
177
|
+
- \`src/\` - Source code
|
|
178
|
+
- \`src/admin/\` - Admin dashboard customizations
|
|
179
|
+
- \`src/api/\` - API routes and middlewares
|
|
180
|
+
- \`src/modules/\` - Custom modules
|
|
181
|
+
- \`src/workflows/\` - Business logic workflows
|
|
182
|
+
- \`src/subscribers/\` - Event subscribers
|
|
183
|
+
- \`medusa-config.ts\` - MedusaJS configuration
|
|
184
|
+
- \`.env\` - Environment variables
|
|
185
|
+
|
|
186
|
+
## Environment Variables
|
|
187
|
+
|
|
188
|
+
Key environment variables (see \`.env\` for full list):
|
|
189
|
+
|
|
190
|
+
- \`DATABASE_URL\` - Database connection string
|
|
191
|
+
- \`JWT_SECRET\` - Secret for JWT tokens
|
|
192
|
+
- \`COOKIE_SECRET\` - Secret for cookies
|
|
193
|
+
- \`STORE_CORS\` - Allowed origins for storefront
|
|
194
|
+
- \`ADMIN_CORS\` - Allowed origins for admin
|
|
195
|
+
|
|
196
|
+
## Documentation
|
|
197
|
+
|
|
198
|
+
- [MedusaJS Documentation](https://docs.medusajs.com)
|
|
199
|
+
- [API Reference](https://docs.medusajs.com/api)
|
|
200
|
+
- [Admin Guide](https://docs.medusajs.com/admin)
|
|
201
|
+
|
|
202
|
+
## Next Steps
|
|
203
|
+
|
|
204
|
+
1. Configure your database connection in \`.env\`
|
|
205
|
+
2. Run \`${options.packageManager === "npm"
|
|
206
|
+
? "npx"
|
|
207
|
+
: options.packageManager === "pnpm"
|
|
208
|
+
? "pnpm dlx"
|
|
209
|
+
: "bunx"} medusa db:setup\` to initialize the database
|
|
210
|
+
3. Start the development server with \`${options.packageManager} run dev\`
|
|
211
|
+
4. Access the admin dashboard at http://localhost:9000/app
|
|
212
|
+
5. Create your first admin user
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
Generated with [task-o-matic](https://github.com/DimitriGilbert/task-o-matic)
|
|
217
|
+
`;
|
|
218
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface OpenTuiBootstrapOptions {
|
|
2
|
+
projectName: string;
|
|
3
|
+
projectPath: string;
|
|
4
|
+
framework: "solid" | "vue" | "react";
|
|
5
|
+
packageManager: "npm" | "pnpm" | "bun";
|
|
6
|
+
}
|
|
7
|
+
export declare function bootstrapOpenTuiProject(options: OpenTuiBootstrapOptions): Promise<{
|
|
8
|
+
success: boolean;
|
|
9
|
+
message: string;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=opentui-bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opentui-bootstrap.d.ts","sourceRoot":"","sources":["../../../src/lib/bootstrap/opentui-bootstrap.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IACrC,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;CACxC;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA4FhD"}
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.bootstrapOpenTuiProject = bootstrapOpenTuiProject;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const child_process_1 = require("child_process");
|
|
11
|
+
const util_1 = require("util");
|
|
12
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
13
|
+
async function bootstrapOpenTuiProject(options) {
|
|
14
|
+
try {
|
|
15
|
+
console.log(chalk_1.default.blue(`\n🚀 Bootstrapping OpenTUI project: ${options.projectName}`));
|
|
16
|
+
// Warn if not using Bun
|
|
17
|
+
if (options.packageManager !== "bun") {
|
|
18
|
+
console.log(chalk_1.default.yellow(` ⚠️ OpenTUI works best with Bun. Consider using --package-manager bun`));
|
|
19
|
+
}
|
|
20
|
+
// Create project directory
|
|
21
|
+
if (!(0, fs_1.existsSync)(options.projectPath)) {
|
|
22
|
+
(0, fs_1.mkdirSync)(options.projectPath, { recursive: true });
|
|
23
|
+
console.log(chalk_1.default.green(` ✓ Created project directory`));
|
|
24
|
+
}
|
|
25
|
+
// Create directory structure
|
|
26
|
+
const dirs = ["src", "src/components"];
|
|
27
|
+
dirs.forEach(dir => {
|
|
28
|
+
const fullPath = (0, path_1.join)(options.projectPath, dir);
|
|
29
|
+
(0, fs_1.mkdirSync)(fullPath, { recursive: true });
|
|
30
|
+
});
|
|
31
|
+
console.log(chalk_1.default.green(` ✓ Created directory structure`));
|
|
32
|
+
// Generate files
|
|
33
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, "package.json"), generatePackageJson(options));
|
|
34
|
+
console.log(chalk_1.default.green(` ✓ Created package.json`));
|
|
35
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, "tsconfig.json"), generateTsConfig());
|
|
36
|
+
console.log(chalk_1.default.green(` ✓ Created tsconfig.json`));
|
|
37
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, "build.ts"), generateBuildScriptTemplate(options.framework));
|
|
38
|
+
console.log(chalk_1.default.green(` ✓ Created build.ts`));
|
|
39
|
+
// Generate framework-specific files
|
|
40
|
+
const extension = options.framework === "vue" ? "vue" : "tsx";
|
|
41
|
+
const indexContent = getFrameworkIndexTemplate(options.framework);
|
|
42
|
+
const appContent = getFrameworkAppTemplate(options.framework);
|
|
43
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, "src/index.ts"), indexContent);
|
|
44
|
+
console.log(chalk_1.default.green(` ✓ Created src/index.ts`));
|
|
45
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, `src/App.${extension}`), appContent);
|
|
46
|
+
console.log(chalk_1.default.green(` ✓ Created src/App.${extension}`));
|
|
47
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, "README.md"), generateReadmeTemplate(options));
|
|
48
|
+
console.log(chalk_1.default.green(` ✓ Created README.md`));
|
|
49
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(options.projectPath, ".gitignore"), generateGitignoreTemplate());
|
|
50
|
+
console.log(chalk_1.default.green(` ✓ Created .gitignore`));
|
|
51
|
+
// Install dependencies
|
|
52
|
+
console.log(chalk_1.default.cyan(`\n 📦 Installing dependencies with ${options.packageManager}...`));
|
|
53
|
+
const installCmd = options.packageManager === "npm" ? "npm install" :
|
|
54
|
+
options.packageManager === "pnpm" ? "pnpm install" :
|
|
55
|
+
"bun install";
|
|
56
|
+
await execAsync(installCmd, { cwd: options.projectPath });
|
|
57
|
+
console.log(chalk_1.default.green(` ✓ Dependencies installed`));
|
|
58
|
+
return {
|
|
59
|
+
success: true,
|
|
60
|
+
message: `OpenTUI project "${options.projectName}" created successfully!`
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
message: `Failed to bootstrap OpenTUI project: ${message}`
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function generatePackageJson(options) {
|
|
72
|
+
const frameworkDeps = getFrameworkDependencies(options.framework);
|
|
73
|
+
const frameworkDevDeps = getFrameworkDevDependencies(options.framework);
|
|
74
|
+
const pkg = {
|
|
75
|
+
name: options.projectName,
|
|
76
|
+
version: "0.1.0",
|
|
77
|
+
type: "module",
|
|
78
|
+
scripts: {
|
|
79
|
+
build: "bun run build.ts",
|
|
80
|
+
dev: "bun run --watch src/index.ts",
|
|
81
|
+
start: "bun run dist/index.js"
|
|
82
|
+
},
|
|
83
|
+
dependencies: {
|
|
84
|
+
"@opentui/core": "latest",
|
|
85
|
+
...frameworkDeps
|
|
86
|
+
},
|
|
87
|
+
devDependencies: {
|
|
88
|
+
typescript: "latest",
|
|
89
|
+
"@types/node": "latest",
|
|
90
|
+
...frameworkDevDeps
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
return JSON.stringify(pkg, null, 2);
|
|
94
|
+
}
|
|
95
|
+
function getFrameworkDependencies(framework) {
|
|
96
|
+
const deps = {
|
|
97
|
+
solid: {
|
|
98
|
+
"@opentui/solid": "latest",
|
|
99
|
+
"solid-js": "latest"
|
|
100
|
+
},
|
|
101
|
+
vue: {
|
|
102
|
+
"@opentui/vue": "latest",
|
|
103
|
+
vue: "latest"
|
|
104
|
+
},
|
|
105
|
+
react: {
|
|
106
|
+
"@opentui/react": "latest",
|
|
107
|
+
react: "latest"
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
return deps[framework];
|
|
111
|
+
}
|
|
112
|
+
function getFrameworkDevDependencies(framework) {
|
|
113
|
+
const devDeps = {
|
|
114
|
+
solid: {
|
|
115
|
+
"bun-plugin-solid": "latest"
|
|
116
|
+
},
|
|
117
|
+
vue: {
|
|
118
|
+
"bun-plugin-vue3": "latest"
|
|
119
|
+
},
|
|
120
|
+
react: {}
|
|
121
|
+
};
|
|
122
|
+
return devDeps[framework];
|
|
123
|
+
}
|
|
124
|
+
function generateTsConfig() {
|
|
125
|
+
const config = {
|
|
126
|
+
compilerOptions: {
|
|
127
|
+
target: "ES2022",
|
|
128
|
+
module: "ESNext",
|
|
129
|
+
moduleResolution: "bundler",
|
|
130
|
+
strict: true,
|
|
131
|
+
esModuleInterop: true,
|
|
132
|
+
skipLibCheck: true,
|
|
133
|
+
jsx: "preserve",
|
|
134
|
+
jsxImportSource: "solid-js",
|
|
135
|
+
types: ["bun-types"]
|
|
136
|
+
},
|
|
137
|
+
include: ["src/**/*", "build.ts"],
|
|
138
|
+
exclude: ["node_modules", "dist"]
|
|
139
|
+
};
|
|
140
|
+
return JSON.stringify(config, null, 2);
|
|
141
|
+
}
|
|
142
|
+
function generateBuildScriptTemplate(framework) {
|
|
143
|
+
const plugins = {
|
|
144
|
+
solid: `import { pluginSolid } from "bun-plugin-solid";`,
|
|
145
|
+
vue: `import { pluginVue3 } from "bun-plugin-vue3";`,
|
|
146
|
+
react: ``
|
|
147
|
+
};
|
|
148
|
+
const pluginArray = {
|
|
149
|
+
solid: `plugins: [pluginSolid()]`,
|
|
150
|
+
vue: `plugins: [pluginVue3()]`,
|
|
151
|
+
react: `plugins: []`
|
|
152
|
+
};
|
|
153
|
+
return `${plugins[framework] ? plugins[framework] + "\n\n" : ""}const result = await Bun.build({
|
|
154
|
+
entrypoints: ["./src/index.ts"],
|
|
155
|
+
outdir: "./dist",
|
|
156
|
+
target: "bun",
|
|
157
|
+
${pluginArray[framework]},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
if (!result.success) {
|
|
161
|
+
console.error("Build failed");
|
|
162
|
+
for (const message of result.logs) {
|
|
163
|
+
console.error(message);
|
|
164
|
+
}
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log("Build successful!");
|
|
169
|
+
`;
|
|
170
|
+
}
|
|
171
|
+
function getFrameworkIndexTemplate(framework) {
|
|
172
|
+
const templates = {
|
|
173
|
+
solid: `import { createCliRenderer } from "@opentui/core";
|
|
174
|
+
import { createRoot } from "@opentui/solid";
|
|
175
|
+
import { App } from "./App";
|
|
176
|
+
|
|
177
|
+
const renderer = await createCliRenderer({
|
|
178
|
+
exitOnCtrlC: true,
|
|
179
|
+
targetFps: 60,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
renderer.start();
|
|
183
|
+
createRoot(renderer).render(() => <App />);
|
|
184
|
+
`,
|
|
185
|
+
vue: `import { createCliRenderer } from "@opentui/core";
|
|
186
|
+
import { createRoot } from "@opentui/vue";
|
|
187
|
+
import App from "./App.vue";
|
|
188
|
+
|
|
189
|
+
const renderer = await createCliRenderer({
|
|
190
|
+
exitOnCtrlC: true,
|
|
191
|
+
targetFps: 60,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
renderer.start();
|
|
195
|
+
createRoot(renderer).render(App);
|
|
196
|
+
`,
|
|
197
|
+
react: `import { createCliRenderer } from "@opentui/core";
|
|
198
|
+
import { createRoot } from "@opentui/react";
|
|
199
|
+
import { App } from "./App";
|
|
200
|
+
|
|
201
|
+
const renderer = await createCliRenderer({
|
|
202
|
+
exitOnCtrlC: true,
|
|
203
|
+
targetFps: 60,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
renderer.start();
|
|
207
|
+
createRoot(renderer).render(<App />);
|
|
208
|
+
`
|
|
209
|
+
};
|
|
210
|
+
return templates[framework];
|
|
211
|
+
}
|
|
212
|
+
function getFrameworkAppTemplate(framework) {
|
|
213
|
+
const templates = {
|
|
214
|
+
solid: `import { TextRenderable } from "@opentui/core";
|
|
215
|
+
|
|
216
|
+
export function App() {
|
|
217
|
+
return (
|
|
218
|
+
<TextRenderable
|
|
219
|
+
content="Hello from OpenTUI with Solid!"
|
|
220
|
+
fg="#00FF00"
|
|
221
|
+
position="absolute"
|
|
222
|
+
left={10}
|
|
223
|
+
top={5}
|
|
224
|
+
/>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
`,
|
|
228
|
+
vue: `<script setup lang="ts">
|
|
229
|
+
</script>
|
|
230
|
+
|
|
231
|
+
<template>
|
|
232
|
+
<textRenderable
|
|
233
|
+
content="Hello from OpenTUI with Vue!"
|
|
234
|
+
:style="{ fg: '#00FF00', position: 'absolute', left: 10, top: 5 }"
|
|
235
|
+
/>
|
|
236
|
+
</template>
|
|
237
|
+
`,
|
|
238
|
+
react: `import { TextRenderable } from "@opentui/core";
|
|
239
|
+
|
|
240
|
+
export function App() {
|
|
241
|
+
return (
|
|
242
|
+
<TextRenderable
|
|
243
|
+
content="Hello from OpenTUI with React!"
|
|
244
|
+
fg="#00FF00"
|
|
245
|
+
position="absolute"
|
|
246
|
+
left={10}
|
|
247
|
+
top={5}
|
|
248
|
+
/>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
`
|
|
252
|
+
};
|
|
253
|
+
return templates[framework];
|
|
254
|
+
}
|
|
255
|
+
function generateReadmeTemplate(options) {
|
|
256
|
+
return `# ${options.projectName}
|
|
257
|
+
|
|
258
|
+
Terminal User Interface (TUI) application built with OpenTUI and ${options.framework === "solid" ? "Solid.js" : options.framework === "vue" ? "Vue.js" : "React"}
|
|
259
|
+
|
|
260
|
+
Generated by task-o-matic
|
|
261
|
+
|
|
262
|
+
## Installation
|
|
263
|
+
|
|
264
|
+
\`\`\`bash
|
|
265
|
+
${options.packageManager} install
|
|
266
|
+
\`\`\`
|
|
267
|
+
|
|
268
|
+
## Development
|
|
269
|
+
|
|
270
|
+
\`\`\`bash
|
|
271
|
+
# Run in development mode with watch
|
|
272
|
+
${options.packageManager} run dev
|
|
273
|
+
|
|
274
|
+
# Build the project
|
|
275
|
+
${options.packageManager} run build
|
|
276
|
+
|
|
277
|
+
# Run the built TUI app
|
|
278
|
+
${options.packageManager} start
|
|
279
|
+
\`\`\`
|
|
280
|
+
|
|
281
|
+
## Project Structure
|
|
282
|
+
|
|
283
|
+
- \`src/index.ts\` - Application entry point
|
|
284
|
+
- \`src/App.${options.framework === "vue" ? "vue" : "tsx"}\` - Main TUI component
|
|
285
|
+
- \`src/components/\` - Reusable TUI components
|
|
286
|
+
- \`build.ts\` - Bun build configuration
|
|
287
|
+
|
|
288
|
+
## Technologies
|
|
289
|
+
|
|
290
|
+
- **OpenTUI** - Terminal UI framework
|
|
291
|
+
- **${options.framework === "solid" ? "Solid.js" : options.framework === "vue" ? "Vue.js" : "React"}** - Component framework
|
|
292
|
+
- **TypeScript** - Type-safe development
|
|
293
|
+
- **Bun** - Fast JavaScript runtime and bundler
|
|
294
|
+
|
|
295
|
+
## Controls
|
|
296
|
+
|
|
297
|
+
- \`Ctrl+C\` - Exit the application
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
Generated with [task-o-matic](https://github.com/anthropics/task-o-matic)
|
|
302
|
+
`;
|
|
303
|
+
}
|
|
304
|
+
function generateGitignoreTemplate() {
|
|
305
|
+
return `# Dependencies
|
|
306
|
+
node_modules/
|
|
307
|
+
.pnp
|
|
308
|
+
.pnp.js
|
|
309
|
+
|
|
310
|
+
# Testing
|
|
311
|
+
coverage/
|
|
312
|
+
|
|
313
|
+
# Production
|
|
314
|
+
dist/
|
|
315
|
+
build/
|
|
316
|
+
|
|
317
|
+
# Misc
|
|
318
|
+
.DS_Store
|
|
319
|
+
.env
|
|
320
|
+
.env.local
|
|
321
|
+
.env.development.local
|
|
322
|
+
.env.test.local
|
|
323
|
+
.env.production.local
|
|
324
|
+
|
|
325
|
+
# Logs
|
|
326
|
+
npm-debug.log*
|
|
327
|
+
yarn-debug.log*
|
|
328
|
+
yarn-error.log*
|
|
329
|
+
lerna-debug.log*
|
|
330
|
+
bun-debug.log*
|
|
331
|
+
|
|
332
|
+
# IDEs
|
|
333
|
+
.idea/
|
|
334
|
+
.vscode/
|
|
335
|
+
*.swp
|
|
336
|
+
*.swo
|
|
337
|
+
*~
|
|
338
|
+
|
|
339
|
+
# TypeScript
|
|
340
|
+
*.tsbuildinfo
|
|
341
|
+
`;
|
|
342
|
+
}
|