taskdex 0.1.4 → 0.1.5

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/README.md CHANGED
@@ -39,6 +39,10 @@ Setup now defaults to `dev-client` runtime, can build the native app (`expo run:
39
39
  For iOS builds, setup asks whether to run on a real iPhone or Simulator, and supports choosing a specific iPhone device name.
40
40
  When a `pnpm-lock.yaml` is present in `mobile`, the CLI installs mobile dependencies with pnpm automatically.
41
41
  Setup writes runtime bridge env values into `mobile/.env.local`, sets `CODEX_CWD` for bridge agent workspace, and can pass `OPENAI_API_KEY` if provided.
42
+ Setup also includes Convex mode selection:
43
+ - `new` runs `convex dev --once` automatically
44
+ - `existing` prompts for Convex env values and writes them
45
+ - `skip` leaves Convex untouched (bridge/local state still works, cloud persistence may be limited)
42
46
 
43
47
  For an already-cloned repo:
44
48
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskdex",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Terminal-first installer and launcher for Taskdex mobile + bridge",
5
5
  "type": "module",
6
6
  "bin": {
@@ -174,6 +174,14 @@ function parseInstallChoice(input) {
174
174
  throw new Error('Install choice must be Y or N.');
175
175
  }
176
176
 
177
+ function parseConvexMode(input) {
178
+ const normalized = input.trim().toLowerCase() || 'new';
179
+ if (['new', 'setup', 'create'].includes(normalized)) return 'new';
180
+ if (['existing', 'manual'].includes(normalized)) return 'existing';
181
+ if (['skip', 'none'].includes(normalized)) return 'skip';
182
+ throw new Error('Convex setup mode must be "new", "existing", or "skip".');
183
+ }
184
+
177
185
  function upsertEnvVars(envFilePath, values) {
178
186
  const keys = Object.keys(values);
179
187
  const original = existsSync(envFilePath) ? readFileSync(envFilePath, 'utf8') : '';
@@ -208,6 +216,16 @@ async function readSetupConfig() {
208
216
  const runtimeInput = await rl.question('App runtime (dev-client/expo-go) [dev-client]: ');
209
217
  const installInput = await rl.question('Install npm dependencies first? [Y/n]: ');
210
218
  const runtime = parseRuntime(runtimeInput);
219
+ const convexModeInput = await rl.question('Convex setup (new/existing/skip) [new]: ');
220
+ const convexMode = parseConvexMode(convexModeInput);
221
+ let convexUrlInput = '';
222
+ let convexDeploymentInput = '';
223
+ let convexSiteUrlInput = '';
224
+ if (convexMode === 'existing') {
225
+ convexUrlInput = (await rl.question('EXPO_PUBLIC_CONVEX_URL: ')).trim();
226
+ convexDeploymentInput = (await rl.question('CONVEX_DEPLOYMENT (optional): ')).trim();
227
+ convexSiteUrlInput = (await rl.question('EXPO_PUBLIC_CONVEX_SITE_URL (optional): ')).trim();
228
+ }
211
229
  let buildDevClient = false;
212
230
  let buildPlatform = process.platform === 'darwin' ? 'ios' : 'android';
213
231
  let iosTarget = 'iphone';
@@ -235,6 +253,10 @@ async function readSetupConfig() {
235
253
  apiKey: apiKeyInput.trim() || crypto.randomBytes(24).toString('hex'),
236
254
  expoMode: parseExpoMode(expoModeInput),
237
255
  runtime,
256
+ convexMode,
257
+ convexUrlInput,
258
+ convexDeploymentInput,
259
+ convexSiteUrlInput,
238
260
  buildDevClient,
239
261
  buildPlatform,
240
262
  iosTarget,
@@ -260,6 +282,10 @@ async function runInteractiveSetup(rootDir) {
260
282
  apiKey,
261
283
  expoMode,
262
284
  runtime,
285
+ convexMode,
286
+ convexUrlInput,
287
+ convexDeploymentInput,
288
+ convexSiteUrlInput,
263
289
  buildDevClient,
264
290
  buildPlatform,
265
291
  iosTarget,
@@ -275,14 +301,12 @@ async function runInteractiveSetup(rootDir) {
275
301
  throw new Error(`Workspace path does not exist: ${workspacePath}`);
276
302
  }
277
303
 
278
- upsertEnvVars(path.join(mobileDir, '.env.local'), {
279
- EXPO_PUBLIC_BRIDGE_URL: bridgeUrl,
280
- EXPO_PUBLIC_BRIDGE_API_KEY: apiKey,
281
- });
304
+ const envFilePath = path.join(mobileDir, '.env.local');
282
305
 
283
306
  console.log(`\nBridge URL: ${bridgeUrl}`);
284
307
  console.log(`Bridge API key: ${apiKey}`);
285
308
  console.log(`Agent workspace: ${workspacePath}`);
309
+ console.log(`Convex mode: ${convexMode}`);
286
310
  console.log(`Expo mode: ${expoMode}\n`);
287
311
 
288
312
  if (installDeps) {
@@ -294,6 +318,28 @@ async function runInteractiveSetup(rootDir) {
294
318
  await installMobileDependencies(mobileDir);
295
319
  }
296
320
 
321
+ if (convexMode === 'new') {
322
+ console.log('\nSetting up Convex deployment...\n');
323
+ await runCommand(npxCmd, ['-y', 'convex', 'dev', '--once'], { cwd: mobileDir });
324
+ }
325
+
326
+ if (convexMode === 'existing') {
327
+ if (!convexUrlInput) {
328
+ throw new Error('EXPO_PUBLIC_CONVEX_URL is required when Convex mode is "existing".');
329
+ }
330
+ const convexValues = {
331
+ EXPO_PUBLIC_CONVEX_URL: convexUrlInput,
332
+ ...(convexDeploymentInput ? { CONVEX_DEPLOYMENT: convexDeploymentInput } : {}),
333
+ ...(convexSiteUrlInput ? { EXPO_PUBLIC_CONVEX_SITE_URL: convexSiteUrlInput } : {}),
334
+ };
335
+ upsertEnvVars(envFilePath, convexValues);
336
+ }
337
+
338
+ upsertEnvVars(envFilePath, {
339
+ EXPO_PUBLIC_BRIDGE_URL: bridgeUrl,
340
+ EXPO_PUBLIC_BRIDGE_API_KEY: apiKey,
341
+ });
342
+
297
343
  console.log('\nStarting bridge server...\n');
298
344
  const bridgeProcess = spawn(npmCmd, ['run', 'dev'], {
299
345
  cwd: bridgeDir,