@eugene218/noxdev 1.0.1 → 1.0.2

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.
Files changed (2) hide show
  1. package/dist/index.js +87 -27
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2500,10 +2500,44 @@ async function runRemove(projectId, force) {
2500
2500
  // src/commands/setup.ts
2501
2501
  import chalk12 from "chalk";
2502
2502
  import { execSync as execSync8, spawnSync } from "child_process";
2503
- import fs from "fs";
2503
+ import fs2 from "fs";
2504
2504
  import os from "os";
2505
- import path2 from "path";
2505
+ import path3 from "path";
2506
2506
  import { createInterface as createInterface2 } from "readline";
2507
+
2508
+ // src/lib/paths.ts
2509
+ import fs from "fs";
2510
+ import path2 from "path";
2511
+ import { fileURLToPath as fileURLToPath2 } from "url";
2512
+ var cachedRoot = null;
2513
+ function findCliRoot() {
2514
+ if (cachedRoot) return cachedRoot;
2515
+ const here = path2.dirname(fileURLToPath2(import.meta.url));
2516
+ let dir = here;
2517
+ while (dir !== "/" && dir !== ".") {
2518
+ const pkgPath = path2.join(dir, "package.json");
2519
+ if (fs.existsSync(pkgPath)) {
2520
+ try {
2521
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
2522
+ if (pkg.name === "@eugene218/noxdev" || pkg.name === "noxdev") {
2523
+ cachedRoot = dir;
2524
+ return dir;
2525
+ }
2526
+ } catch {
2527
+ }
2528
+ }
2529
+ dir = path2.dirname(dir);
2530
+ }
2531
+ throw new Error(`Could not find noxdev CLI package root walking up from ${here}`);
2532
+ }
2533
+ function dockerfilePath() {
2534
+ return path2.join(findCliRoot(), "docker", "Dockerfile");
2535
+ }
2536
+ function demoTasksPath() {
2537
+ return path2.join(findCliRoot(), "templates", "demo-tasks.md");
2538
+ }
2539
+
2540
+ // src/commands/setup.ts
2507
2541
  function registerSetup(program2) {
2508
2542
  program2.command("setup").description("Build Docker image and prepare noxdev for first use").option("--rebuild", "Force rebuild of Docker image even if it exists").option("--yes", "Skip confirmation prompts (for scripting)").action(async (opts) => {
2509
2543
  try {
@@ -2523,10 +2557,20 @@ async function runSetup(opts = {}) {
2523
2557
  console.log(chalk12.cyan("Checking prerequisites...\n"));
2524
2558
  const nodeVersion = process.versions.node;
2525
2559
  const major = parseInt(nodeVersion.split(".")[0]);
2526
- if (major < 20 || major >= 23) {
2527
- console.error(chalk12.red(`\u2716 Node ${nodeVersion} not supported. Install Node 20 or 22 LTS.`));
2560
+ if (major < 20) {
2561
+ console.error(chalk12.red(`\u2716 Node ${process.versions.node} is too old. noxdev requires Node 20 or newer.`));
2562
+ process.exit(1);
2563
+ }
2564
+ if (major >= 25) {
2565
+ console.error(chalk12.red(`\u2716 Node ${process.versions.node} is not supported.`));
2566
+ console.error(chalk12.gray(" noxdev depends on better-sqlite3 which lacks prebuilt binaries for Node 25+."));
2567
+ console.error(chalk12.gray(" Install Node 22 LTS: brew install node@22 (macOS) or nvm install 22"));
2528
2568
  process.exit(1);
2529
2569
  }
2570
+ if (major > 22) {
2571
+ console.warn(chalk12.yellow(`\u26A0 Node ${process.versions.node} is untested (supported: 20.x, 22.x LTS).`));
2572
+ console.warn(chalk12.gray(" Continuing anyway. Report issues at github.com/eugeneorlov/noxdev/issues"));
2573
+ }
2530
2574
  console.log(chalk12.green(`\u2713 Node ${nodeVersion} (supported)`));
2531
2575
  try {
2532
2576
  execSync8("docker --version", { stdio: "pipe" });
@@ -2577,10 +2621,9 @@ async function runSetup(opts = {}) {
2577
2621
  process.exit(0);
2578
2622
  }
2579
2623
  }
2580
- const cliRoot = path2.resolve(path2.dirname(new URL(import.meta.url).pathname), "..", "..");
2581
- const dockerfilePath = path2.join(cliRoot, "docker", "Dockerfile");
2582
- if (!fs.existsSync(dockerfilePath)) {
2583
- console.error(chalk12.red("\u2716 Dockerfile not found at " + dockerfilePath));
2624
+ const dockerfileLocation = dockerfilePath();
2625
+ if (!fs2.existsSync(dockerfileLocation)) {
2626
+ console.error(chalk12.red("\u2716 Dockerfile not found at " + dockerfileLocation));
2584
2627
  console.error(chalk12.gray(" This is a noxdev install bug. Reinstall with:"));
2585
2628
  console.error(chalk12.gray(" npm install -g @eugene218/noxdev"));
2586
2629
  process.exit(1);
@@ -2595,7 +2638,7 @@ async function runSetup(opts = {}) {
2595
2638
  if (imageExists && !opts.rebuild) {
2596
2639
  console.log(chalk12.green("\n\u2713 Docker image already exists (use --rebuild to force)"));
2597
2640
  } else {
2598
- const dockerfileDir = path2.dirname(dockerfilePath);
2641
+ const dockerfileDir = path3.dirname(dockerfileLocation);
2599
2642
  console.log(chalk12.cyan("\nBuilding noxdev-runner image (this takes 3-5 minutes)...\n"));
2600
2643
  const result = spawnSync("docker", ["build", "-t", "noxdev-runner:latest", dockerfileDir], {
2601
2644
  stdio: "inherit"
@@ -2640,9 +2683,9 @@ async function runSetup(opts = {}) {
2640
2683
  console.log(chalk12.gray(" Install with: brew install age"));
2641
2684
  }
2642
2685
  }
2643
- const noxdevDir = path2.join(os.homedir(), ".noxdev");
2644
- if (!fs.existsSync(noxdevDir)) {
2645
- fs.mkdirSync(noxdevDir, { recursive: true });
2686
+ const noxdevDir = path3.join(os.homedir(), ".noxdev");
2687
+ if (!fs2.existsSync(noxdevDir)) {
2688
+ fs2.mkdirSync(noxdevDir, { recursive: true });
2646
2689
  console.log(chalk12.green("\n\u2713 Created ~/.noxdev/"));
2647
2690
  } else {
2648
2691
  console.log(chalk12.green("\n\u2713 ~/.noxdev/ already exists"));
@@ -2667,6 +2710,19 @@ import { join as join10 } from "path";
2667
2710
  import { homedir as homedir8, tmpdir as tmpdir2 } from "os";
2668
2711
  import chalk13 from "chalk";
2669
2712
  import ora2 from "ora";
2713
+ function dumpErr(err) {
2714
+ if (err && typeof err === "object") {
2715
+ const e = err;
2716
+ if (e.stderr?.length) {
2717
+ console.error(chalk13.gray(" \u2500 stderr \u2500"));
2718
+ console.error(chalk13.gray(" " + e.stderr.toString().trim().replace(/\n/g, "\n ")));
2719
+ }
2720
+ if (e.stdout?.length) {
2721
+ console.error(chalk13.gray(" \u2500 stdout \u2500"));
2722
+ console.error(chalk13.gray(" " + e.stdout.toString().trim().replace(/\n/g, "\n ")));
2723
+ }
2724
+ }
2725
+ }
2670
2726
  function registerDemo(program2) {
2671
2727
  program2.command("demo").description("Scaffold a fresh Vite + React + TypeScript project and run noxdev demo tasks").option("--fresh", "Clean up any existing noxdev-demo project first").action(async (opts) => {
2672
2728
  try {
@@ -2682,7 +2738,7 @@ function registerDemo(program2) {
2682
2738
  });
2683
2739
  }
2684
2740
  async function runDemo(opts = {}) {
2685
- console.log(chalk13.bold("\n\u{1F3AD} noxdev demo\n"));
2741
+ console.log(chalk13.bold("\n\u{1F989} noxdev demo\n"));
2686
2742
  const projectName = "noxdev-demo";
2687
2743
  const tempDir = join10(tmpdir2(), projectName);
2688
2744
  const worktreePath = join10(homedir8(), "worktrees", projectName);
@@ -2739,24 +2795,26 @@ async function runDemo(opts = {}) {
2739
2795
  try {
2740
2796
  execSync9(`npm create vite@latest ${projectName} -- --template react-ts`, {
2741
2797
  cwd: tmpdir2(),
2742
- stdio: "pipe"
2798
+ stdio: ["pipe", "pipe", "pipe"]
2743
2799
  });
2744
2800
  spinner.succeed("Vite project scaffolded");
2745
2801
  } catch (err) {
2746
2802
  spinner.fail("Failed to scaffold Vite project");
2803
+ dumpErr(err);
2747
2804
  throw err;
2748
2805
  }
2749
2806
  console.log(chalk13.bold("\nStep 3: Initializing git repository"));
2750
2807
  const gitSpinner = ora2("Setting up git...").start();
2751
2808
  try {
2752
- execSync9("git init", { cwd: tempDir, stdio: "pipe" });
2753
- execSync9('git config user.name "noxdev"', { cwd: tempDir, stdio: "pipe" });
2754
- execSync9('git config user.email "noxdev@demo"', { cwd: tempDir, stdio: "pipe" });
2755
- execSync9("git add .", { cwd: tempDir, stdio: "pipe" });
2756
- execSync9('git commit -m "Initial Vite scaffold"', { cwd: tempDir, stdio: "pipe" });
2809
+ execSync9("git init", { cwd: tempDir, stdio: ["pipe", "pipe", "pipe"] });
2810
+ execSync9('git config user.name "noxdev"', { cwd: tempDir, stdio: ["pipe", "pipe", "pipe"] });
2811
+ execSync9('git config user.email "noxdev@demo"', { cwd: tempDir, stdio: ["pipe", "pipe", "pipe"] });
2812
+ execSync9("git add .", { cwd: tempDir, stdio: ["pipe", "pipe", "pipe"] });
2813
+ execSync9('git commit -m "Initial Vite scaffold"', { cwd: tempDir, stdio: ["pipe", "pipe", "pipe"] });
2757
2814
  gitSpinner.succeed("Git repository initialized");
2758
2815
  } catch (err) {
2759
2816
  gitSpinner.fail("Failed to initialize git repository");
2817
+ dumpErr(err);
2760
2818
  throw err;
2761
2819
  }
2762
2820
  console.log(chalk13.bold("\nStep 4: Registering project with noxdev"));
@@ -2768,7 +2826,7 @@ async function runDemo(opts = {}) {
2768
2826
  }).trim();
2769
2827
  execSync9(`git worktree add -b ${branch} ${worktreePath} ${defaultBranch}`, {
2770
2828
  cwd: tempDir,
2771
- stdio: "pipe"
2829
+ stdio: ["pipe", "pipe", "pipe"]
2772
2830
  });
2773
2831
  const projectConfig = {
2774
2832
  project: projectName,
@@ -2807,31 +2865,32 @@ async function runDemo(opts = {}) {
2807
2865
  registerSpinner.succeed("Project registered with noxdev");
2808
2866
  } catch (err) {
2809
2867
  registerSpinner.fail("Failed to register project");
2868
+ dumpErr(err);
2810
2869
  throw err;
2811
2870
  }
2812
2871
  console.log(chalk13.bold("\nStep 5: Setting up demo tasks"));
2813
2872
  const tasksSpinner = ora2("Copying demo tasks template...").start();
2814
2873
  try {
2815
- const templatesDir = join10(import.meta.dirname, "../../../templates");
2816
- const demoTasksPath = join10(templatesDir, "demo-tasks.md");
2817
2874
  const targetTasksPath = join10(worktreePath, "TASKS.md");
2818
- copyFileSync2(demoTasksPath, targetTasksPath);
2875
+ copyFileSync2(demoTasksPath(), targetTasksPath);
2819
2876
  tasksSpinner.succeed("Demo tasks copied");
2820
2877
  } catch (err) {
2821
2878
  tasksSpinner.fail("Failed to copy demo tasks");
2879
+ dumpErr(err);
2822
2880
  throw err;
2823
2881
  }
2824
2882
  console.log(chalk13.bold("\nStep 6: Installing dependencies"));
2825
2883
  const depsSpinner = ora2("Installing dependencies with pnpm...").start();
2826
2884
  try {
2827
- execSync9("pnpm install", { cwd: worktreePath, stdio: "pipe" });
2885
+ execSync9("pnpm install", { cwd: worktreePath, stdio: ["pipe", "pipe", "pipe"] });
2828
2886
  depsSpinner.succeed("Dependencies installed");
2829
2887
  } catch (err) {
2830
2888
  depsSpinner.fail("Failed to install dependencies");
2889
+ dumpErr(err);
2831
2890
  throw err;
2832
2891
  }
2833
2892
  console.log(chalk13.bold("\nStep 7: Running noxdev demo tasks autonomously"));
2834
- console.log(chalk13.cyan("\u{1F916} Launching autonomous agent...\n"));
2893
+ console.log(chalk13.cyan("\u{1F989} Launching autonomous agent...\n"));
2835
2894
  try {
2836
2895
  const { runAllProjects: runAllProjects2 } = await Promise.resolve().then(() => (init_run(), run_exports));
2837
2896
  const projectRow = {
@@ -2844,6 +2903,7 @@ async function runDemo(opts = {}) {
2844
2903
  await runSingleProject(projectRow);
2845
2904
  } catch (err) {
2846
2905
  console.error(chalk13.red("Failed to run noxdev tasks:"), err instanceof Error ? err.message : String(err));
2906
+ dumpErr(err);
2847
2907
  throw err;
2848
2908
  }
2849
2909
  console.log(chalk13.bold("\n\u{1F389} Demo complete!"));
@@ -2900,8 +2960,8 @@ async function runSingleProject(project) {
2900
2960
  };
2901
2961
  await executeRun2(ctx);
2902
2962
  try {
2903
- execSync9("git add TASKS.md", { cwd: project.worktree_path, stdio: "pipe" });
2904
- execSync9('git commit -m "noxdev: update task statuses"', { cwd: project.worktree_path, stdio: "pipe" });
2963
+ execSync9("git add TASKS.md", { cwd: project.worktree_path, stdio: ["pipe", "pipe", "pipe"] });
2964
+ execSync9('git commit -m "noxdev: update task statuses"', { cwd: project.worktree_path, stdio: ["pipe", "pipe", "pipe"] });
2905
2965
  console.log(chalk13.gray(" \u2713 TASKS.md status updates committed"));
2906
2966
  } catch {
2907
2967
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eugene218/noxdev",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Autonomous overnight coding agent orchestrator — ship code while you sleep",
5
5
  "keywords": [
6
6
  "cli",