taskdex 0.1.3 → 0.1.4

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
@@ -38,6 +38,7 @@ This will clone the repo and immediately run interactive terminal setup.
38
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.
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
+ 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.
41
42
 
42
43
  For an already-cloned repo:
43
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taskdex",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Terminal-first installer and launcher for Taskdex mobile + bridge",
5
5
  "type": "module",
6
6
  "bin": {
@@ -2,7 +2,7 @@
2
2
 
3
3
  import crypto from 'node:crypto';
4
4
  import { spawn } from 'node:child_process';
5
- import { existsSync, readdirSync } from 'node:fs';
5
+ import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
6
6
  import os from 'node:os';
7
7
  import path from 'node:path';
8
8
  import process from 'node:process';
@@ -174,6 +174,26 @@ function parseInstallChoice(input) {
174
174
  throw new Error('Install choice must be Y or N.');
175
175
  }
176
176
 
177
+ function upsertEnvVars(envFilePath, values) {
178
+ const keys = Object.keys(values);
179
+ const original = existsSync(envFilePath) ? readFileSync(envFilePath, 'utf8') : '';
180
+ const lines = original ? original.split(/\r?\n/) : [];
181
+ const seen = new Set();
182
+ const updated = lines.map((line) => {
183
+ const match = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/);
184
+ if (!match) return line;
185
+ const key = match[1];
186
+ if (!keys.includes(key)) return line;
187
+ seen.add(key);
188
+ return `${key}=${values[key]}`;
189
+ });
190
+ for (const key of keys) {
191
+ if (!seen.has(key)) updated.push(`${key}=${values[key]}`);
192
+ }
193
+ const nextContent = `${updated.filter((line) => line !== '').join('\n')}\n`;
194
+ writeFileSync(envFilePath, nextContent, 'utf8');
195
+ }
196
+
177
197
  function wait(ms) {
178
198
  return new Promise((resolve) => setTimeout(resolve, ms));
179
199
  }
@@ -192,6 +212,8 @@ async function readSetupConfig() {
192
212
  let buildPlatform = process.platform === 'darwin' ? 'ios' : 'android';
193
213
  let iosTarget = 'iphone';
194
214
  let iosDeviceName = '';
215
+ const openAiApiKey = (await rl.question('OPENAI_API_KEY (optional, Enter to use current shell/Codex login): ')).trim();
216
+ const workspaceInput = (await rl.question('Agent workspace path [repo root]: ')).trim();
195
217
  if (runtime === 'dev-client') {
196
218
  const buildInput = await rl.question('Build native development client now? [Y/n]: ');
197
219
  buildDevClient = parseInstallChoice(buildInput);
@@ -217,6 +239,8 @@ async function readSetupConfig() {
217
239
  buildPlatform,
218
240
  iosTarget,
219
241
  iosDeviceName,
242
+ openAiApiKey,
243
+ workspaceInput,
220
244
  installDeps: parseInstallChoice(installInput),
221
245
  };
222
246
  } finally {
@@ -240,12 +264,25 @@ async function runInteractiveSetup(rootDir) {
240
264
  buildPlatform,
241
265
  iosTarget,
242
266
  iosDeviceName,
267
+ openAiApiKey,
268
+ workspaceInput,
243
269
  installDeps,
244
270
  } = await readSetupConfig();
245
271
  const bridgeUrl = `ws://${getLocalIPv4()}:${port}`;
272
+ const workspacePath = workspaceInput ? path.resolve(workspaceInput) : rootDir;
273
+
274
+ if (!existsSync(workspacePath)) {
275
+ throw new Error(`Workspace path does not exist: ${workspacePath}`);
276
+ }
277
+
278
+ upsertEnvVars(path.join(mobileDir, '.env.local'), {
279
+ EXPO_PUBLIC_BRIDGE_URL: bridgeUrl,
280
+ EXPO_PUBLIC_BRIDGE_API_KEY: apiKey,
281
+ });
246
282
 
247
283
  console.log(`\nBridge URL: ${bridgeUrl}`);
248
284
  console.log(`Bridge API key: ${apiKey}`);
285
+ console.log(`Agent workspace: ${workspacePath}`);
249
286
  console.log(`Expo mode: ${expoMode}\n`);
250
287
 
251
288
  if (installDeps) {
@@ -265,6 +302,8 @@ async function runInteractiveSetup(rootDir) {
265
302
  ...process.env,
266
303
  PORT: String(port),
267
304
  API_KEY: apiKey,
305
+ CODEX_CWD: workspacePath,
306
+ ...(openAiApiKey ? { OPENAI_API_KEY: openAiApiKey } : {}),
268
307
  },
269
308
  });
270
309