cicy-code 2.0.1 → 2.1.47
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/bin/cicy-code.js +28 -214
- package/package.json +15 -6
- package/bin/cicy-code +0 -0
- package/scripts/install.js +0 -60
package/bin/cicy-code.js
CHANGED
|
@@ -1,220 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
// Thin launcher: resolves the prebuilt binary that ships in the
|
|
3
|
+
// platform-specific optionalDependency (cicy-code-<os>-<cpu>) and execs it.
|
|
4
|
+
// No network, no postinstall download — npm installs only the sub-package
|
|
5
|
+
// matching the current os/cpu (the others are skipped via their os/cpu
|
|
6
|
+
// fields), so a CN user pulls just their ~30MB slice from npmmirror.
|
|
7
|
+
const { spawn } = require('child_process');
|
|
4
8
|
const fs = require('fs');
|
|
5
|
-
const https = require('https');
|
|
6
9
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
console.log(' [mirror] Using Chinese mirrors (npm + GitHub proxy)');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Check for updates
|
|
25
|
-
function checkUpdate() {
|
|
26
|
-
const registry = cn
|
|
27
|
-
? 'https://registry.npmmirror.com/cicy-code/latest'
|
|
28
|
-
: 'https://registry.npmjs.org/cicy-code/latest';
|
|
29
|
-
if (cn) console.log(` [mirror] Registry: registry.npmmirror.com`);
|
|
30
|
-
return new Promise((resolve) => {
|
|
31
|
-
https.get(registry, (res) => {
|
|
32
|
-
let data = '';
|
|
33
|
-
res.on('data', (c) => data += c);
|
|
34
|
-
res.on('end', () => {
|
|
35
|
-
try {
|
|
36
|
-
const latest = JSON.parse(data).version;
|
|
37
|
-
if (latest && latest !== pkg.version) {
|
|
38
|
-
resolve(latest);
|
|
39
|
-
} else {
|
|
40
|
-
resolve(null);
|
|
41
|
-
}
|
|
42
|
-
} catch { resolve(null); }
|
|
43
|
-
});
|
|
44
|
-
}).on('error', () => resolve(null));
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function main() {
|
|
49
|
-
// Check update (non-blocking, timeout 3s)
|
|
50
|
-
const latest = await Promise.race([
|
|
51
|
-
checkUpdate(),
|
|
52
|
-
new Promise(r => setTimeout(() => r(null), 3000))
|
|
53
|
-
]);
|
|
54
|
-
|
|
55
|
-
if (latest && !process.env.CICY_SKIP_UPDATE) {
|
|
56
|
-
console.log(`\n Update available: ${pkg.version} → ${latest}`);
|
|
57
|
-
console.log(` Updating...\n`);
|
|
58
|
-
try {
|
|
59
|
-
const npmCmd = cn
|
|
60
|
-
? `npm install -g cicy-code@${latest} --registry=https://registry.npmmirror.com`
|
|
61
|
-
: `npm install -g cicy-code@${latest}`;
|
|
62
|
-
execSync(npmCmd, { stdio: 'inherit' });
|
|
63
|
-
console.log(`\n Updated to ${latest}! Restarting...\n`);
|
|
64
|
-
// Re-exec with new version
|
|
65
|
-
const child = spawn('cicy-code', process.argv.slice(2), { stdio: 'inherit', env: process.env });
|
|
66
|
-
child.on('exit', (code) => process.exit(code || 0));
|
|
67
|
-
return;
|
|
68
|
-
} catch (e) {
|
|
69
|
-
console.log(` Update failed, running current version.\n`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Install globally if not already
|
|
74
|
-
try {
|
|
75
|
-
const globalBin = execSync('npm prefix -g', { encoding: 'utf8' }).trim() + '/bin/cicy-code';
|
|
76
|
-
if (!fs.existsSync(globalBin)) throw new Error('not installed');
|
|
77
|
-
} catch {
|
|
78
|
-
console.log(' Installing cicy-code globally...');
|
|
79
|
-
try {
|
|
80
|
-
const npmCmd = cn
|
|
81
|
-
? 'npm install -g cicy-code --registry=https://registry.npmmirror.com'
|
|
82
|
-
: 'npm install -g cicy-code';
|
|
83
|
-
execSync(npmCmd, { stdio: 'inherit' });
|
|
84
|
-
console.log(' Installed! You can now run: cicy-code\n');
|
|
85
|
-
} catch {}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!fs.existsSync(binPath)) {
|
|
89
|
-
console.error('Binary not found. Reinstall: npm install -g cicy-code');
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Desktop mode: start API server in background, then launch Electron
|
|
94
|
-
if (desktopMode) {
|
|
95
|
-
return launchDesktop();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const child = spawn(binPath, process.argv.slice(2), {
|
|
99
|
-
stdio: 'inherit',
|
|
100
|
-
env: process.env
|
|
101
|
-
});
|
|
102
|
-
child.on('exit', (code) => process.exit(code || 0));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function getToken() {
|
|
106
|
-
try {
|
|
107
|
-
const data = JSON.parse(fs.readFileSync(CICY_GLOBAL_JSON_PATH, 'utf8'));
|
|
108
|
-
return data.api_token || '';
|
|
109
|
-
} catch { return ''; }
|
|
10
|
+
const platformPkg = `cicy-code-${process.platform}-${process.arch}`;
|
|
11
|
+
|
|
12
|
+
let binPath;
|
|
13
|
+
try {
|
|
14
|
+
// require.resolve finds the binary inside the installed sub-package,
|
|
15
|
+
// wherever the package manager hoisted it.
|
|
16
|
+
binPath = require.resolve(`${platformPkg}/cicy-code`);
|
|
17
|
+
} catch {
|
|
18
|
+
console.error(`cicy-code: no prebuilt binary for ${process.platform}-${process.arch}.`);
|
|
19
|
+
console.error(`The optional dependency "${platformPkg}" is not installed.`);
|
|
20
|
+
console.error(`Supported platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64.`);
|
|
21
|
+
console.error(`Reinstall: npm install -g cicy-code` +
|
|
22
|
+
` (in China add --registry=https://registry.npmmirror.com)`);
|
|
23
|
+
process.exit(1);
|
|
110
24
|
}
|
|
111
25
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return new Promise((resolve, reject) => {
|
|
116
|
-
const check = () => {
|
|
117
|
-
if (Date.now() - start > timeout) return reject(new Error('Server start timeout'));
|
|
118
|
-
const req = http.get(`http://127.0.0.1:${port}/api/health`, (res) => {
|
|
119
|
-
resolve();
|
|
120
|
-
});
|
|
121
|
-
req.on('error', () => setTimeout(check, 500));
|
|
122
|
-
req.setTimeout(1000, () => { req.destroy(); setTimeout(check, 500); });
|
|
123
|
-
};
|
|
124
|
-
check();
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async function launchDesktop() {
|
|
129
|
-
const port = process.env.PORT || 8008;
|
|
130
|
-
const desktopPort = 18101;
|
|
131
|
-
|
|
132
|
-
// 0. Kill existing electron/cicy-code and free ports
|
|
133
|
-
try { execSync(`pkill -f 'electron' 2>/dev/null || true`, { shell: true }); } catch {}
|
|
134
|
-
try { execSync(`lsof -ti:${desktopPort} | xargs kill -9 2>/dev/null || true`, { shell: true }); } catch {}
|
|
135
|
-
try { execSync(`lsof -ti:${port} | xargs kill -9 2>/dev/null || true`, { shell: true }); } catch {}
|
|
136
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
137
|
-
|
|
138
|
-
// 1. Start API server in background
|
|
139
|
-
const serverArgs = process.argv.slice(2).filter(a => a !== '--desktop');
|
|
140
|
-
const isWin = process.platform === 'win32';
|
|
141
|
-
const server = spawn(isWin ? binPath : 'nohup', isWin ? serverArgs : [binPath, ...serverArgs], {
|
|
142
|
-
stdio: 'ignore',
|
|
143
|
-
detached: true,
|
|
144
|
-
env: { ...process.env, CICY_NO_BROWSER: '1', TERM: process.env.TERM || 'xterm-256color' }
|
|
145
|
-
});
|
|
146
|
-
server.on('exit', (code, signal) => console.error(` ⚠️ Server exited code=${code} signal=${signal}`));
|
|
147
|
-
server.unref();
|
|
148
|
-
console.log(` 🚀 Starting cicy-code server (PID: ${server.pid})...`);
|
|
149
|
-
|
|
150
|
-
// 2. Wait for server ready
|
|
151
|
-
try {
|
|
152
|
-
await waitForServer(port, 30000);
|
|
153
|
-
} catch {
|
|
154
|
-
console.error(' ❌ Server failed to start within 30s');
|
|
155
|
-
process.exit(1);
|
|
156
|
-
}
|
|
157
|
-
console.log(` ✅ Server ready on port ${port}`);
|
|
158
|
-
|
|
159
|
-
// 3. Get token
|
|
160
|
-
const token = getToken();
|
|
161
|
-
const url = `http://127.0.0.1:${port}/?token=${token}`;
|
|
162
|
-
|
|
163
|
-
// 4. Launch Electron via global 'electron' binary (no signing needed)
|
|
164
|
-
// cicy-desktop uses official Electron binary + our JS code
|
|
165
|
-
// RPC/MCP server starts on desktopPort (18101)
|
|
166
|
-
let electronBinary = null;
|
|
167
|
-
try {
|
|
168
|
-
electronBinary = execSync('which electron 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
169
|
-
} catch {}
|
|
170
|
-
|
|
171
|
-
if (!electronBinary) {
|
|
172
|
-
console.log(' ⚠️ Electron not found. Installing...');
|
|
173
|
-
try {
|
|
174
|
-
execSync('npm install -g electron', { stdio: 'inherit' });
|
|
175
|
-
electronBinary = execSync('which electron', { encoding: 'utf8' }).trim();
|
|
176
|
-
} catch {
|
|
177
|
-
console.error(' ❌ Failed to install Electron. Install manually: npm install -g electron');
|
|
178
|
-
console.log(` 📱 Fallback: open browser → ${url}`);
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Find cicy-desktop package from the global install
|
|
184
|
-
let desktopDir = null;
|
|
185
|
-
|
|
186
|
-
// Check global 'cicy-desktop' package
|
|
187
|
-
try {
|
|
188
|
-
const cicyBin = execSync('which cicy 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
189
|
-
desktopDir = path.resolve(path.dirname(cicyBin), '..', 'lib', 'node_modules', 'cicy-desktop');
|
|
190
|
-
if (!fs.existsSync(path.join(desktopDir, 'src', 'main.js'))) desktopDir = null;
|
|
191
|
-
} catch {}
|
|
192
|
-
|
|
193
|
-
if (!desktopDir) {
|
|
194
|
-
console.log(' ⚠️ cicy-desktop not found. Installing...');
|
|
195
|
-
try {
|
|
196
|
-
execSync('npm install -g cicy-desktop', { stdio: 'inherit' });
|
|
197
|
-
const cicyBin = execSync('which cicy', { encoding: 'utf8' }).trim();
|
|
198
|
-
desktopDir = path.resolve(path.dirname(cicyBin), '..', 'lib', 'node_modules', 'cicy-desktop');
|
|
199
|
-
} catch {
|
|
200
|
-
console.error(' ❌ Failed to install cicy-desktop. Install manually: npm install -g cicy-desktop');
|
|
201
|
-
console.log(` 📱 Fallback: open browser → ${url}`);
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
console.log(` 🖥️ Opening desktop: ${url}`);
|
|
207
|
-
console.log(` 🔧 RPC/MCP server: http://127.0.0.1:${desktopPort}`);
|
|
208
|
-
|
|
209
|
-
const desktop = spawn(electronBinary, [desktopDir, `--url=${url}`, `--port=${desktopPort}`], {
|
|
210
|
-
stdio: 'inherit',
|
|
211
|
-
env: { ...process.env, PORT: String(desktopPort) }
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
desktop.on('exit', (code) => {
|
|
215
|
-
try { process.kill(server.pid); } catch {}
|
|
216
|
-
process.exit(code || 0);
|
|
217
|
-
});
|
|
218
|
-
}
|
|
26
|
+
// npm restores the 0755 mode from the tarball, but chmod defensively in case
|
|
27
|
+
// a mirror or extraction stripped the exec bit.
|
|
28
|
+
try { fs.chmodSync(binPath, 0o755); } catch {}
|
|
219
29
|
|
|
220
|
-
|
|
30
|
+
const child = spawn(binPath, process.argv.slice(2), { stdio: 'inherit', env: process.env });
|
|
31
|
+
child.on('exit', (code, signal) => {
|
|
32
|
+
if (signal) process.kill(process.pid, signal);
|
|
33
|
+
else process.exit(code == null ? 0 : code);
|
|
34
|
+
});
|
package/package.json
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cicy-code",
|
|
3
|
-
"
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "2.1.47",
|
|
4
7
|
"description": "CiCy Code - AI-powered development environment",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "cicybot",
|
|
10
|
+
"email": "support@cicy-ai.com"
|
|
11
|
+
},
|
|
5
12
|
"bin": {
|
|
6
13
|
"cicy-code": "bin/cicy-code.js"
|
|
7
14
|
},
|
|
8
|
-
"scripts": {
|
|
9
|
-
"postinstall": "node scripts/install.js"
|
|
10
|
-
},
|
|
11
15
|
"files": [
|
|
12
|
-
"bin/"
|
|
13
|
-
"scripts/"
|
|
16
|
+
"bin/cicy-code.js"
|
|
14
17
|
],
|
|
18
|
+
"optionalDependencies": {
|
|
19
|
+
"cicy-code-darwin-arm64": "2.1.47",
|
|
20
|
+
"cicy-code-darwin-x64": "2.1.47",
|
|
21
|
+
"cicy-code-linux-x64": "2.1.47",
|
|
22
|
+
"cicy-code-linux-arm64": "2.1.47"
|
|
23
|
+
},
|
|
15
24
|
"repository": {
|
|
16
25
|
"type": "git",
|
|
17
26
|
"url": "git+https://github.com/cicy-ai/cicy-code.git"
|
package/bin/cicy-code
DELETED
|
Binary file
|
package/scripts/install.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
const https = require('https');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
const VERSION = require('../package.json').version;
|
|
6
|
-
const GH_URL = `https://github.com/cicy-ai/cicy-code/releases/download/v${VERSION}`;
|
|
7
|
-
const CN_URL = `https://gh-proxy.com/https://github.com/cicy-ai/cicy-code/releases/download/v${VERSION}`;
|
|
8
|
-
|
|
9
|
-
const cn = process.env.CN_MIRROR === '1' || process.argv.includes('--cn');
|
|
10
|
-
const BASE_URL = cn ? CN_URL : GH_URL;
|
|
11
|
-
|
|
12
|
-
const PLATFORMS = {
|
|
13
|
-
'darwin-arm64': 'cicy-code-darwin-arm64',
|
|
14
|
-
'darwin-x64': 'cicy-code-darwin-amd64',
|
|
15
|
-
'linux-x64': 'cicy-code-linux-amd64',
|
|
16
|
-
'linux-arm64': 'cicy-code-linux-arm64',
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const key = `${process.platform}-${process.arch}`;
|
|
20
|
-
const binName = PLATFORMS[key];
|
|
21
|
-
|
|
22
|
-
if (!binName) {
|
|
23
|
-
if (process.platform === 'win32') {
|
|
24
|
-
console.error('Windows is not supported natively. Please use WSL:\n wsl --install\n wsl npx cicy-code');
|
|
25
|
-
} else {
|
|
26
|
-
console.error(`Unsupported platform: ${key}`);
|
|
27
|
-
}
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const binDir = path.join(__dirname, '..', 'bin');
|
|
32
|
-
const binPath = path.join(binDir, 'cicy-code');
|
|
33
|
-
const url = `${BASE_URL}/${binName}`;
|
|
34
|
-
|
|
35
|
-
console.log(`Downloading ${binName}${cn ? ' (CN mirror: gh-proxy.com)' : ''}...`);
|
|
36
|
-
console.log(` URL: ${url}`);
|
|
37
|
-
|
|
38
|
-
function download(url, dest, redirects = 5) {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
if (redirects === 0) return reject(new Error('Too many redirects'));
|
|
41
|
-
const proto = url.startsWith('https') ? https : require('http');
|
|
42
|
-
proto.get(url, (res) => {
|
|
43
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
44
|
-
return download(res.headers.location, dest, redirects - 1).then(resolve).catch(reject);
|
|
45
|
-
}
|
|
46
|
-
if (res.statusCode !== 200) return reject(new Error(`HTTP ${res.statusCode}`));
|
|
47
|
-
const file = fs.createWriteStream(dest);
|
|
48
|
-
res.pipe(file);
|
|
49
|
-
file.on('finish', () => { file.close(); fs.chmodSync(dest, 0o755); resolve(); });
|
|
50
|
-
}).on('error', reject);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
download(url, binPath)
|
|
55
|
-
.then(() => console.log('Done!'))
|
|
56
|
-
.catch((err) => {
|
|
57
|
-
console.error('Download failed:', err.message);
|
|
58
|
-
if (!cn) console.error('Try: CN_MIRROR=1 npx cicy-code');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
});
|