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 CHANGED
@@ -1,220 +1,34 @@
1
1
  #!/usr/bin/env node
2
- const { spawn, execSync } = require('child_process');
3
- const path = require('path');
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 pkg = require('../package.json');
8
- const binPath = path.join(__dirname, 'cicy-code');
9
- const os = require('os');
10
- const CICY_ROOT_DIR = path.join(os.homedir(), 'cicy-ai');
11
- const CICY_GLOBAL_JSON_PATH = path.join(CICY_ROOT_DIR, 'global.json');
12
-
13
- const cn = process.argv.includes('--cn') || process.env.CN_MIRROR === '1';
14
- const desktopMode = process.argv.includes('--desktop');
15
-
16
- if (process.argv.includes('--cn')) {
17
- process.env.CN_MIRROR = '1';
18
- }
19
-
20
- if (cn) {
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
- function waitForServer(port, timeout) {
113
- const http = require('http');
114
- const start = Date.now();
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
- main();
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
- "version": "2.0.1",
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
@@ -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
- });