taskdex 0.1.0 → 0.1.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/README.md CHANGED
@@ -35,6 +35,7 @@ taskdex init
35
35
  ```
36
36
 
37
37
  This will clone the repo and immediately run interactive terminal setup.
38
+ Setup now defaults to `dev-client` runtime, can build the native app (`expo run:ios` / `expo run:android`), and then starts Expo in `--dev-client` mode.
38
39
 
39
40
  For an already-cloned repo:
40
41
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskdex",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Terminal-first installer and launcher for Taskdex mobile + bridge",
5
5
  "type": "module",
6
6
  "bin": {
@@ -134,6 +134,22 @@ function parseExpoMode(input) {
134
134
  return normalized;
135
135
  }
136
136
 
137
+ function parseRuntime(input) {
138
+ const normalized = input.trim().toLowerCase() || 'dev-client';
139
+ if (['dev-client', 'dev', 'devbuild', 'dev-build'].includes(normalized)) return 'dev-client';
140
+ if (['expo-go', 'go', 'expo'].includes(normalized)) return 'expo-go';
141
+ throw new Error('Runtime must be "dev-client" or "expo-go".');
142
+ }
143
+
144
+ function parseBuildPlatform(input) {
145
+ const fallback = process.platform === 'darwin' ? 'ios' : 'android';
146
+ const normalized = input.trim().toLowerCase() || fallback;
147
+ if (!['ios', 'android'].includes(normalized)) {
148
+ throw new Error('Build platform must be "ios" or "android".');
149
+ }
150
+ return normalized;
151
+ }
152
+
137
153
  function parseInstallChoice(input) {
138
154
  const normalized = input.trim().toLowerCase();
139
155
  if (!normalized || normalized === 'y' || normalized === 'yes') return true;
@@ -152,12 +168,27 @@ async function readSetupConfig() {
152
168
  const portInput = await rl.question('Bridge port [3001]: ');
153
169
  const apiKeyInput = await rl.question('Bridge API key [auto-generate]: ');
154
170
  const expoModeInput = await rl.question('Expo mode (lan/tunnel) [lan]: ');
171
+ const runtimeInput = await rl.question('App runtime (dev-client/expo-go) [dev-client]: ');
155
172
  const installInput = await rl.question('Install npm dependencies first? [Y/n]: ');
173
+ const runtime = parseRuntime(runtimeInput);
174
+ let buildDevClient = false;
175
+ let buildPlatform = process.platform === 'darwin' ? 'ios' : 'android';
176
+ if (runtime === 'dev-client') {
177
+ const buildInput = await rl.question('Build native development client now? [Y/n]: ');
178
+ buildDevClient = parseInstallChoice(buildInput);
179
+ if (buildDevClient) {
180
+ const platformInput = await rl.question(`Build platform (ios/android) [${buildPlatform}]: `);
181
+ buildPlatform = parseBuildPlatform(platformInput);
182
+ }
183
+ }
156
184
 
157
185
  return {
158
186
  port: parsePort((portInput || '3001').trim()),
159
187
  apiKey: apiKeyInput.trim() || crypto.randomBytes(24).toString('hex'),
160
188
  expoMode: parseExpoMode(expoModeInput),
189
+ runtime,
190
+ buildDevClient,
191
+ buildPlatform,
161
192
  installDeps: parseInstallChoice(installInput),
162
193
  };
163
194
  } finally {
@@ -172,7 +203,7 @@ async function runInteractiveSetup(rootDir) {
172
203
  throw new Error(`Invalid Taskdex repository at ${rootDir}`);
173
204
  }
174
205
 
175
- const { port, apiKey, expoMode, installDeps } = await readSetupConfig();
206
+ const { port, apiKey, expoMode, runtime, buildDevClient, buildPlatform, installDeps } = await readSetupConfig();
176
207
  const bridgeUrl = `ws://${getLocalIPv4()}:${port}`;
177
208
 
178
209
  console.log(`\nBridge URL: ${bridgeUrl}`);
@@ -182,6 +213,8 @@ async function runInteractiveSetup(rootDir) {
182
213
  if (installDeps) {
183
214
  console.log('Installing bridge dependencies...\n');
184
215
  await runCommand(npmCmd, ['install'], { cwd: bridgeDir });
216
+ // Keep older clones working where this dependency might be missing.
217
+ await runCommand(npmCmd, ['install', 'qrcode-terminal@^0.12.0'], { cwd: bridgeDir });
185
218
  console.log('\nInstalling mobile dependencies...\n');
186
219
  await runCommand(npmCmd, ['install'], { cwd: mobileDir });
187
220
  }
@@ -204,18 +237,32 @@ async function runInteractiveSetup(rootDir) {
204
237
 
205
238
  await wait(1200);
206
239
 
240
+ const expoEnv = {
241
+ ...process.env,
242
+ EXPO_PUBLIC_BRIDGE_URL: bridgeUrl,
243
+ EXPO_PUBLIC_BRIDGE_API_KEY: apiKey,
244
+ };
245
+
246
+ if (runtime === 'dev-client' && buildDevClient) {
247
+ console.log(`\nBuilding native dev client (${buildPlatform})...\n`);
248
+ await runCommand(npxCmd, ['expo', `run:${buildPlatform}`, '--no-bundler'], {
249
+ cwd: mobileDir,
250
+ env: expoEnv,
251
+ });
252
+ }
253
+
207
254
  console.log('\nStarting Expo. Scan the QR code to open the app.');
208
255
  console.log('Bridge URL and API key are prefilled from this terminal setup.\n');
256
+ if (runtime === 'dev-client' && !buildDevClient) {
257
+ console.log('If dev client is not installed yet, rerun setup and enable native build.\n');
258
+ }
259
+
260
+ const expoArgs = runtime === 'dev-client'
261
+ ? ['expo', 'start', '--dev-client', `--${expoMode}`]
262
+ : ['expo', 'start', `--${expoMode}`];
209
263
 
210
264
  try {
211
- await runCommand(npxCmd, ['expo', 'start', `--${expoMode}`], {
212
- cwd: mobileDir,
213
- env: {
214
- ...process.env,
215
- EXPO_PUBLIC_BRIDGE_URL: bridgeUrl,
216
- EXPO_PUBLIC_BRIDGE_API_KEY: apiKey,
217
- },
218
- });
265
+ await runCommand(npxCmd, expoArgs, { cwd: mobileDir, env: expoEnv });
219
266
  } finally {
220
267
  if (!bridgeProcess.killed) {
221
268
  bridgeProcess.kill('SIGTERM');