nextdesk 0.1.4 → 0.1.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.
Binary file
@@ -45,17 +45,17 @@ async function build(options) {
45
45
  copySpinner.fail(`Failed to copy Next.js build: ${err.message}`);
46
46
  process.exit(1);
47
47
  }
48
- // Step 3: Copy runtime binary
49
- const runtimeSpinner = (0, ora_1.default)('Copying runtime...').start();
48
+ // Step 3: Get runtime binary (downloads from GitHub if not available locally)
49
+ const runtimeSpinner = (0, ora_1.default)('Getting runtime...').start();
50
50
  try {
51
- const runtime = (0, nextjs_1.getRuntimeBinary)();
52
- const outputBinary = path_1.default.join(outputDir, appName);
51
+ const runtime = await (0, nextjs_1.getRuntimeBinaryAsync)();
52
+ const outputBinary = path_1.default.join(outputDir, appName + (process.platform === 'win32' ? '.exe' : ''));
53
53
  fs_1.default.copyFileSync(runtime, outputBinary);
54
54
  fs_1.default.chmodSync(outputBinary, 0o755);
55
- runtimeSpinner.succeed('Runtime copied');
55
+ runtimeSpinner.succeed('Runtime ready');
56
56
  }
57
57
  catch (err) {
58
- runtimeSpinner.fail(`Failed to copy runtime: ${err.message}`);
58
+ runtimeSpinner.fail(`Failed to get runtime: ${err.message}`);
59
59
  process.exit(1);
60
60
  }
61
61
  // Step 4: Create run script
@@ -35,14 +35,13 @@ async function init(options) {
35
35
  }
36
36
  // Try to find and copy runtime binary - look from various common locations
37
37
  const possiblePaths = [
38
+ // From npm package (when installed via npx)
39
+ path_1.default.join(cwd, 'node_modules/nextdesk/bin/nextdesk-runtime'),
40
+ // Development paths
38
41
  path_1.default.join(cwd, '../mydesk-poc/target/release/mydesk-poc'),
39
42
  path_1.default.join(process.env.HOME || '', 'Projects/Personal/mydesk-poc/target/release/mydesk-poc'),
40
43
  '/home/yoni/Desktop/Projects/Personal/mydesk-poc/target/release/mydesk-poc',
41
44
  ];
42
- // Also check if running from node_modules (npx)
43
- if (process.env.npm_package_name?.startsWith('nextdesk')) {
44
- possiblePaths.unshift(path_1.default.join(cwd, '../../mydesk-poc/target/release/mydesk-poc'));
45
- }
46
45
  let runtimeCopied = false;
