@agent-webui/ai-desk-daemon 1.0.19 → 1.0.20

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
@@ -18,60 +18,7 @@
18
18
 
19
19
  ## 📦 安装
20
20
 
21
- ### 方式 1: npm 安装(纯 CLI 工具)
22
-
23
- **适合场景**:开发者、服务器环境、CI/CD、命令行用户
24
-
25
- ```bash
26
- # 全局安装
27
- npm install -g @agent-webui/ai-desk-daemon
28
-
29
- # 启动 daemon
30
- aidesk start
31
-
32
- # 查看状态
33
- aidesk status
34
- ```
35
-
36
- **⚠️ 如果遇到 E401 错误**:
37
-
38
- 如果你看到类似 `401 Unauthorized - GET https://npm.pkg.github.com/@agent-webui%2fai-desk-daemon` 的错误,说明你的 npm 配置指向了 GitHub Packages。请运行:
39
-
40
- ```bash
41
- # 临时解决(仅本次安装)
42
- npm install -g @agent-webui/ai-desk-daemon --registry=https://registry.npmjs.org/
43
-
44
- # 永久解决(推荐)
45
- npm config set @agent-webui:registry https://registry.npmjs.org/
46
- ```
47
-
48
- **包含内容**:
49
- - ✅ AI Desk Daemon 后台服务
50
- - ✅ CLI 命令行管理工具
51
- - ✅ HTTP API (http://localhost:9527)
52
-
53
- **不包含**:
54
- - ❌ 系统托盘应用 (Tray)
55
- - ❌ 桌面 GUI 应用
56
-
57
- **可用命令**:
58
- - `aidesk start` - 启动守护进程(后台运行)
59
- - `aidesk start --log` - 启动守护进程(前台运行,跟随日志)
60
- - `aidesk stop` - 停止守护进程
61
- - `aidesk restart` - 重启守护进程
62
- - `aidesk status` - 查看状态
63
- - `aidesk logs` - 查看日志
64
- - `aidesk logs -f` - 实时查看日志(不会停止守护进程)
65
-
66
- 📖 详细使用说明:[NPM_CLI.md](NPM_CLI.md)
67
-
68
- ---
69
-
70
- ### 方式 2: 完整安装(Daemon + Tray)
71
-
72
- **适合场景**:桌面用户、需要系统托盘图标、完整 GUI 体验
73
-
74
- #### macOS
21
+ ### macOS
75
22
 
76
23
  ```bash
77
24
  # 下载并安装
@@ -81,7 +28,7 @@ curl -fsSL https://github.com/your-repo/ai-desk-desktop/releases/latest/download
81
28
  ./scripts/install-macos.sh
82
29
  ```
83
30
 
84
- #### Linux
31
+ ### Linux
85
32
 
86
33
  ```bash
87
34
  # Ubuntu/Debian
@@ -92,7 +39,7 @@ systemctl --user enable ai-desk-daemon
92
39
  systemctl --user start ai-desk-daemon
93
40
  ```
94
41
 
95
- #### Windows
42
+ ### Windows
96
43
 
97
44
  ```powershell
98
45
  # 以管理员身份运行 PowerShell
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-webui/ai-desk-daemon",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "AI Desk Daemon - CLI tool for managing the AI Desk daemon service",
5
5
  "main": "lib/daemon-manager.js",
6
6
  "bin": {
@@ -25,8 +25,7 @@
25
25
  "bin/",
26
26
  "lib/",
27
27
  "scripts/postinstall.js",
28
- "README.md",
29
- ".npmrc"
28
+ "README.md"
30
29
  ],
31
30
  "dependencies": {
32
31
  "commander": "^11.0.0",
@@ -1,157 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Post-install script to download platform-specific daemon binary from GitHub Releases
4
+ * Post-install script for @agent-webui/ai-desk-daemon
5
+ * This script does nothing - binaries are managed separately
6
+ *
7
+ * In the future, this could download platform-specific binaries from GitHub Releases
5
8
  */
6
9
 
7
- const https = require('https');
8
- const fs = require('fs');
9
- const path = require('path');
10
- const { execSync } = require('child_process');
11
-
12
- const GITHUB_REPO = 'agent-webui/ai-desk-daemon';
13
- const PACKAGE_VERSION = require('../package.json').version;
14
-
15
- // Platform mapping
16
- const PLATFORM_MAP = {
17
- 'darwin-x64': 'darwin-x64',
18
- 'darwin-arm64': 'darwin-arm64',
19
- 'linux-x64': 'linux-x64',
20
- 'linux-arm64': 'linux-arm64',
21
- 'win32-x64': 'win32-x64'
22
- };
23
-
24
- function getPlatform() {
25
- const platform = process.platform;
26
- const arch = process.arch;
27
- const key = `${platform}-${arch}`;
28
-
29
- if (!PLATFORM_MAP[key]) {
30
- console.error(`Unsupported platform: ${platform}-${arch}`);
31
- console.error('Supported platforms:', Object.keys(PLATFORM_MAP).join(', '));
32
- process.exit(1);
33
- }
34
-
35
- return PLATFORM_MAP[key];
36
- }
37
-
38
- function getBinaryName(platform) {
39
- return platform.startsWith('win32') ? 'ai-desk-daemon.exe' : 'ai-desk-daemon';
40
- }
41
-
42
- function downloadFile(url, dest) {
43
- return new Promise((resolve, reject) => {
44
- console.log(`Downloading from: ${url}`);
45
-
46
- const file = fs.createWriteStream(dest);
47
-
48
- https.get(url, (response) => {
49
- if (response.statusCode === 302 || response.statusCode === 301) {
50
- // Follow redirect
51
- file.close();
52
- fs.unlinkSync(dest);
53
- return downloadFile(response.headers.location, dest).then(resolve).catch(reject);
54
- }
55
-
56
- if (response.statusCode !== 200) {
57
- file.close();
58
- fs.unlinkSync(dest);
59
- return reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
60
- }
61
-
62
- const totalSize = parseInt(response.headers['content-length'], 10);
63
- let downloadedSize = 0;
64
- let lastPercent = 0;
65
-
66
- response.on('data', (chunk) => {
67
- downloadedSize += chunk.length;
68
- const percent = Math.floor((downloadedSize / totalSize) * 100);
69
- if (percent > lastPercent && percent % 10 === 0) {
70
- console.log(`Progress: ${percent}%`);
71
- lastPercent = percent;
72
- }
73
- });
74
-
75
- response.pipe(file);
76
-
77
- file.on('finish', () => {
78
- file.close();
79
- console.log('Download complete!');
80
- resolve();
81
- });
82
- }).on('error', (err) => {
83
- file.close();
84
- fs.unlinkSync(dest);
85
- reject(err);
86
- });
87
- });
88
- }
89
-
90
- async function main() {
91
- console.log('='.repeat(50));
92
- console.log('AI Desk Daemon - Post Install');
93
- console.log('='.repeat(50));
94
-
95
- const platform = getPlatform();
96
- const binaryName = getBinaryName(platform);
97
-
98
- console.log(`Platform: ${platform}`);
99
- console.log(`Version: ${PACKAGE_VERSION}`);
100
- console.log(`Binary: ${binaryName}`);
101
- console.log('');
102
-
103
- // Create dist directory
104
- const distDir = path.join(__dirname, '..', 'dist', platform);
105
- if (!fs.existsSync(distDir)) {
106
- fs.mkdirSync(distDir, { recursive: true });
107
- }
108
-
109
- const binaryPath = path.join(distDir, binaryName);
110
-
111
- // Check if binary already exists
112
- if (fs.existsSync(binaryPath)) {
113
- console.log('Binary already exists, skipping download.');
114
- console.log(`Location: ${binaryPath}`);
115
- return;
116
- }
117
-
118
- // Download from GitHub Releases
119
- // Format: ai-desk-daemon-darwin-arm64 or ai-desk-daemon-win32-x64.exe
120
- const assetName = platform.startsWith('win32')
121
- ? `ai-desk-daemon-${platform}.exe`
122
- : `ai-desk-daemon-${platform}`;
123
- const downloadUrl = `https://github.com/${GITHUB_REPO}/releases/download/v${PACKAGE_VERSION}/${assetName}`;
124
-
125
- console.log('Downloading daemon binary...');
126
-
127
- try {
128
- await downloadFile(downloadUrl, binaryPath);
129
-
130
- // Set executable permission (Unix-like systems)
131
- if (process.platform !== 'win32') {
132
- fs.chmodSync(binaryPath, 0o755);
133
- console.log('Set executable permission');
134
- }
135
-
136
- console.log('');
137
- console.log('✓ Installation complete!');
138
- console.log(`Binary installed at: ${binaryPath}`);
139
- console.log('');
140
- console.log('Run "aidesk --help" to get started.');
141
- console.log('='.repeat(50));
142
- } catch (error) {
143
- console.error('');
144
- console.error('✗ Failed to download daemon binary');
145
- console.error(`Error: ${error.message}`);
146
- console.error('');
147
- console.error('Please try one of the following:');
148
- console.error(`1. Download manually from: https://github.com/${GITHUB_REPO}/releases/tag/v${PACKAGE_VERSION}`);
149
- console.error(`2. Place the binary at: ${binaryPath}`);
150
- console.error('3. Report this issue at: https://github.com/${GITHUB_REPO}/issues');
151
- console.error('='.repeat(50));
152
- process.exit(1);
153
- }
154
- }
155
-
156
- main();
157
-
10
+ console.log('✓ @agent-webui/ai-desk-daemon installed successfully');
11
+ console.log('');
12
+ console.log('Note: This is a CLI wrapper. The actual daemon binaries are managed separately.');
13
+ console.log('');
package/bin/cli.js DELETED
@@ -1,231 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * AI Desk Daemon CLI
5
- */
6
-
7
- const { program } = require('commander');
8
- const chalk = require('chalk');
9
- const fs = require('fs');
10
- const { start, stop, restart, status } = require('../lib/daemon-manager');
11
- const { getLogPath } = require('../lib/platform');
12
- const { VERSION } = require('../lib/platform');
13
-
14
- program
15
- .name('ai-desk-daemon')
16
- .description('AI Desk Daemon - CLI tool for managing the AI Desk daemon service')
17
- .version(VERSION);
18
-
19
- // Start command
20
- program
21
- .command('start')
22
- .description('Start the daemon')
23
- .option('--log', 'Follow daemon logs in foreground (Ctrl+C to stop daemon)')
24
- .action(async (options) => {
25
- try {
26
- const { getPidPath } = require('../lib/platform');
27
- const daemonPid = start();
28
- console.log(chalk.green('✓ Daemon started successfully'));
29
-
30
- // Only follow logs if --log is specified
31
- if (options.log) {
32
- console.log(chalk.cyan('\n📋 Following daemon logs (Ctrl+C to stop daemon)...\n'));
33
-
34
- // Wait a moment for daemon to start writing logs
35
- await new Promise(resolve => setTimeout(resolve, 1000));
36
-
37
- const logPath = getLogPath();
38
- if (!fs.existsSync(logPath)) {
39
- console.log(chalk.yellow('Waiting for logs...'));
40
- await new Promise(resolve => setTimeout(resolve, 2000));
41
- }
42
-
43
- // Follow logs (tail -f) - works on Unix-like systems
44
- if (process.platform !== 'win32') {
45
- const { spawn } = require('child_process');
46
- const tail = spawn('tail', ['-f', logPath]);
47
-
48
- tail.stdout.on('data', (data) => {
49
- process.stdout.write(data);
50
- });
51
-
52
- tail.stderr.on('data', (data) => {
53
- process.stderr.write(data);
54
- });
55
-
56
- tail.on('error', (error) => {
57
- console.error(chalk.red('Failed to follow logs:'), error.message);
58
- process.exit(1);
59
- });
60
-
61
- // Handle Ctrl+C - stop the daemon
62
- process.on('SIGINT', () => {
63
- console.log(chalk.yellow('\n\n⏹ Stopping daemon...'));
64
- tail.kill();
65
-
66
- try {
67
- // Stop the daemon
68
- const { stop } = require('../lib/daemon-manager');
69
- stop();
70
- console.log(chalk.green('✓ Daemon stopped successfully'));
71
- } catch (error) {
72
- console.error(chalk.red('✗ Failed to stop daemon:'), error.message);
73
- }
74
-
75
- process.exit(0);
76
- });
77
- } else {
78
- // Windows: use polling to read log file
79
- console.log(chalk.yellow('Log following on Windows - press Ctrl+C to stop daemon\n'));
80
-
81
- let lastSize = 0;
82
- const pollInterval = setInterval(() => {
83
- try {
84
- const stats = fs.statSync(logPath);
85
- if (stats.size > lastSize) {
86
- const stream = fs.createReadStream(logPath, {
87
- start: lastSize,
88
- end: stats.size
89
- });
90
- stream.on('data', (chunk) => {
91
- process.stdout.write(chunk);
92
- });
93
- lastSize = stats.size;
94
- }
95
- } catch (error) {
96
- // Ignore errors
97
- }
98
- }, 500);
99
-
100
- process.on('SIGINT', () => {
101
- clearInterval(pollInterval);
102
- console.log(chalk.yellow('\n\n⏹ Stopping daemon...'));
103
-
104
- try {
105
- // Stop the daemon
106
- const { stop } = require('../lib/daemon-manager');
107
- stop();
108
- console.log(chalk.green('✓ Daemon stopped successfully'));
109
- } catch (error) {
110
- console.error(chalk.red('✗ Failed to stop daemon:'), error.message);
111
- }
112
-
113
- process.exit(0);
114
- });
115
- }
116
- }
117
- } catch (error) {
118
- console.error(chalk.red('✗ Failed to start daemon:'), error.message);
119
- process.exit(1);
120
- }
121
- });
122
-
123
- // Stop command
124
- program
125
- .command('stop')
126
- .description('Stop the daemon')
127
- .action(async () => {
128
- try {
129
- stop();
130
- console.log(chalk.green('✓ Daemon stopped successfully'));
131
- } catch (error) {
132
- console.error(chalk.red('✗ Failed to stop daemon:'), error.message);
133
- process.exit(1);
134
- }
135
- });
136
-
137
- // Restart command
138
- program
139
- .command('restart')
140
- .description('Restart the daemon')
141
- .action(async () => {
142
- try {
143
- restart();
144
- console.log(chalk.green('✓ Daemon restarted successfully'));
145
- } catch (error) {
146
- console.error(chalk.red('✗ Failed to restart daemon:'), error.message);
147
- process.exit(1);
148
- }
149
- });
150
-
151
- // Status command
152
- program
153
- .command('status')
154
- .description('Check daemon status')
155
- .action(async () => {
156
- try {
157
- const statusInfo = await status();
158
-
159
- console.log('\n' + chalk.bold('AI Desk Daemon Status'));
160
- console.log('─'.repeat(40));
161
-
162
- if (statusInfo.running) {
163
- console.log(chalk.green('● Running'));
164
-
165
- if (statusInfo.health && statusInfo.health.data) {
166
- const { status: healthStatus, version } = statusInfo.health.data;
167
- console.log(`Version: ${version || 'unknown'}`);
168
- console.log(`Status: ${healthStatus}`);
169
- }
170
-
171
- console.log(`Port: ${statusInfo.port}`);
172
- console.log(`Dashboard: http://localhost:${statusInfo.port}/daemon-dashboard.html`);
173
- } else {
174
- console.log(chalk.red('○ Stopped'));
175
- }
176
-
177
- console.log(`Logs: ${statusInfo.logPath}`);
178
- console.log('');
179
- } catch (error) {
180
- console.error(chalk.red('✗ Failed to get status:'), error.message);
181
- process.exit(1);
182
- }
183
- });
184
-
185
- // Logs command
186
- program
187
- .command('logs')
188
- .description('View daemon logs')
189
- .option('-f, --follow', 'Follow log output')
190
- .option('-n, --lines <number>', 'Number of lines to show', '50')
191
- .action((options) => {
192
- const logPath = getLogPath();
193
-
194
- if (!fs.existsSync(logPath)) {
195
- console.log(chalk.yellow('No logs found'));
196
- return;
197
- }
198
-
199
- if (options.follow) {
200
- // Follow logs (tail -f)
201
- const { spawn } = require('child_process');
202
- const tail = spawn('tail', ['-f', logPath]);
203
-
204
- tail.stdout.on('data', (data) => {
205
- process.stdout.write(data);
206
- });
207
-
208
- tail.on('error', (error) => {
209
- console.error(chalk.red('Failed to follow logs:'), error.message);
210
- process.exit(1);
211
- });
212
- } else {
213
- // Show last N lines
214
- const { execSync } = require('child_process');
215
- try {
216
- const output = execSync(`tail -n ${options.lines} "${logPath}"`, { encoding: 'utf8' });
217
- console.log(output);
218
- } catch (error) {
219
- console.error(chalk.red('Failed to read logs:'), error.message);
220
- process.exit(1);
221
- }
222
- }
223
- });
224
-
225
- program.parse(process.argv);
226
-
227
- // Show help if no command provided
228
- if (!process.argv.slice(2).length) {
229
- program.outputHelp();
230
- }
231
-
package/lib/config.js DELETED
@@ -1,103 +0,0 @@
1
- /**
2
- * Configuration management
3
- */
4
-
5
- const fs = require('fs');
6
- const path = require('path');
7
- const { getConfigDir, getConfigPath } = require('./platform');
8
-
9
- const DEFAULT_PORT = 9527;
10
-
11
- /**
12
- * Ensure config directory exists
13
- */
14
- function ensureConfigDir() {
15
- const configDir = getConfigDir();
16
- const logsDir = path.join(configDir, 'logs');
17
-
18
- if (!fs.existsSync(configDir)) {
19
- fs.mkdirSync(configDir, { recursive: true });
20
- }
21
-
22
- if (!fs.existsSync(logsDir)) {
23
- fs.mkdirSync(logsDir, { recursive: true });
24
- }
25
- }
26
-
27
- /**
28
- * Load config from file
29
- */
30
- function loadConfig() {
31
- ensureConfigDir();
32
-
33
- const configPath = getConfigPath();
34
-
35
- if (!fs.existsSync(configPath)) {
36
- // Create default config
37
- const defaultConfig = {
38
- port: DEFAULT_PORT,
39
- logLevel: 'info',
40
- autoStart: true
41
- };
42
- saveConfig(defaultConfig);
43
- return defaultConfig;
44
- }
45
-
46
- try {
47
- const content = fs.readFileSync(configPath, 'utf8');
48
- return JSON.parse(content);
49
- } catch (error) {
50
- console.error('Failed to load config:', error.message);
51
- return { port: DEFAULT_PORT };
52
- }
53
- }
54
-
55
- /**
56
- * Save config to file
57
- */
58
- function saveConfig(config) {
59
- ensureConfigDir();
60
-
61
- const configPath = getConfigPath();
62
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
63
- }
64
-
65
- /**
66
- * Get port from config
67
- */
68
- function getPort() {
69
- const config = loadConfig();
70
- const port = config.port || DEFAULT_PORT;
71
- // Ensure port is a valid integer
72
- const portNum = parseInt(port, 10);
73
- if (isNaN(portNum) || portNum <= 0 || portNum > 65535) {
74
- console.warn(`Invalid port ${port}, using default ${DEFAULT_PORT}`);
75
- return DEFAULT_PORT;
76
- }
77
- return portNum;
78
- }
79
-
80
- /**
81
- * Set port in config
82
- */
83
- function setPort(port) {
84
- const config = loadConfig();
85
- // Ensure port is stored as integer
86
- const portNum = parseInt(port, 10);
87
- if (isNaN(portNum) || portNum <= 0 || portNum > 65535) {
88
- throw new Error(`Invalid port number: ${port}`);
89
- }
90
- config.port = portNum;
91
- saveConfig(config);
92
- }
93
-
94
- module.exports = {
95
- ensureConfigDir,
96
- loadConfig,
97
- saveConfig,
98
- getPort,
99
- setPort,
100
- getConfigPath, // Re-export from platform.js
101
- DEFAULT_PORT
102
- };
103
-
@@ -1,189 +0,0 @@
1
- /**
2
- * Daemon process management
3
- */
4
-
5
- const fs = require('fs');
6
- const { spawn, execSync } = require('child_process');
7
- const http = require('http');
8
- const { getDaemonBinaryPath, getPidPath, getLogPath } = require('./platform');
9
- const { getPort, getConfigPath } = require('./config');
10
-
11
- /**
12
- * Check if daemon is running
13
- */
14
- function isRunning() {
15
- const pidPath = getPidPath();
16
-
17
- if (!fs.existsSync(pidPath)) {
18
- return false;
19
- }
20
-
21
- try {
22
- const pid = parseInt(fs.readFileSync(pidPath, 'utf8').trim());
23
-
24
- // Check if process exists
25
- process.kill(pid, 0);
26
- return true;
27
- } catch (error) {
28
- // Process doesn't exist
29
- return false;
30
- }
31
- }
32
-
33
- /**
34
- * Get daemon health status
35
- */
36
- function getHealth() {
37
- return new Promise((resolve) => {
38
- const port = getPort();
39
- const options = {
40
- hostname: 'localhost',
41
- port: port,
42
- path: '/health',
43
- method: 'GET',
44
- timeout: 2000
45
- };
46
-
47
- const req = http.request(options, (res) => {
48
- let data = '';
49
- res.on('data', (chunk) => { data += chunk; });
50
- res.on('end', () => {
51
- try {
52
- const health = JSON.parse(data);
53
- resolve(health);
54
- } catch (error) {
55
- resolve(null);
56
- }
57
- });
58
- });
59
-
60
- req.on('error', () => resolve(null));
61
- req.on('timeout', () => {
62
- req.destroy();
63
- resolve(null);
64
- });
65
-
66
- req.end();
67
- });
68
- }
69
-
70
- /**
71
- * Start daemon
72
- */
73
- function start() {
74
- if (isRunning()) {
75
- throw new Error('Daemon is already running');
76
- }
77
-
78
- const binaryPath = getDaemonBinaryPath();
79
- if (!fs.existsSync(binaryPath)) {
80
- throw new Error(
81
- `Daemon binary not found at: ${binaryPath}\n` +
82
- `This might be a corrupted installation. Try reinstalling:\n` +
83
- ` npm install -g @ringcentral/ai-desk-daemon --force`
84
- );
85
- }
86
-
87
- // Ensure binary is executable (Unix-like systems)
88
- if (process.platform !== 'win32') {
89
- try {
90
- fs.chmodSync(binaryPath, 0o755);
91
- } catch (error) {
92
- // Ignore permission errors
93
- }
94
- }
95
-
96
- const port = getPort();
97
- const configPath = getConfigPath();
98
- const logPath = getLogPath();
99
-
100
- // Ensure port is a number
101
- const portNumber = typeof port === 'number' ? port : parseInt(port, 10);
102
- if (isNaN(portNumber)) {
103
- throw new Error(`Invalid port number: ${port}`);
104
- }
105
-
106
- // Ensure log directory exists
107
- const logDir = require('path').dirname(logPath);
108
- if (!fs.existsSync(logDir)) {
109
- fs.mkdirSync(logDir, { recursive: true });
110
- }
111
-
112
- // The daemon handles its own logging to file (see daemon/logger.go)
113
- // It uses io.MultiWriter to write to both stdout and the log file
114
- // So we should ignore stdout/stderr here to avoid duplication
115
- const child = spawn(binaryPath, ['--port', portNumber.toString(), '--config', configPath], {
116
- detached: true,
117
- stdio: ['ignore', 'ignore', 'ignore'] // Daemon writes to its own log file
118
- });
119
-
120
- child.unref();
121
-
122
- // Save PID
123
- fs.writeFileSync(getPidPath(), child.pid.toString());
124
-
125
- console.log(`Daemon started (PID: ${child.pid})`);
126
- console.log(`Port: ${portNumber}`);
127
- console.log(`Logs: ${logPath}`);
128
-
129
- return child.pid;
130
- }
131
-
132
- /**
133
- * Stop daemon
134
- */
135
- function stop() {
136
- const pidPath = getPidPath();
137
-
138
- if (!fs.existsSync(pidPath)) {
139
- throw new Error('Daemon is not running');
140
- }
141
-
142
- const pid = parseInt(fs.readFileSync(pidPath, 'utf8').trim());
143
-
144
- try {
145
- process.kill(pid, 'SIGTERM');
146
- fs.unlinkSync(pidPath);
147
- console.log('Daemon stopped');
148
- } catch (error) {
149
- fs.unlinkSync(pidPath);
150
- throw new Error(`Failed to stop daemon: ${error.message}`);
151
- }
152
- }
153
-
154
- /**
155
- * Restart daemon
156
- */
157
- function restart() {
158
- if (isRunning()) {
159
- stop();
160
- // Wait a bit for graceful shutdown
161
- execSync('sleep 1');
162
- }
163
- start();
164
- }
165
-
166
- /**
167
- * Get daemon status
168
- */
169
- async function status() {
170
- const running = isRunning();
171
- const health = running ? await getHealth() : null;
172
-
173
- return {
174
- running,
175
- health,
176
- port: getPort(),
177
- logPath: getLogPath()
178
- };
179
- }
180
-
181
- module.exports = {
182
- isRunning,
183
- getHealth,
184
- start,
185
- stop,
186
- restart,
187
- status
188
- };
189
-
package/lib/platform.js DELETED
@@ -1,87 +0,0 @@
1
- /**
2
- * Platform detection and binary path resolution
3
- */
4
-
5
- const os = require('os');
6
- const path = require('path');
7
-
8
- const VERSION = '1.0.19';
9
-
10
- /**
11
- * Detect current platform and architecture
12
- */
13
- function detectPlatform() {
14
- const platform = os.platform();
15
- const arch = os.arch();
16
-
17
- let platformKey;
18
-
19
- // Map Node.js platform to binary directory name
20
- switch (platform) {
21
- case 'darwin':
22
- platformKey = arch === 'arm64' ? 'darwin-arm64' : 'darwin-x64';
23
- break;
24
- case 'linux':
25
- platformKey = arch === 'arm64' ? 'linux-arm64' : 'linux-x64';
26
- break;
27
- case 'win32':
28
- platformKey = 'win32-x64';
29
- break;
30
- default:
31
- throw new Error(`Unsupported platform: ${platform}-${arch}`);
32
- }
33
-
34
- return { platform, arch, platformKey };
35
- }
36
-
37
- /**
38
- * Get daemon binary path from npm package
39
- */
40
- function getDaemonBinaryPath() {
41
- const { platform, platformKey } = detectPlatform();
42
-
43
- // Binary is in the npm package under dist/<platform>/
44
- const binaryName = platform === 'win32' ? 'ai-desk-daemon.exe' : 'ai-desk-daemon';
45
- const binaryPath = path.join(__dirname, '..', 'dist', platformKey, binaryName);
46
-
47
- return binaryPath;
48
- }
49
-
50
- /**
51
- * Get config directory
52
- */
53
- function getConfigDir() {
54
- return path.join(os.homedir(), '.aidesktop');
55
- }
56
-
57
- /**
58
- * Get config file path
59
- */
60
- function getConfigPath() {
61
- return path.join(getConfigDir(), 'daemon-config.json');
62
- }
63
-
64
- /**
65
- * Get log file path
66
- */
67
- function getLogPath() {
68
- return path.join(getConfigDir(), 'logs', 'daemon.log');
69
- }
70
-
71
- /**
72
- * Get PID file path
73
- */
74
- function getPidPath() {
75
- return path.join(getConfigDir(), 'daemon.pid');
76
- }
77
-
78
- module.exports = {
79
- detectPlatform,
80
- getDaemonBinaryPath,
81
- getConfigDir,
82
- getConfigPath,
83
- getLogPath,
84
- getPidPath,
85
- VERSION
86
- };
87
-