@anh3d0nic/qwen-code-termux-ice 16.0.4 → 16.0.7
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/qwen-ice +25 -5
- package/package.json +6 -5
- package/scripts/build.js +88 -0
- package/scripts/build_package.js +37 -0
- package/scripts/build_sandbox.js +174 -0
- package/scripts/build_vscode_companion.js +30 -0
- package/scripts/check-build-status.js +148 -0
- package/scripts/check-i18n.ts +462 -0
- package/scripts/check-lockfile.js +74 -0
- package/scripts/clean.js +59 -0
- package/scripts/copy_bundle_assets.js +90 -0
- package/scripts/copy_files.js +86 -0
- package/scripts/create_alias.sh +39 -0
- package/scripts/dev.js +109 -0
- package/scripts/esbuild-shims.js +29 -0
- package/scripts/generate-git-commit-info.js +71 -0
- package/scripts/generate-settings-schema.ts +146 -0
- package/scripts/get-release-version.js +411 -0
- package/scripts/ice-mobile.js +5 -0
- package/scripts/ice-session.js +6 -0
- package/scripts/ice-skills.js +31 -0
- package/scripts/ice-teams.js +34 -0
- package/scripts/ice-v10.js +276 -0
- package/scripts/ice-v11.js +276 -0
- package/scripts/ice-v12.js +568 -0
- package/scripts/ice-v13.js +824 -0
- package/scripts/ice-v14.js +1059 -0
- package/scripts/ice-v15.js +1501 -0
- package/scripts/ice-v2.js +26 -0
- package/scripts/ice-v3-core.js +261 -0
- package/scripts/ice-v3.js +46 -0
- package/scripts/ice-v4.js +657 -0
- package/scripts/ice-v5.js +371 -0
- package/scripts/ice-v6.js +305 -0
- package/scripts/ice-v7.js +291 -0
- package/scripts/ice-v8.js +550 -0
- package/scripts/ice-v9.js +546 -0
- package/scripts/install-ice.sh +70 -0
- package/scripts/install.sh +136 -0
- package/scripts/installation/INSTALLATION_GUIDE.md +250 -0
- package/scripts/installation/install-qwen-with-source.bat +302 -0
- package/scripts/installation/install-qwen-with-source.sh +570 -0
- package/scripts/lint.js +205 -0
- package/scripts/local_telemetry.js +219 -0
- package/scripts/postinstall.cjs +235 -0
- package/scripts/pre-commit.js +22 -0
- package/scripts/prepare-package.js +186 -0
- package/scripts/prepare-termux.cjs +26 -0
- package/scripts/sandbox_command.js +128 -0
- package/scripts/start.js +86 -0
- package/scripts/telemetry.js +85 -0
- package/scripts/telemetry_gcp.js +188 -0
- package/scripts/telemetry_utils.js +450 -0
- package/scripts/test-v10.js +18 -0
- package/scripts/test-v11.js +18 -0
- package/scripts/test-v12.js +18 -0
- package/scripts/test-v13.js +18 -0
- package/scripts/test-v14.js +18 -0
- package/scripts/test-v3.js +47 -0
- package/scripts/test-v4.js +47 -0
- package/scripts/test-v6.js +59 -0
- package/scripts/test-v8.js +42 -0
- package/scripts/test-v9.js +18 -0
- package/scripts/test-windows-paths.js +51 -0
- package/scripts/tests/get-release-version.test.js +186 -0
- package/scripts/tests/test-setup.ts +12 -0
- package/scripts/tests/vitest.config.ts +26 -0
- package/scripts/unused-keys-only-in-locales.json +62 -0
- package/scripts/version.js +112 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright 2025 Google LLC
|
|
6
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import net from 'node:net';
|
|
12
|
+
import os from 'node:os';
|
|
13
|
+
import { spawnSync } from 'node:child_process';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import crypto from 'node:crypto';
|
|
16
|
+
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = path.dirname(__filename);
|
|
19
|
+
|
|
20
|
+
const projectRoot = path.resolve(__dirname, '..');
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generates a unique hash for a project based on its root path.
|
|
24
|
+
* On Windows, paths are case-insensitive, so we normalize to lowercase
|
|
25
|
+
* to ensure the same physical path always produces the same hash.
|
|
26
|
+
* This logic must match getProjectHash() in packages/core/src/utils/paths.ts
|
|
27
|
+
*/
|
|
28
|
+
function getProjectHash(projectRoot) {
|
|
29
|
+
// On Windows, normalize path to lowercase for case-insensitive matching
|
|
30
|
+
const normalizedPath =
|
|
31
|
+
os.platform() === 'win32' ? projectRoot.toLowerCase() : projectRoot;
|
|
32
|
+
return crypto.createHash('sha256').update(normalizedPath).digest('hex');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const projectHash = getProjectHash(projectRoot);
|
|
36
|
+
|
|
37
|
+
// User-level .gemini directory in home
|
|
38
|
+
const USER_GEMINI_DIR = path.join(os.homedir(), '.qwen');
|
|
39
|
+
// Project-level .gemini directory in the workspace
|
|
40
|
+
const WORKSPACE_QWEN_DIR = path.join(projectRoot, '.qwen');
|
|
41
|
+
|
|
42
|
+
// Telemetry artifacts are stored in a hashed directory under the user's ~/.qwen/tmp
|
|
43
|
+
export const OTEL_DIR = path.join(USER_GEMINI_DIR, 'tmp', projectHash, 'otel');
|
|
44
|
+
export const BIN_DIR = path.join(OTEL_DIR, 'bin');
|
|
45
|
+
|
|
46
|
+
// Workspace settings remain in the project's .gemini directory
|
|
47
|
+
export const WORKSPACE_SETTINGS_FILE = path.join(
|
|
48
|
+
WORKSPACE_QWEN_DIR,
|
|
49
|
+
'settings.json',
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
export function getJson(url) {
|
|
53
|
+
const tmpFile = path.join(
|
|
54
|
+
os.tmpdir(),
|
|
55
|
+
`qwen-code-releases-${Date.now()}.json`,
|
|
56
|
+
);
|
|
57
|
+
try {
|
|
58
|
+
const result = spawnSync(
|
|
59
|
+
'curl',
|
|
60
|
+
['-sL', '-H', 'User-Agent: qwen-code-dev-script', '-o', tmpFile, url],
|
|
61
|
+
{ stdio: 'pipe', encoding: 'utf-8' },
|
|
62
|
+
);
|
|
63
|
+
if (result.status !== 0) {
|
|
64
|
+
throw new Error(result.stderr);
|
|
65
|
+
}
|
|
66
|
+
const content = fs.readFileSync(tmpFile, 'utf-8');
|
|
67
|
+
return JSON.parse(content);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
console.error(`Failed to fetch or parse JSON from ${url}`);
|
|
70
|
+
throw e;
|
|
71
|
+
} finally {
|
|
72
|
+
if (fs.existsSync(tmpFile)) {
|
|
73
|
+
fs.unlinkSync(tmpFile);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function downloadFile(url, dest) {
|
|
79
|
+
try {
|
|
80
|
+
const result = spawnSync('curl', ['-fL', '-sS', '-o', dest, url], {
|
|
81
|
+
stdio: 'pipe',
|
|
82
|
+
encoding: 'utf-8',
|
|
83
|
+
});
|
|
84
|
+
if (result.status !== 0) {
|
|
85
|
+
throw new Error(result.stderr);
|
|
86
|
+
}
|
|
87
|
+
return dest;
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.error(`Failed to download file from ${url}`);
|
|
90
|
+
throw e;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function findFile(startPath, filter) {
|
|
95
|
+
if (!fs.existsSync(startPath)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const files = fs.readdirSync(startPath);
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
const filename = path.join(startPath, file);
|
|
101
|
+
const stat = fs.lstatSync(filename);
|
|
102
|
+
if (stat.isDirectory()) {
|
|
103
|
+
const result = findFile(filename, filter);
|
|
104
|
+
if (result) return result;
|
|
105
|
+
} else if (filter(file)) {
|
|
106
|
+
return filename;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function fileExists(filePath) {
|
|
113
|
+
return fs.existsSync(filePath);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function readJsonFile(filePath) {
|
|
117
|
+
if (!fileExists(filePath)) {
|
|
118
|
+
return {};
|
|
119
|
+
}
|
|
120
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
121
|
+
try {
|
|
122
|
+
return JSON.parse(content);
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.error(`Error parsing JSON from ${filePath}: ${e.message}`);
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function writeJsonFile(filePath, data) {
|
|
130
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function moveBinary(source, destination) {
|
|
134
|
+
try {
|
|
135
|
+
fs.renameSync(source, destination);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (error.code !== 'EXDEV') {
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
// Handle a cross-device error: copy-to-temp-then-rename.
|
|
141
|
+
const destDir = path.dirname(destination);
|
|
142
|
+
const destFile = path.basename(destination);
|
|
143
|
+
const tempDest = path.join(destDir, `${destFile}.tmp`);
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
fs.copyFileSync(source, tempDest);
|
|
147
|
+
fs.renameSync(tempDest, destination);
|
|
148
|
+
} catch (moveError) {
|
|
149
|
+
// If copy or rename fails, clean up the intermediate temp file.
|
|
150
|
+
if (fs.existsSync(tempDest)) {
|
|
151
|
+
fs.unlinkSync(tempDest);
|
|
152
|
+
}
|
|
153
|
+
throw moveError;
|
|
154
|
+
}
|
|
155
|
+
fs.unlinkSync(source);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function waitForPort(port, timeout = 10000) {
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
const startTime = Date.now();
|
|
162
|
+
const tryConnect = () => {
|
|
163
|
+
const socket = new net.Socket();
|
|
164
|
+
socket.once('connect', () => {
|
|
165
|
+
socket.end();
|
|
166
|
+
resolve();
|
|
167
|
+
});
|
|
168
|
+
socket.once('error', (_) => {
|
|
169
|
+
if (Date.now() - startTime > timeout) {
|
|
170
|
+
reject(new Error(`Timeout waiting for port ${port} to open.`));
|
|
171
|
+
} else {
|
|
172
|
+
setTimeout(tryConnect, 500);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
socket.connect(port, 'localhost');
|
|
176
|
+
};
|
|
177
|
+
tryConnect();
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export async function ensureBinary(
|
|
182
|
+
executableName,
|
|
183
|
+
repo,
|
|
184
|
+
assetNameCallback,
|
|
185
|
+
binaryNameInArchive,
|
|
186
|
+
isJaeger = false,
|
|
187
|
+
) {
|
|
188
|
+
const executablePath = path.join(BIN_DIR, executableName);
|
|
189
|
+
if (fileExists(executablePath)) {
|
|
190
|
+
console.log(`✅ ${executableName} already exists at ${executablePath}`);
|
|
191
|
+
return executablePath;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
console.log(`🔍 ${executableName} not found. Downloading from ${repo}...`);
|
|
195
|
+
|
|
196
|
+
const platform = process.platform === 'win32' ? 'windows' : process.platform;
|
|
197
|
+
const arch = process.arch === 'x64' ? 'amd64' : process.arch;
|
|
198
|
+
const ext = platform === 'windows' ? 'zip' : 'tar.gz';
|
|
199
|
+
|
|
200
|
+
if (isJaeger && platform === 'windows' && arch === 'arm64') {
|
|
201
|
+
console.warn(
|
|
202
|
+
`⚠️ Jaeger does not have a release for Windows on ARM64. Skipping.`,
|
|
203
|
+
);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let release;
|
|
208
|
+
let asset;
|
|
209
|
+
|
|
210
|
+
if (isJaeger) {
|
|
211
|
+
console.log(`🔍 Finding latest Jaeger v2+ asset...`);
|
|
212
|
+
const releases = getJson(`https://api.github.com/repos/${repo}/releases`);
|
|
213
|
+
const sortedReleases = releases
|
|
214
|
+
.filter((r) => !r.prerelease && r.tag_name.startsWith('v'))
|
|
215
|
+
.sort((a, b) => {
|
|
216
|
+
const aVersion = a.tag_name.substring(1).split('.').map(Number);
|
|
217
|
+
const bVersion = b.tag_name.substring(1).split('.').map(Number);
|
|
218
|
+
for (let i = 0; i < Math.max(aVersion.length, bVersion.length); i++) {
|
|
219
|
+
if ((aVersion[i] || 0) > (bVersion[i] || 0)) return -1;
|
|
220
|
+
if ((aVersion[i] || 0) < (bVersion[i] || 0)) return 1;
|
|
221
|
+
}
|
|
222
|
+
return 0;
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
for (const r of sortedReleases) {
|
|
226
|
+
const expectedSuffix =
|
|
227
|
+
platform === 'windows'
|
|
228
|
+
? `-${platform}-${arch}.zip`
|
|
229
|
+
: `-${platform}-${arch}.tar.gz`;
|
|
230
|
+
const foundAsset = r.assets.find(
|
|
231
|
+
(a) =>
|
|
232
|
+
a.name.startsWith('jaeger-2.') && a.name.endsWith(expectedSuffix),
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
if (foundAsset) {
|
|
236
|
+
release = r;
|
|
237
|
+
asset = foundAsset;
|
|
238
|
+
console.log(
|
|
239
|
+
`⬇️ Found ${asset.name} in release ${r.tag_name}, downloading...`,
|
|
240
|
+
);
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (!asset) {
|
|
245
|
+
throw new Error(
|
|
246
|
+
`Could not find a suitable Jaeger v2 asset for platform ${platform}/${arch}.`,
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
} else {
|
|
250
|
+
release = getJson(`https://api.github.com/repos/${repo}/releases/latest`);
|
|
251
|
+
const version = release.tag_name.startsWith('v')
|
|
252
|
+
? release.tag_name.substring(1)
|
|
253
|
+
: release.tag_name;
|
|
254
|
+
const assetName = assetNameCallback(version, platform, arch, ext);
|
|
255
|
+
asset = release.assets.find((a) => a.name === assetName);
|
|
256
|
+
if (!asset) {
|
|
257
|
+
throw new Error(
|
|
258
|
+
`Could not find a suitable asset for ${repo} (version ${version}) on platform ${platform}/${arch}. Searched for: ${assetName}`,
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const downloadUrl = asset.browser_download_url;
|
|
264
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'qwen-code-telemetry-'));
|
|
265
|
+
const archivePath = path.join(tmpDir, asset.name);
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
console.log(`⬇️ Downloading ${asset.name}...`);
|
|
269
|
+
downloadFile(downloadUrl, archivePath);
|
|
270
|
+
console.log(`📦 Extracting ${asset.name}...`);
|
|
271
|
+
|
|
272
|
+
const actualExt = asset.name.endsWith('.zip') ? 'zip' : 'tar.gz';
|
|
273
|
+
|
|
274
|
+
let result;
|
|
275
|
+
if (actualExt === 'zip') {
|
|
276
|
+
result = spawnSync('unzip', ['-o', archivePath, '-d', tmpDir], {
|
|
277
|
+
stdio: 'pipe',
|
|
278
|
+
encoding: 'utf-8',
|
|
279
|
+
});
|
|
280
|
+
} else {
|
|
281
|
+
result = spawnSync('tar', ['-xzf', archivePath, '-C', tmpDir], {
|
|
282
|
+
stdio: 'pipe',
|
|
283
|
+
encoding: 'utf-8',
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
if (result.status !== 0) {
|
|
287
|
+
throw new Error(result.stderr);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const nameToFind = binaryNameInArchive || executableName;
|
|
291
|
+
const foundBinaryPath = findFile(tmpDir, (file) => {
|
|
292
|
+
if (platform === 'windows') {
|
|
293
|
+
return file === `${nameToFind}.exe`;
|
|
294
|
+
}
|
|
295
|
+
return file === nameToFind;
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
if (!foundBinaryPath) {
|
|
299
|
+
throw new Error(
|
|
300
|
+
`Could not find binary "${nameToFind}" in extracted archive at ${tmpDir}. Contents: ${fs.readdirSync(tmpDir).join(', ')}`,
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
moveBinary(foundBinaryPath, executablePath);
|
|
305
|
+
|
|
306
|
+
if (platform !== 'windows') {
|
|
307
|
+
fs.chmodSync(executablePath, '755');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
console.log(`✅ ${executableName} installed at ${executablePath}`);
|
|
311
|
+
return executablePath;
|
|
312
|
+
} finally {
|
|
313
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
314
|
+
if (fs.existsSync(archivePath)) {
|
|
315
|
+
fs.unlinkSync(archivePath);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export function manageTelemetrySettings(
|
|
321
|
+
enable,
|
|
322
|
+
oTelEndpoint = 'http://localhost:4317',
|
|
323
|
+
target = 'local',
|
|
324
|
+
originalSandboxSettingToRestore,
|
|
325
|
+
) {
|
|
326
|
+
const workspaceSettings = readJsonFile(WORKSPACE_SETTINGS_FILE);
|
|
327
|
+
const currentSandboxSetting = workspaceSettings.sandbox;
|
|
328
|
+
let settingsModified = false;
|
|
329
|
+
|
|
330
|
+
if (typeof workspaceSettings.telemetry !== 'object') {
|
|
331
|
+
workspaceSettings.telemetry = {};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (enable) {
|
|
335
|
+
if (workspaceSettings.telemetry.enabled !== true) {
|
|
336
|
+
workspaceSettings.telemetry.enabled = true;
|
|
337
|
+
settingsModified = true;
|
|
338
|
+
console.log('⚙️ Enabled telemetry in workspace settings.');
|
|
339
|
+
}
|
|
340
|
+
if (workspaceSettings.sandbox !== false) {
|
|
341
|
+
workspaceSettings.sandbox = false;
|
|
342
|
+
settingsModified = true;
|
|
343
|
+
console.log('✅ Disabled sandbox mode for telemetry.');
|
|
344
|
+
}
|
|
345
|
+
if (workspaceSettings.telemetry.otlpEndpoint !== oTelEndpoint) {
|
|
346
|
+
workspaceSettings.telemetry.otlpEndpoint = oTelEndpoint;
|
|
347
|
+
settingsModified = true;
|
|
348
|
+
console.log(`🔧 Set telemetry OTLP endpoint to ${oTelEndpoint}.`);
|
|
349
|
+
}
|
|
350
|
+
if (workspaceSettings.telemetry.target !== target) {
|
|
351
|
+
workspaceSettings.telemetry.target = target;
|
|
352
|
+
settingsModified = true;
|
|
353
|
+
console.log(`🎯 Set telemetry target to ${target}.`);
|
|
354
|
+
}
|
|
355
|
+
} else {
|
|
356
|
+
if (workspaceSettings.telemetry.enabled === true) {
|
|
357
|
+
delete workspaceSettings.telemetry.enabled;
|
|
358
|
+
settingsModified = true;
|
|
359
|
+
console.log('⚙️ Disabled telemetry in workspace settings.');
|
|
360
|
+
}
|
|
361
|
+
if (workspaceSettings.telemetry.otlpEndpoint) {
|
|
362
|
+
delete workspaceSettings.telemetry.otlpEndpoint;
|
|
363
|
+
settingsModified = true;
|
|
364
|
+
console.log('🔧 Cleared telemetry OTLP endpoint.');
|
|
365
|
+
}
|
|
366
|
+
if (workspaceSettings.telemetry.target) {
|
|
367
|
+
delete workspaceSettings.telemetry.target;
|
|
368
|
+
settingsModified = true;
|
|
369
|
+
console.log('🎯 Cleared telemetry target.');
|
|
370
|
+
}
|
|
371
|
+
if (Object.keys(workspaceSettings.telemetry).length === 0) {
|
|
372
|
+
delete workspaceSettings.telemetry;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (
|
|
376
|
+
originalSandboxSettingToRestore !== undefined &&
|
|
377
|
+
workspaceSettings.sandbox !== originalSandboxSettingToRestore
|
|
378
|
+
) {
|
|
379
|
+
workspaceSettings.sandbox = originalSandboxSettingToRestore;
|
|
380
|
+
settingsModified = true;
|
|
381
|
+
console.log('✅ Restored original sandbox setting.');
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (settingsModified) {
|
|
386
|
+
writeJsonFile(WORKSPACE_SETTINGS_FILE, workspaceSettings);
|
|
387
|
+
console.log('✅ Workspace settings updated.');
|
|
388
|
+
} else {
|
|
389
|
+
console.log(
|
|
390
|
+
enable
|
|
391
|
+
? '✅ Workspace settings are already configured for telemetry.'
|
|
392
|
+
: '✅ Workspace settings already reflect telemetry disabled.',
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
return currentSandboxSetting;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
export function registerCleanup(
|
|
399
|
+
getProcesses,
|
|
400
|
+
getLogFileDescriptors,
|
|
401
|
+
originalSandboxSetting,
|
|
402
|
+
) {
|
|
403
|
+
let cleanedUp = false;
|
|
404
|
+
const cleanup = () => {
|
|
405
|
+
if (cleanedUp) return;
|
|
406
|
+
cleanedUp = true;
|
|
407
|
+
|
|
408
|
+
console.log('\n👋 Shutting down...');
|
|
409
|
+
|
|
410
|
+
manageTelemetrySettings(false, null, originalSandboxSetting);
|
|
411
|
+
|
|
412
|
+
const processes = getProcesses ? getProcesses() : [];
|
|
413
|
+
processes.forEach((proc) => {
|
|
414
|
+
if (proc && proc.pid) {
|
|
415
|
+
const name = path.basename(proc.spawnfile);
|
|
416
|
+
try {
|
|
417
|
+
console.log(`🛑 Stopping ${name} (PID: ${proc.pid})...`);
|
|
418
|
+
process.kill(proc.pid, 'SIGTERM');
|
|
419
|
+
console.log(`✅ ${name} stopped.`);
|
|
420
|
+
} catch (e) {
|
|
421
|
+
if (e.code !== 'ESRCH') {
|
|
422
|
+
console.error(`Error stopping ${name}: ${e.message}`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
const logFileDescriptors = getLogFileDescriptors
|
|
429
|
+
? getLogFileDescriptors()
|
|
430
|
+
: [];
|
|
431
|
+
logFileDescriptors.forEach((fd) => {
|
|
432
|
+
if (fd) {
|
|
433
|
+
try {
|
|
434
|
+
fs.closeSync(fd);
|
|
435
|
+
} catch (_) {
|
|
436
|
+
/* no-op */
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
process.on('exit', cleanup);
|
|
443
|
+
process.on('SIGINT', () => process.exit(0));
|
|
444
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
445
|
+
process.on('uncaughtException', (err) => {
|
|
446
|
+
console.error('Uncaught Exception:', err);
|
|
447
|
+
cleanup();
|
|
448
|
+
process.exit(1);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
console.log('❄️ ICE v10.0.0 Test Suite\n'); console.log('='.repeat(60));
|
|
4
|
+
const tests = [
|
|
5
|
+
{ name: 'BUG FIX 1: IntentLadder deep intent', cmd: 'node scripts/ice-v10.js ladder "fix this error"' },
|
|
6
|
+
{ name: 'BUG FIX 2: ConfidenceGating learns', cmd: 'node scripts/ice-v10.js confidence "test"' },
|
|
7
|
+
{ name: 'BUG FIX 3: DomainMemory persists', cmd: 'node scripts/ice-v10.js memory show' },
|
|
8
|
+
{ name: 'NEW: Parallel Task Splitter', cmd: 'node scripts/ice-v10.js parallel "build login page"' },
|
|
9
|
+
{ name: 'Self-Critique Loop', cmd: 'node scripts/ice-v10.js critique "function test() { return 1; }"' },
|
|
10
|
+
{ name: 'Adversarial Testing', cmd: 'node scripts/ice-v10.js adversarial "function test(x) { return x; }"' },
|
|
11
|
+
{ name: 'Termux Specialist', cmd: 'node scripts/ice-v10.js termux "sudo apt-get install python"' },
|
|
12
|
+
{ name: 'Context-Aware Val', cmd: 'node scripts/ice-v10.js validate "prisma.user.findUnique()"' },
|
|
13
|
+
{ name: 'Pushback Mode', cmd: 'node scripts/ice-v10.js pushback "SELECT * + userId"' },
|
|
14
|
+
{ name: 'Four-Layer Val', cmd: 'node scripts/ice-v10.js layers "function test() {}"' }
|
|
15
|
+
];
|
|
16
|
+
let passed = 0, failed = 0;
|
|
17
|
+
tests.forEach((t, i) => { console.log(`\nTest ${i + 1}: ${t.name}`); console.log('-'.repeat(60)); try { execSync(t.cmd, { stdio: 'inherit' }); console.log('✅ PASS\n'); passed++; } catch (e) { console.log('❌ FAIL\n'); failed++; } }
|
|
18
|
+
console.log('='.repeat(60)); console.log(`\nResults: ${passed}/${tests.length} passed\n`); process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
console.log('❄️ ICE v10.0.0 Test Suite\n'); console.log('='.repeat(60));
|
|
4
|
+
const tests = [
|
|
5
|
+
{ name: 'BUG FIX 1: IntentLadder deep intent', cmd: 'node scripts/ice-v10.js ladder "fix this error"' },
|
|
6
|
+
{ name: 'BUG FIX 2: ConfidenceGating learns', cmd: 'node scripts/ice-v10.js confidence "test"' },
|
|
7
|
+
{ name: 'BUG FIX 3: DomainMemory persists', cmd: 'node scripts/ice-v10.js memory show' },
|
|
8
|
+
{ name: 'NEW: Parallel Task Splitter', cmd: 'node scripts/ice-v10.js parallel "build login page"' },
|
|
9
|
+
{ name: 'Self-Critique Loop', cmd: 'node scripts/ice-v10.js critique "function test() { return 1; }"' },
|
|
10
|
+
{ name: 'Adversarial Testing', cmd: 'node scripts/ice-v10.js adversarial "function test(x) { return x; }"' },
|
|
11
|
+
{ name: 'Termux Specialist', cmd: 'node scripts/ice-v10.js termux "sudo apt-get install python"' },
|
|
12
|
+
{ name: 'Context-Aware Val', cmd: 'node scripts/ice-v10.js validate "prisma.user.findUnique()"' },
|
|
13
|
+
{ name: 'Pushback Mode', cmd: 'node scripts/ice-v10.js pushback "SELECT * + userId"' },
|
|
14
|
+
{ name: 'Four-Layer Val', cmd: 'node scripts/ice-v10.js layers "function test() {}"' }
|
|
15
|
+
];
|
|
16
|
+
let passed = 0, failed = 0;
|
|
17
|
+
tests.forEach((t, i) => { console.log(`\nTest ${i + 1}: ${t.name}`); console.log('-'.repeat(60)); try { execSync(t.cmd, { stdio: 'inherit' }); console.log('✅ PASS\n'); passed++; } catch (e) { console.log('❌ FAIL\n'); failed++; } }
|
|
18
|
+
console.log('='.repeat(60)); console.log(`\nResults: ${passed}/${tests.length} passed\n`); process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
console.log('❄️ ICE v12.0.0 Test Suite - Unified Pipeline\n'); console.log('='.repeat(60));
|
|
4
|
+
const tests = [
|
|
5
|
+
{ name: 'Unified Pipeline (sudo fix)', cmd: 'node scripts/ice-v12.js "fix sudo error"' },
|
|
6
|
+
{ name: 'Unified Pipeline (function)', cmd: 'node scripts/ice-v12.js "create function"' },
|
|
7
|
+
{ name: 'Intent Ladder (deep intent)', cmd: 'node scripts/ice-v12.js "debug this issue"' },
|
|
8
|
+
{ name: 'Self-Critique (7 questions)', cmd: 'node scripts/ice-v12.js "sudo apt install python"' },
|
|
9
|
+
{ name: 'Auto-Run Loop', cmd: 'node scripts/ice-v12.js "run echo test"' },
|
|
10
|
+
{ name: 'Domain Memory', cmd: 'node scripts/ice-v12.js init' },
|
|
11
|
+
{ name: 'Parallel Task Splitter', cmd: 'node scripts/ice-v12.js parallel "build login page"' },
|
|
12
|
+
{ name: 'Confidence Gating', cmd: 'node scripts/ice-v12.js "maybe help"' },
|
|
13
|
+
{ name: 'Termux Specialist', cmd: 'node scripts/ice-v12.js "systemctl restart"' },
|
|
14
|
+
{ name: 'Code Quality Gate', cmd: 'node scripts/ice-v12.js "function test() {}"' }
|
|
15
|
+
];
|
|
16
|
+
let passed = 0, failed = 0;
|
|
17
|
+
tests.forEach((t, i) => { console.log(`\nTest ${i + 1}: ${t.name}`); console.log('-'.repeat(60)); try { execSync(t.cmd, { stdio: 'inherit', timeout: 30000 }); console.log('✅ PASS\n'); passed++; } catch (e) { console.log('❌ FAIL\n'); failed++; } }
|
|
18
|
+
console.log('='.repeat(60)); console.log(`\nResults: ${passed}/${tests.length} passed\n`); process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
console.log('❄️ ICE v13.0.0 Test Suite - Self-Improving Intelligence\n'); console.log('='.repeat(60));
|
|
4
|
+
const tests = [
|
|
5
|
+
{ name: 'BUG FIX 1: Auto-Run (exit code 0)', cmd: 'node scripts/ice-v13.js "run echo test"' },
|
|
6
|
+
{ name: 'BUG FIX 2: Confidence learns', cmd: 'node scripts/ice-v13.js "maybe help"' },
|
|
7
|
+
{ name: 'Pattern Learning Engine', cmd: 'node scripts/ice-v13.js "sudo install"' },
|
|
8
|
+
{ name: 'Quality Scorer', cmd: 'node scripts/ice-v13.js "create function"' },
|
|
9
|
+
{ name: 'Smart Context', cmd: 'node scripts/ice-v13.js "test context"' },
|
|
10
|
+
{ name: 'Unified Pipeline', cmd: 'node scripts/ice-v13.js "debug issue"' },
|
|
11
|
+
{ name: 'Parallel Task Splitter', cmd: 'node scripts/ice-v13.js parallel "build login"' },
|
|
12
|
+
{ name: 'Self-Critique (7 questions)', cmd: 'node scripts/ice-v13.js "apt install"' },
|
|
13
|
+
{ name: 'Domain Memory', cmd: 'node scripts/ice-v13.js init' },
|
|
14
|
+
{ name: 'Termux Specialist', cmd: 'node scripts/ice-v13.js "systemctl restart"' }
|
|
15
|
+
];
|
|
16
|
+
let passed = 0, failed = 0;
|
|
17
|
+
tests.forEach((t, i) => { console.log(`\nTest ${i + 1}: ${t.name}`); console.log('-'.repeat(60)); try { execSync(t.cmd, { stdio: 'inherit', timeout: 30000 }); console.log('✅ PASS\n'); passed++; } catch (e) { console.log('❌ FAIL\n'); failed++; } }
|
|
18
|
+
console.log('='.repeat(60)); console.log(`\nResults: ${passed}/${tests.length} passed\n`); process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
console.log('❄️ ICE v14.0.0 Test Suite - Verification + Hardening\n'); console.log('='.repeat(60));
|
|
4
|
+
const tests = [
|
|
5
|
+
{ name: 'CHECK 1: PatternLearning READ/WRITE', cmd: 'grep -n "user_patterns" scripts/ice-v14.js' },
|
|
6
|
+
{ name: 'CHECK 2: QualityScorer SAVE', cmd: 'grep -n "quality_history\\|QUALITY_FILE" scripts/ice-v14.js || echo "FAIL: No quality_history found"' },
|
|
7
|
+
{ name: 'CHECK 3: SmartContext COMPRESS', cmd: 'grep -n "slice.*-3\\|compress" scripts/ice-v14.js | head -5' },
|
|
8
|
+
{ name: 'CHECK 4: Confidence THRESHOLDS', cmd: 'grep -n "adjustThresholds\\|CERTAIN\\|LIKELY" scripts/ice-v14.js | head -5' },
|
|
9
|
+
{ name: 'UPGRADE 1: PatternPreventer', cmd: 'grep -n "PatternPreventer\\|preventErrors" scripts/ice-v14.js' },
|
|
10
|
+
{ name: 'UPGRADE 2: QualityBlocker', cmd: 'grep -n "QualityBlocker\\|blockAndRegenerate" scripts/ice-v14.js' },
|
|
11
|
+
{ name: 'UPGRADE 3: SessionSummary', cmd: 'grep -n "SessionSummary\\|session_summary" scripts/ice-v14.js' },
|
|
12
|
+
{ name: 'UPGRADE 4: ColdStartIntelligence', cmd: 'grep -n "ColdStartIntelligence\\|printWelcome" scripts/ice-v14.js' },
|
|
13
|
+
{ name: 'Pipeline Integration', cmd: 'node scripts/ice-v14.js "test"' },
|
|
14
|
+
{ name: 'Pattern Prevention', cmd: 'node scripts/ice-v14.js "sudo install python"' }
|
|
15
|
+
];
|
|
16
|
+
let passed = 0, failed = 0;
|
|
17
|
+
tests.forEach((t, i) => { console.log(`\nTest ${i + 1}: ${t.name}`); console.log('-'.repeat(60)); try { execSync(t.cmd, { stdio: 'inherit', timeout: 30000 }); console.log('✅ PASS\n'); passed++; } catch (e) { console.log('❌ FAIL\n'); failed++; } }
|
|
18
|
+
console.log('='.repeat(60)); console.log(`\nResults: ${passed}/${tests.length} passed\n`); process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ICE v3.0 Test Suite
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
|
|
9
|
+
console.log('❄️ ICE v3.0 Test Suite\\n');
|
|
10
|
+
console.log('=' .repeat(60));
|
|
11
|
+
|
|
12
|
+
const tests = [
|
|
13
|
+
{
|
|
14
|
+
name: 'Thinking Partner',
|
|
15
|
+
command: 'node scripts/ice-v3.js thinking "Test problem"'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Security Validation (SQL Injection)',
|
|
19
|
+
command: 'node scripts/ice-v3.js validate "def login(user): query = \'SELECT * FROM users WHERE id = \' + user"'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'Technical Debt Detection',
|
|
23
|
+
command: 'node scripts/ice-v3.js debt "class God: def a(): pass; def b(): pass"'
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
let passed = 0;
|
|
28
|
+
let failed = 0;
|
|
29
|
+
|
|
30
|
+
tests.forEach((test, i) => {
|
|
31
|
+
console.log(`\\nTest ${i + 1}: ${test.name}`);
|
|
32
|
+
console.log('-'.repeat(60));
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
execSync(test.command, { stdio: 'inherit' });
|
|
36
|
+
console.log(`✅ PASS\\n`);
|
|
37
|
+
passed++;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.log(`❌ FAIL\\n`);
|
|
40
|
+
failed++;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
console.log('=' .repeat(60));
|
|
45
|
+
console.log(`\\nResults: ${passed} passed, ${failed} failed\\n`);
|
|
46
|
+
|
|
47
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ICE v4.0 Test Suite
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
|
|
9
|
+
console.log('❄️ ICE v4.0 Test Suite\\n');
|
|
10
|
+
console.log('=' .repeat(60));
|
|
11
|
+
|
|
12
|
+
const tests = [
|
|
13
|
+
{
|
|
14
|
+
name: 'Enhanced Validation (50 rules)',
|
|
15
|
+
command: 'node scripts/ice-v4.js validate "def login(user): query = \'SELECT * FROM users WHERE id = \' + user"'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Feedback System',
|
|
19
|
+
command: 'node scripts/ice-v4.js feedback --stats'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'Multi-Model Voting',
|
|
23
|
+
command: 'node scripts/ice-v4.js vote "test code"'
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
let passed = 0;
|
|
28
|
+
let failed = 0;
|
|
29
|
+
|
|
30
|
+
tests.forEach((test, i) => {
|
|
31
|
+
console.log(`\\nTest ${i + 1}: ${test.name}`);
|
|
32
|
+
console.log('-'.repeat(60));
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
execSync(test.command, { stdio: 'inherit' });
|
|
36
|
+
console.log(`✅ PASS\\n`);
|
|
37
|
+
passed++;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.log(`❌ FAIL\\n`);
|
|
40
|
+
failed++;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
console.log('=' .repeat(60));
|
|
45
|
+
console.log(`\\nResults: ${passed} passed, ${failed} failed\\n`);
|
|
46
|
+
|
|
47
|
+
process.exit(failed > 0 ? 1 : 0);
|