task-o-matic 0.0.4 → 0.0.6

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/bin.js CHANGED
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,eAAO,MAAM,eAAe,SAiExB,CAAC"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../../src/commands/workflow.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,eAAO,MAAM,eAAe,SAiExB,CAAC"}
@@ -10,6 +10,7 @@ const chalk_1 = __importDefault(require("chalk"));
10
10
  const fs_1 = require("fs");
11
11
  const path_1 = require("path");
12
12
  const config_1 = require("../lib/config");
13
+ const better_t_stack_cli_1 = require("../lib/better-t-stack-cli");
13
14
  const prd_1 = require("../services/prd");
14
15
  const tasks_1 = require("../services/tasks");
15
16
  const workflow_ai_assistant_1 = require("../services/workflow-ai-assistant");
@@ -72,7 +73,7 @@ exports.workflowCommand = new commander_1.Command("workflow")
72
73
  */
73
74
  async function stepInitialize(state, aiOptions, streamingOptions) {
74
75
  console.log(chalk_1.default.blue.bold("\nšŸ“¦ Step 1: Project Initialization\n"));
75
- // Check if already initialized
76
+ // Check if already initialized in current directory
76
77
  const taskOMaticDir = config_1.configManager.getTaskOMaticDir();
77
78
  const alreadyInitialized = (0, fs_1.existsSync)(taskOMaticDir);
78
79
  if (alreadyInitialized) {
@@ -91,6 +92,7 @@ async function stepInitialize(state, aiOptions, streamingOptions) {
91
92
  state.currentStep = "define-prd";
92
93
  return;
93
94
  }
95
+ const projectName = await (0, workflow_prompts_1.textInputPrompt)("What is the name of your project?", "my-app");
94
96
  // Choose initialization method
95
97
  let initMethod = await (0, workflow_prompts_1.selectPrompt)("How would you like to configure your project?", [
96
98
  { name: "Quick start (recommended defaults)", value: "quick" },
@@ -107,6 +109,8 @@ async function stepInitialize(state, aiOptions, streamingOptions) {
107
109
  aiOptions,
108
110
  streamingOptions,
109
111
  });
112
+ // Override AI's project name with user's choice if they provided one (though we just asked for it, so we should use it)
113
+ config.projectName = projectName;
110
114
  console.log(chalk_1.default.green("\nāœ“ AI Recommendations:"));
111
115
  console.log(chalk_1.default.gray(` Project: ${config.projectName}`));
112
116
  console.log(chalk_1.default.gray(` AI Provider: ${config.aiProvider}`));
@@ -125,7 +129,7 @@ async function stepInitialize(state, aiOptions, streamingOptions) {
125
129
  }
126
130
  if (initMethod === "quick") {
127
131
  config = {
128
- projectName: "my-project",
132
+ projectName: projectName,
129
133
  aiProvider: "openrouter",
130
134
  aiModel: "anthropic/claude-3.5-sonnet",
131
135
  frontend: "next",
@@ -137,7 +141,7 @@ async function stepInitialize(state, aiOptions, streamingOptions) {
137
141
  }
138
142
  else if (initMethod === "custom") {
139
143
  config = {
140
- projectName: await (0, workflow_prompts_1.textInputPrompt)("Project name:", "my-project"),
144
+ projectName: projectName,
141
145
  aiProvider: await (0, workflow_prompts_1.selectPrompt)("AI Provider:", [
142
146
  "openrouter",
143
147
  "anthropic",
@@ -172,15 +176,99 @@ async function stepInitialize(state, aiOptions, streamingOptions) {
172
176
  config.auth = await (0, workflow_prompts_1.confirmPrompt)("Include authentication?", true);
173
177
  }
174
178
  }
175
- // Initialize project
176
- console.log(chalk_1.default.cyan("\n Initializing project...\n"));
177
- // Create .task-o-matic directory
178
- if (!(0, fs_1.existsSync)(taskOMaticDir)) {
179
- (0, fs_1.mkdirSync)(taskOMaticDir, { recursive: true });
179
+ // Bootstrap Logic
180
+ let projectDir = process.cwd();
181
+ let didBootstrap = false;
182
+ if (config.frontend || config.backend) {
183
+ const shouldBootstrap = await (0, workflow_prompts_1.confirmPrompt)("Bootstrap project now?", true);
184
+ if (shouldBootstrap) {
185
+ console.log(chalk_1.default.cyan("\n Bootstrapping with Better-T-Stack...\n"));
186
+ try {
187
+ const result = await (0, better_t_stack_cli_1.runBetterTStackCLI)({
188
+ projectName: config.projectName,
189
+ frontend: config.frontend || "next",
190
+ backend: config.backend || "hono",
191
+ database: config.database || "sqlite",
192
+ noAuth: !config.auth,
193
+ // Default values for required fields that might be missing from simple config
194
+ orm: "drizzle",
195
+ packageManager: "npm",
196
+ runtime: "node",
197
+ noInstall: false,
198
+ noGit: false,
199
+ }, process.cwd());
200
+ if (result.success) {
201
+ console.log(chalk_1.default.green(`\nāœ“ ${result.message}\n`));
202
+ didBootstrap = true;
203
+ // Update project directory if a new directory was created
204
+ if (result.projectPath) {
205
+ projectDir = (0, path_1.resolve)(process.cwd(), result.projectPath);
206
+ console.log(chalk_1.default.cyan(` šŸ“‚ Switching to project directory: ${projectDir}\n`));
207
+ process.chdir(projectDir);
208
+ config_1.configManager.setWorkingDirectory(projectDir);
209
+ state.projectDir = projectDir;
210
+ }
211
+ }
212
+ else {
213
+ console.log(chalk_1.default.red(`\nāœ— Bootstrap failed: ${result.message}\n`));
214
+ console.log(chalk_1.default.yellow("You can try running 'task-o-matic init bootstrap' manually later.\n"));
215
+ }
216
+ }
217
+ catch (error) {
218
+ console.log(chalk_1.default.red(`\nāœ— Bootstrap failed: ${error}\n`));
219
+ }
220
+ }
221
+ }
222
+ // Initialize task-o-matic in the correct directory (projectDir)
223
+ console.log(chalk_1.default.cyan("\n Initializing task-o-matic...\n"));
224
+ // Re-check task-o-matic dir in the new location
225
+ const newTaskOMaticDir = (0, path_1.join)(projectDir, ".task-o-matic");
226
+ if (!(0, fs_1.existsSync)(newTaskOMaticDir)) {
227
+ (0, fs_1.mkdirSync)(newTaskOMaticDir, { recursive: true });
180
228
  ["tasks", "prd", "logs"].forEach((dir) => {
181
- (0, fs_1.mkdirSync)((0, path_1.join)(taskOMaticDir, dir), { recursive: true });
229
+ (0, fs_1.mkdirSync)((0, path_1.join)(newTaskOMaticDir, dir), { recursive: true });
182
230
  });
183
231
  }
232
+ // Handle .env configuration
233
+ const envPath = (0, path_1.join)(projectDir, ".env");
234
+ let envContent = "";
235
+ if ((0, fs_1.existsSync)(envPath)) {
236
+ envContent = (0, fs_1.readFileSync)(envPath, "utf-8");
237
+ }
238
+ // Check if we need to ask for API key
239
+ const providerKeyName = config.aiProvider === "openai"
240
+ ? "OPENAI_API_KEY"
241
+ : config.aiProvider === "anthropic"
242
+ ? "ANTHROPIC_API_KEY"
243
+ : config.aiProvider === "openrouter"
244
+ ? "OPENROUTER_API_KEY"
245
+ : "AI_API_KEY";
246
+ // Check if key exists in current env OR in the target .env file
247
+ const hasKeyInEnv = process.env[providerKeyName] || envContent.includes(providerKeyName);
248
+ if (!hasKeyInEnv) {
249
+ console.log(chalk_1.default.yellow(`\nāš ļø No API key found for ${config.aiProvider}`));
250
+ const apiKey = await (0, workflow_prompts_1.textInputPrompt)(`Enter your ${config.aiProvider} API Key:`);
251
+ // Prepare .env content
252
+ let newEnvContent = envContent;
253
+ if (newEnvContent && !newEnvContent.endsWith("\n")) {
254
+ newEnvContent += "\n";
255
+ }
256
+ if (!newEnvContent.includes("AI_PROVIDER=")) {
257
+ newEnvContent += `AI_PROVIDER=${config.aiProvider}\n`;
258
+ }
259
+ if (!newEnvContent.includes("AI_MODEL=")) {
260
+ newEnvContent += `AI_MODEL=${config.aiModel}\n`;
261
+ }
262
+ if (!newEnvContent.includes(`${providerKeyName}=`)) {
263
+ newEnvContent += `${providerKeyName}=${apiKey}\n`;
264
+ }
265
+ (0, fs_1.writeFileSync)(envPath, newEnvContent);
266
+ console.log(chalk_1.default.green(`āœ“ Saved configuration to ${envPath}`));
267
+ // Update process.env for immediate use in this session
268
+ process.env[providerKeyName] = apiKey;
269
+ process.env.AI_PROVIDER = config.aiProvider;
270
+ process.env.AI_MODEL = config.aiModel;
271
+ }
184
272
  // Save configuration
185
273
  config_1.configManager.setConfig({
186
274
  ai: {
@@ -188,30 +276,11 @@ async function stepInitialize(state, aiOptions, streamingOptions) {
188
276
  model: config.aiModel,
189
277
  maxTokens: 32768,
190
278
  temperature: 0.5,
279
+ apiKey: process.env[providerKeyName], // Ensure key is in config if needed
191
280
  },
192
281
  });
193
282
  config_1.configManager.save();
194
283
  console.log(chalk_1.default.green("āœ“ Project initialized"));
195
- // Bootstrap if configured
196
- if (config.frontend || config.backend) {
197
- const shouldBootstrap = await (0, workflow_prompts_1.confirmPrompt)("Bootstrap project now?", true);
198
- if (shouldBootstrap) {
199
- console.log(chalk_1.default.cyan("\n Bootstrapping with Better-T-Stack...\n"));
200
- console.log(chalk_1.default.gray(" (This may take a few minutes)\n"));
201
- // Note: Actual bootstrap would call Better-T-Stack CLI
202
- // For now, we'll just note the configuration
203
- const btsConfig = {
204
- projectName: config.projectName,
205
- frontend: config.frontend,
206
- backend: config.backend,
207
- database: config.database,
208
- auth: config.auth,
209
- };
210
- (0, fs_1.writeFileSync)((0, path_1.join)(taskOMaticDir, "bts-config.json"), JSON.stringify(btsConfig, null, 2));
211
- console.log(chalk_1.default.yellow("ℹ Bootstrap configuration saved"));
212
- console.log(chalk_1.default.gray(" Run 'task-o-matic init bootstrap' to complete setup\n"));
213
- }
214
- }
215
284
  state.initialized = true;
216
285
  state.projectName = config.projectName;
217
286
  state.aiConfig = {
@@ -31,5 +31,6 @@ export interface InitOptions {
31
31
  export declare function runBetterTStackCLI(options: InitOptions, workingDirectory?: string): Promise<{
32
32
  success: boolean;
33
33
  message: string;
34
+ projectPath?: string;
34
35
  }>;
35
36
  //# sourceMappingURL=better-t-stack-cli.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"better-t-stack-cli.d.ts","sourceRoot":"","sources":["../../src/lib/better-t-stack-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKrC,qBAAa,mBAAmB;IACxB,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAmDF,OAAO,CAAC,kBAAkB;YAsBZ,aAAa;CAqB5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAkChD"}
1
+ {"version":3,"file":"better-t-stack-cli.d.ts","sourceRoot":"","sources":["../../src/lib/better-t-stack-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKrC,qBAAa,mBAAmB;IACxB,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAqDF,OAAO,CAAC,kBAAkB;YAyBZ,aAAa;CAqB5B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,WAAW,EACpB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsCtE"}
@@ -68,7 +68,9 @@ class BetterTStackService {
68
68
  git: config.git,
69
69
  install: config.install,
70
70
  addons: config.addons,
71
- examples: config.examples,
71
+ examples: config.examples && config.examples.length > 0
72
+ ? config.examples
73
+ : undefined,
72
74
  disableAnalytics: true,
73
75
  };
74
76
  }
@@ -114,5 +116,9 @@ async function runBetterTStackCLI(options, workingDirectory) {
114
116
  examples: options.examples || [],
115
117
  };
116
118
  const result = await btsService.createProject(options.projectName || options.name || "", btsConfig, workingDirectory);
117
- return { success: result.success, message: result.message };
119
+ return {
120
+ success: result.success,
121
+ message: result.message,
122
+ projectPath: result.projectPath,
123
+ };
118
124
  }
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-o-matic",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "AI-powered task management CLI",
5
5
  "keywords": [
6
6
  "task-management",
@@ -50,8 +50,8 @@
50
50
  "start": "node dist/cli/bin.js",
51
51
  "check-types": "tsc --noEmit --skipLibCheck",
52
52
  "test": "mocha -r tsx/cjs src/test/**/*.test.ts",
53
- "prepare": "npm run build",
54
- "prepublishOnly": "bun run build && bun test"
53
+ "prepare": "npm run build && chmod +x dist/cli/bin.js",
54
+ "prepublishOnly": "bun run build && chmod +x dist/cli/bin.js && bun test"
55
55
  },
56
56
  "dependencies": {
57
57
  "@ai-sdk/anthropic": "^2.0.44",