47
46
  for (const src of possiblePaths) {
48
47
  if (fs_1.default.existsSync(src)) {
@@ -55,7 +54,7 @@ async function init(options) {
55
54
  }
56
55
  }
57
56
  if (!runtimeCopied) {
58
- spinner.warn('Runtime binary not found');
57
+ spinner.warn('Runtime binary not found - install nextdesk globally or from source');
59
58
  }
60
59
  // Create nextdesk.config.js
61
60
  const configContent = `export default {
@@ -6,11 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isNextJsProject = isNextJsProject;
7
7
  exports.getPackageJson = getPackageJson;
8
8
  exports.getAppName = getAppName;
9
+ exports.downloadRuntimeBinary = downloadRuntimeBinary;
9
10
  exports.waitForServer = waitForServer;
10
11
  exports.getRuntimeBinary = getRuntimeBinary;
12
+ exports.getRuntimeBinaryAsync = getRuntimeBinaryAsync;
11
13
  const fs_1 = __importDefault(require("fs"));
12
14
  const path_1 = __importDefault(require("path"));
13
15
  const http_1 = __importDefault(require("http"));
16
+ const https_1 = __importDefault(require("https"));
17
+ const GITHUB_REPO = 'yoniwitz/nextdesk';
14
18
  function isNextJsProject(cwd = process.cwd()) {
15
19
  return (fs_1.default.existsSync(path_1.default.join(cwd, 'next.config.js')) ||
16
20
  fs_1.default.existsSync(path_1.default.join(cwd, 'next.config.ts')) ||
@@ -26,6 +30,89 @@ function getAppName(cwd = process.cwd()) {
26
30
  const pkg = getPackageJson(cwd);
27
31
  return pkg?.name ?? path_1.default.basename(cwd);
28
32
  }
33
+ function getPlatformBinaryName() {
34
+ const platform = process.platform;
35
+ const arch = process.arch;
36
+ if (platform === 'linux')
37
+ return 'x86_64-unknown-linux-gnu';
38
+ if (platform === 'darwin') {
39
+ return arch === 'arm64' ? 'aarch64-apple-darwin' : 'x86_64-apple-darwin';
40
+ }
41
+ if (platform === 'win32')
42
+ return 'x86_64-pc-windows-msvc';
43
+ throw new Error(`Unsupported platform: ${platform}`);
44
+ }
45
+ function getExtension() {
46
+ return process.platform === 'win32' ? '.exe' : '';
47
+ }
48
+ async function downloadFile(url, destPath) {
49
+ return new Promise((resolve, reject) => {
50
+ const protocol = url.startsWith('https') ? https_1.default : http_1.default;
51
+ const request = protocol.get(url, (response) => {
52
+ if (response.statusCode === 302 || response.statusCode === 301) {
53
+ const redirectUrl = response.headers.location;
54
+ if (redirectUrl) {
55
+ downloadFile(redirectUrl, destPath).then(resolve).catch(reject);
56
+ return;
57
+ }
58
+ }
59
+ if (response.statusCode !== 200) {
60
+ reject(new Error(`Failed to download: ${response.statusCode}`));
61
+ return;
62
+ }
63
+ const file = fs_1.default.createWriteStream(destPath);
64
+ response.pipe(file);
65
+ file.on('finish', () => {
66
+ file.close();
67
+ resolve();
68
+ });
69
+ });
70
+ request.on('error', reject);
71
+ });
72
+ }
73
+ async function getLatestRelease() {
74
+ return new Promise((resolve, reject) => {
75
+ https_1.default.get(`https://api.github.com/repos/${GITHUB_REPO}/releases/latest`, {
76
+ headers: { 'User-Agent': 'nextdesk' }
77
+ }, (res) => {
78
+ let data = '';
79
+ res.on('data', chunk => data += chunk);
80
+ res.on('end', () => {
81
+ try {
82
+ resolve(JSON.parse(data));
83
+ }
84
+ catch (e) {
85
+ reject(e);
86
+ }
87
+ });
88
+ }).on('error', reject);
89
+ });
90
+ }
91
+ async function downloadRuntimeBinary(cwd) {
92
+ const targetDir = path_1.default.join(cwd, '.nextdesk', 'bin');
93
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
94
+ const binaryName = `mydesk-poc${getExtension()}`;
95
+ const targetPath = path_1.default.join(targetDir, `nextdesk-runtime${getExtension()}`);
96
+ if (fs_1.default.existsSync(targetPath)) {
97
+ return targetPath;
98
+ }
99
+ console.log('Downloading NextDesk runtime...');
100
+ try {
101
+ const release = await getLatestRelease();
102
+ const platformTarget = getPlatformBinaryName();
103
+ const asset = release.assets.find(a => a.name.includes(platformTarget));
104
+ if (!asset) {
105
+ throw new Error(`No binary available for ${platformTarget}. Please build from source.`);
106
+ }
107
+ await downloadFile(asset.browser_download_url, targetPath);
108
+ fs_1.default.chmodSync(targetPath, 0o755);
109
+ console.log('Runtime downloaded successfully!');
110
+ return targetPath;
111
+ }
112
+ catch (err) {
113
+ throw new Error(`Failed to download runtime: ${err.message}`);
114
+ }
115
+ }
29
116
  function waitForServer(url, timeout = 60000) {
30
117
  return new Promise((resolve, reject) => {
31
118
  const start = Date.now();
@@ -51,21 +138,33 @@ function waitForServer(url, timeout = 60000) {
51
138
  }
52
139
  function getRuntimeBinary() {
53
140
  const cwd = process.cwd();
54
- // Priority 1: Check in project's .nextdesk/bin/ (after init)
55
141
  const localBinary = path_1.default.join(cwd, '.nextdesk/bin/nextdesk-runtime');
56
142
  if (fs_1.default.existsSync(localBinary))
57
143
  return localBinary;
58
- // Priority 2: Check in node_modules/.nextdesk/bin/
59
144
  const nodeModulesBinary = path_1.default.join(cwd, 'node_modules/.nextdesk/bin/nextdesk-runtime');
60
145
  if (fs_1.default.existsSync(nodeModulesBinary))
61
146
  return nodeModulesBinary;
62
- // Priority 3: Check parent's mydesk-poc (development)
63
147
  const devBinary = path_1.default.join(cwd, '../mydesk-poc/target/release/mydesk-poc');
64
148
  if (fs_1.default.existsSync(devBinary))
65
149
  return devBinary;
66
- // Priority 4: Check hardcoded path from home
67
150
  const homeBinary = path_1.default.join(process.env.HOME || '', 'Projects/Personal/mydesk-poc/target/release/mydesk-poc');
68
151
  if (fs_1.default.existsSync(homeBinary))
69
152
  return homeBinary;
70
153
  throw new Error('NextDesk runtime not found. Run `npx nextdesk init` to set it up.');
71
154
  }
155
+ async function getRuntimeBinaryAsync() {
156
+ const cwd = process.cwd();
157
+ const localBinary = path_1.default.join(cwd, '.nextdesk/bin/nextdesk-runtime');
158
+ if (fs_1.default.existsSync(localBinary))
159
+ return localBinary;
160
+ const nodeModulesBinary = path_1.default.join(cwd, 'node_modules/.nextdesk/bin/nextdesk-runtime');
161
+ if (fs_1.default.existsSync(nodeModulesBinary))
162
+ return nodeModulesBinary;
163
+ const devBinary = path_1.default.join(cwd, '../mydesk-poc/target/release/mydesk-poc');
164
+ if (fs_1.default.existsSync(devBinary))
165
+ return devBinary;
166
+ const homeBinary = path_1.default.join(process.env.HOME || '', 'Projects/Personal/mydesk-poc/target/release/mydesk-poc');
167
+ if (fs_1.default.existsSync(homeBinary))
168
+ return homeBinary;
169
+ return downloadRuntimeBinary(cwd);
170
+ }
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "nextdesk",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Turn your Next.js app into a 5MB desktop app in 30 seconds",
5
5
  "bin": {
6
6
  "nextdesk": "./dist/index.js"
7
7
  },
8
+ "files": [
9
+ "dist/",
10
+ "bin/"
11
+ ],
8
12
  "scripts": {
9
13
  "build": "tsc && chmod +x dist/index.js",
10
14
  "dev": "tsc --watch",
@@ -1,127 +0,0 @@
1
- import chalk from 'chalk'
2
- import ora from 'ora'
3
- import execa from 'execa'
4
- import fs from 'fs'
5
- import path from 'path'
6
- import { isNextJsProject, getAppName, getRuntimeBinary } from '../utils/nextjs'
7
-
8
- interface BuildOptions {
9
- target: string
10
- }
11
-
12
- export async function build(options: BuildOptions) {
13
- const cwd = process.cwd()
14
-
15
- if (!isNextJsProject(cwd)) {
16
- console.error(chalk.red('✗ Not a Next.js project. Make sure next.config.js exists.'))
17
- process.exit(1)
18
- }
19
-
20
- const appName = getAppName(cwd)
21
- const outputDir = path.join(cwd, 'dist-desktop')
22
-
23
- console.log(chalk.bold(`\n📦 Building ${appName} for desktop...\n`))
24
-
25
- // Clean output directory
26
- if (fs.existsSync(outputDir)) {
27
- fs.rmSync(outputDir, { recursive: true })
28
- }
29
- fs.mkdirSync(outputDir, { recursive: true })
30
-
31
- // Step 1: Build Next.js app
32
- const nextSpinner = ora('Building Next.js app...').start()
33
- try {
34
- await execa('npm', ['run', 'build'], { cwd, stdio: 'pipe' })
35
- nextSpinner.succeed('Next.js app built')
36
- } catch (err: any) {
37
- nextSpinner.fail(`Next.js build failed: ${err.message}`)
38
- process.exit(1)
39
- }
40
-
41
- // Step 2: Copy Next.js output
42
- const copySpinner = ora('Copying Next.js build...').start()
43
- try {
44
- const nextOut = path.join(cwd, '.next')
45
- fs.cpSync(nextOut, path.join(outputDir, '.next'), { recursive: true })
46
- copySpinner.succeed('Next.js build copied')
47
- } catch (err: any) {
48
- copySpinner.fail(`Failed to copy Next.js build: ${err.message}`)
49
- process.exit(1)
50
- }
51
-
52
- // Step 3: Copy runtime binary
53
- const runtimeSpinner = ora('Copying runtime...').start()
54
- try {
55
- const runtime = getRuntimeBinary()
56
- const outputBinary = path.join(outputDir, appName)
57
- fs.copyFileSync(runtime, outputBinary)
58
- fs.chmodSync(outputBinary, 0o755)
59
- runtimeSpinner.succeed('Runtime copied')
60
- } catch (err: any) {
61
- runtimeSpinner.fail(`Failed to copy runtime: ${err.message}`)
62
- process.exit(1)
63
- }
64
-
65
- // Step 4: Create run script
66
- const scriptSpinner = ora('Creating run script...').start()
67
- try {
68
- const runScript = `#!/bin/bash
69
- APP_NAME="${appName}"
70
- PORT=3000
71
-
72
- # Start Next.js production server in background
73
- echo "Starting $APP_NAME server..."
74
- npm run start &
75
-
76
- # Wait for server to be ready
77
- sleep 3
78
-
79
- # Launch desktop app
80
- cd "$(dirname "$0")"
81
- "./$APP_NAME" "http://localhost:$PORT" "$APP_NAME"
82
- `
83
- fs.writeFileSync(path.join(outputDir, 'run.sh'), runScript)
84
- fs.chmodSync(path.join(outputDir, 'run.sh'), 0o755)
85
-
86
- // Also create Windows batch file
87
- const runBat = `@echo off
88
- set APP_NAME=${appName}
89
- echo Starting %APP_NAME% server...
90
- start /b npm run start
91
- timeout /t 3 /nobreak >nul
92
- "%~dp0%APP_NAME%.exe" "http://localhost:3000" "%APP_NAME%"
93
- `
94
- fs.writeFileSync(path.join(outputDir, 'run.bat'), runBat)
95
-
96
- scriptSpinner.succeed('Run scripts created')
97
- } catch (err: any) {
98
- scriptSpinner.fail(`Failed to create scripts: ${err.message}`)
99
- process.exit(1)
100
- }
101
-
102
- // Step 5: Copy package.json for npm install in output
103
- const depsSpinner = ora('Setting up dependencies...').start()
104
- try {
105
- const packageJson = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8'))
106
- fs.writeFileSync(path.join(outputDir, 'package.json'), JSON.stringify({
107
- name: appName,
108
- version: packageJson.version || '1.0.0',
109
- private: true,
110
- scripts: {
111
- start: 'next start'
112
- }
113
- }, null, 2))
114
- depsSpinner.succeed('Dependencies configured')
115
- } catch (err: any) {
116
- depsSpinner.fail(`Failed to setup dependencies: ${err.message}`)
117
- process.exit(1)
118
- }
119
-
120
- console.log(chalk.bold('\n✨ Build complete!\n'))
121
- console.log(chalk.gray(` Output: ${chalk.cyan(outputDir)}`))
122
- console.log(chalk.gray(` To run:`))
123
- console.log(chalk.cyan(` cd ${outputDir}`))
124
- console.log(chalk.cyan(` npm install`))
125
- console.log(chalk.cyan(` ./run.sh # Linux/Mac`))
126
- console.log(chalk.cyan(` run.bat # Windows\n`))
127
- }
@@ -1,94 +0,0 @@
1
- import chalk from 'chalk'
2
- import ora from 'ora'
3
- import execa from 'execa'
4
- import { isNextJsProject, waitForServer, getRuntimeBinary, getAppName } from '../utils/nextjs'
5
-
6
- interface DevOptions {
7
- port: string
8
- }
9
-
10
- export async function dev(options: DevOptions) {
11
- const port = options.port
12
- const url = `http://localhost:${port}`
13
- const cwd = process.cwd()
14
-
15
- // Check if Next.js project
16
- if (!isNextJsProject(cwd)) {
17
- console.error(chalk.red('✗ Not a Next.js project. Make sure next.config.js exists.'))
18
- process.exit(1)
19
- }
20
-
21
- const appName = getAppName(cwd)
22
- console.log(chalk.bold(`\n🚀 NextDesk — ${appName}\n`))
23
-
24
- // Start Next.js dev server
25
- const nextSpinner = ora('Starting Next.js dev server...').start()
26
-
27
- const nextProcess = execa('npm', ['run', 'dev'], {
28
- cwd,
29
- env: { ...process.env, PORT: port },
30
- stdio: ['ignore', 'pipe', 'pipe'],
31
- })
32
-
33
- nextProcess.stdout?.on('data', (data: Buffer) => {
34
- const line = data.toString()
35
- if (line.includes('Ready') || line.includes('ready')) {
36
- nextSpinner.succeed(`Next.js ready on ${chalk.cyan(url)}`)
37
- }
38
- })
39
-
40
- nextProcess.stderr?.on('data', (data: Buffer) => {
41
- const line = data.toString()
42
- if (line.toLowerCase().includes('error')) {
43
- console.error(chalk.red(line.trim()))
44
- }
45
- })
46
-
47
- // Wait for server to be ready
48
- try {
49
- await waitForServer(url)
50
- } catch (err) {
51
- nextSpinner.fail('Next.js dev server failed to start')
52
- nextProcess.kill()
53
- process.exit(1)
54
- }
55
-
56
- // Launch desktop window
57
- const windowSpinner = ora('Opening desktop window...').start()
58
-
59
- try {
60
- const runtime = getRuntimeBinary()
61
-
62
- const runtimeProcess = execa(runtime, [], {
63
- env: {
64
- ...process.env,
65
- MYDESK_URL: url,
66
- MYDESK_TITLE: appName,
67
- GDK_BACKEND: 'x11',
68
- WAYLAND_DISPLAY: '',
69
- },
70
- stdio: 'inherit',
71
- })
72
-
73
- windowSpinner.succeed(`${chalk.green('✨ Ready!')} Desktop window opened`)
74
- console.log(chalk.gray(`\n App: ${chalk.cyan(url)}`))
75
- console.log(chalk.gray(` Runtime: ${runtime}\n`))
76
-
77
- // Clean shutdown
78
- const cleanup = () => {
79
- nextProcess.kill()
80
- runtimeProcess.kill()
81
- process.exit(0)
82
- }
83
-
84
- process.on('SIGINT', cleanup)
85
- process.on('SIGTERM', cleanup)
86
-
87
- await runtimeProcess
88
-
89
- } catch (err: any) {
90
- windowSpinner.fail(`Failed to open desktop window: ${err.message}`)
91
- nextProcess.kill()
92
- process.exit(1)
93
- }
94
- }
@@ -1,113 +0,0 @@
1
- import chalk from 'chalk'
2
- import ora from 'ora'
3
- import execa from 'execa'
4
- import fs from 'fs'
5
- import path from 'path'
6
-
7
- interface InitOptions {
8
- name?: string
9
- }
10
-
11
- export async function init(options: InitOptions) {
12
- const cwd = process.cwd()
13
- const appName = options.name || path.basename(cwd)
14
-
15
- console.log(chalk.bold(`\n🚀 Initializing NextDesk project: ${appName}\n`))
16
-
17
- const spinner = ora('Setting up project...').start()
18
-
19
- try {
20
- // Check if Next.js project exists
21
- const hasNextConfig = fs.existsSync(path.join(cwd, 'next.config.js')) ||
22
- fs.existsSync(path.join(cwd, 'next.config.mjs')) ||
23
- fs.existsSync(path.join(cwd, 'next.config.ts'))
24
-
25
- if (!hasNextConfig) {
26
- spinner.info('No Next.js project found. Creating one...')
27
-
28
- // Create a basic Next.js app
29
- await execa('npx', ['create-next-app@latest', '.', '--typescript', '--tailwind', '--eslint', '--app', '--src-dir', '--no-import-alias'], {
30
- cwd,
31
- stdio: 'inherit'
32
- })
33
- }
34
-
35
- // Create .nextdesk directory with runtime
36
- const nextdeskDir = path.join(cwd, '.nextdesk')
37
- const binDir = path.join(nextdeskDir, 'bin')
38
- if (!fs.existsSync(binDir)) {
39
- fs.mkdirSync(binDir, { recursive: true })
40
- }
41
-
42
- // Try to find and copy runtime binary - look from various common locations
43
- const possiblePaths = [
44
- path.join(cwd, '../mydesk-poc/target/release/mydesk-poc'),
45
- path.join(process.env.HOME || '', 'Projects/Personal/mydesk-poc/target/release/mydesk-poc'),
46
- '/home/yoni/Desktop/Projects/Personal/mydesk-poc/target/release/mydesk-poc',
47
- ]
48
-
49
- // Also check if running from node_modules (npx)
50
- if (process.env.npm_package_name?.startsWith('nextdesk')) {
51
- possiblePaths.unshift(path.join(cwd, '../../mydesk-poc/target/release/mydesk-poc'))
52
- }
53
-
54
- let runtimeCopied = false
55
- for (const src of possiblePaths) {
56
- if (fs.existsSync(src)) {
57
- const dst = path.join(binDir, 'nextdesk-runtime')
58
- fs.copyFileSync(src, dst)
59
- fs.chmodSync(dst, 0o755)
60
- spinner.succeed('Runtime binary copied')
61
- runtimeCopied = true
62
- break
63
- }
64
- }
65
-
66
- if (!runtimeCopied) {
67
- spinner.warn('Runtime binary not found')
68
- }
69
-
70
- // Create nextdesk.config.js
71
- const configContent = `export default {
72
- name: "${appName}",
73
- version: "1.0.0",
74
- window: {
75
- width: 900,
76
- height: 640,
77
- title: "${appName}",
78
- },
79
- }
80
- `
81
- fs.writeFileSync(path.join(cwd, 'nextdesk.config.js'), configContent)
82
-
83
- // Update package.json scripts
84
- const packageJsonPath = path.join(cwd, 'package.json')
85
- if (fs.existsSync(packageJsonPath)) {
86
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
87
-
88
- if (!packageJson.scripts) {
89
- packageJson.scripts = {}
90
- }
91
-
92
- if (!packageJson.scripts['nextdesk:dev']) {
93
- packageJson.scripts['nextdesk:dev'] = 'npx nextdesk dev'
94
- }
95
- if (!packageJson.scripts['nextdesk:build']) {
96
- packageJson.scripts['nextdesk:build'] = 'npx nextdesk build'
97
- }
98
-
99
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n')
100
- }
101
-
102
- spinner.succeed('NextDesk initialized!')
103
-
104
- console.log(chalk.bold('\n✨ All set!\n'))
105
- console.log(chalk.gray(' Run these commands:'))
106
- console.log(chalk.cyan(' npm run nextdesk:dev # Start desktop app in dev mode'))
107
- console.log(chalk.cyan(' npm run nextdesk:build # Build desktop app for production\n'))
108
-
109
- } catch (err: any) {
110
- spinner.fail(`Initialization failed: ${err.message}`)
111
- process.exit(1)
112
- }
113
- }
package/src/index.ts DELETED
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import { program } from 'commander'
3
- import { dev } from './commands/dev'
4
- import { build } from './commands/build'
5
- import { init } from './commands/init'
6
-
7
- program
8
- .name('mydesk')
9
- .description('Turn your Next.js app into a desktop app in 30 seconds')
10
- .version('0.1.0')
11
-
12
- program
13
- .command('init')
14
- .description('Initialize MyDesk in your Next.js project')
15
- .option('-n, --name <name>', 'App name')
16
- .action(init)
17
-
18
- program
19
- .command('dev')
20
- .description('Start your Next.js app as a desktop app')
21
- .option('-p, --port <port>', 'Next.js dev server port', '3000')
22
- .action(dev)
23
-
24
- program
25
- .command('build')
26
- .description('Build your app for production')
27
- .option('-t, --target <target>', 'Target platform (windows, macos, linux)', process.platform)
28
- .action(build)
29
-
30
- program.parse()
@@ -1,70 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import http from 'http'
4
-
5
- export function isNextJsProject(cwd: string = process.cwd()): boolean {
6
- return (
7
- fs.existsSync(path.join(cwd, 'next.config.js')) ||
8
- fs.existsSync(path.join(cwd, 'next.config.ts')) ||
9
- fs.existsSync(path.join(cwd, 'next.config.mjs'))
10
- )
11
- }
12
-
13
- export function getPackageJson(cwd: string = process.cwd()): Record<string, any> | null {
14
- const pkgPath = path.join(cwd, 'package.json')
15
- if (!fs.existsSync(pkgPath)) return null
16
- return JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
17
- }
18
-
19
- export function getAppName(cwd: string = process.cwd()): string {
20
- const pkg = getPackageJson(cwd)
21
- return pkg?.name ?? path.basename(cwd)
22
- }
23
-
24
- export function waitForServer(url: string, timeout = 60000): Promise<void> {
25
- return new Promise((resolve, reject) => {
26
- const start = Date.now()
27
-
28
- const check = () => {
29
- http.get(url, (res) => {
30
- if (res.statusCode && res.statusCode < 500) {
31
- resolve()
32
- } else {
33
- retry()
34
- }
35
- }).on('error', retry)
36
- }
37
-
38
- const retry = () => {
39
- if (Date.now() - start > timeout) {
40
- reject(new Error(`Server at ${url} did not start within ${timeout}ms`))
41
- return
42
- }
43
- setTimeout(check, 500)
44
- }
45
-
46
- check()
47
- })
48
- }
49
-
50
- export function getRuntimeBinary(): string {
51
- const cwd = process.cwd()
52
-
53
- // Priority 1: Check in project's .nextdesk/bin/ (after init)
54
- const localBinary = path.join(cwd, '.nextdesk/bin/nextdesk-runtime')
55
- if (fs.existsSync(localBinary)) return localBinary
56
-
57
- // Priority 2: Check in node_modules/.nextdesk/bin/
58
- const nodeModulesBinary = path.join(cwd, 'node_modules/.nextdesk/bin/nextdesk-runtime')
59
- if (fs.existsSync(nodeModulesBinary)) return nodeModulesBinary
60
-
61
- // Priority 3: Check parent's mydesk-poc (development)
62
- const devBinary = path.join(cwd, '../mydesk-poc/target/release/mydesk-poc')
63
- if (fs.existsSync(devBinary)) return devBinary
64
-
65
- // Priority 4: Check hardcoded path from home
66
- const homeBinary = path.join(process.env.HOME || '', 'Projects/Personal/mydesk-poc/target/release/mydesk-poc')
67
- if (fs.existsSync(homeBinary)) return homeBinary
68
-
69
- throw new Error('NextDesk runtime not found. Run `npx nextdesk init` to set it up.')
70
- }
package/tsconfig.json DELETED
@@ -1,15 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2020",
4
- "module": "commonjs",
5
- "lib": ["ES2020"],
6
- "outDir": "./dist",
7
- "rootDir": "./src",
8
- "strict": true,
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "resolveJsonModule": true
12
- },
13
- "include": ["src/**/*"],
14
- "exclude": ["node_modules", "dist"]
15
- }