@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
package/bin/qwen-ice
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/data/data/com.termux/files/usr/bin/node
|
|
2
2
|
/**
|
|
3
|
-
* ❄️ Qwen Code ICE v16.0.
|
|
3
|
+
* ❄️ Qwen Code ICE v16.0.6 — Main Binary
|
|
4
|
+
* Fixed: Auto-runs postinstall if core dir missing on fresh install
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const fs = require('fs');
|
|
@@ -8,8 +9,8 @@ const path = require('path');
|
|
|
8
9
|
const readline = require('readline');
|
|
9
10
|
const { spawn } = require('child_process');
|
|
10
11
|
|
|
11
|
-
const VERSION = '16.0.
|
|
12
|
-
const INSTALL_DIR = '
|
|
12
|
+
const VERSION = '16.0.6';
|
|
13
|
+
const INSTALL_DIR = process.env.HOME + '/.qwen-ice';
|
|
13
14
|
const CONFIG_DIR = path.join(INSTALL_DIR, 'config');
|
|
14
15
|
const MEMORY_DIR = path.join(INSTALL_DIR, 'memory');
|
|
15
16
|
const LOGS_DIR = path.join(INSTALL_DIR, 'logs');
|
|
@@ -280,11 +281,30 @@ function printColdStart() {
|
|
|
280
281
|
}
|
|
281
282
|
}
|
|
282
283
|
|
|
284
|
+
function getLatestIceVersion() {
|
|
285
|
+
// Check if core directory exists, run postinstall if not
|
|
286
|
+
if (!fs.existsSync(CORE_DIR)) {
|
|
287
|
+
const { execSync } = require('child_process');
|
|
288
|
+
execSync('node ' + path.join(__dirname, '../scripts/postinstall.cjs'), { stdio: 'inherit' });
|
|
289
|
+
}
|
|
290
|
+
const versions = fs.readdirSync(CORE_DIR)
|
|
291
|
+
.filter(f => f.startsWith('ice-v') && f.endsWith('.js'))
|
|
292
|
+
.sort();
|
|
293
|
+
if (!versions || versions.length === 0) {
|
|
294
|
+
console.error('ICE core not found. Run: node scripts/postinstall.cjs');
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
return versions[versions.length - 1] || 'ice-v15.js';
|
|
298
|
+
}
|
|
299
|
+
|
|
283
300
|
async function processQuery(query) {
|
|
284
301
|
try {
|
|
285
|
-
|
|
302
|
+
// Dynamically load latest ICE version
|
|
303
|
+
const latest = getLatestIceVersion();
|
|
304
|
+
const iceModule = require(path.join(CORE_DIR, latest));
|
|
305
|
+
const IceV16 = iceModule.IceV16 || iceModule.UnifiedPipeline;
|
|
286
306
|
const ice = new IceV16({ yolo, model: selectedModel });
|
|
287
|
-
return
|
|
307
|
+
return ice.process(query);
|
|
288
308
|
} catch (err) {
|
|
289
309
|
return { error: true, message: `Failed to process query: ${err.message}` };
|
|
290
310
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anh3d0nic/qwen-code-termux-ice",
|
|
3
|
-
"version": "16.0.
|
|
4
|
-
"description": "Qwen Code ICE v16.0.
|
|
3
|
+
"version": "16.0.7",
|
|
4
|
+
"description": "Qwen Code ICE v16.0.5 — Compounding Intelligence with proper npm install structure",
|
|
5
5
|
"main": "core/ice-v16.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"qwen-ice": "./bin/qwen-ice",
|
|
8
8
|
"qwen-ice-api-setup": "./bin/qwen-ice-api-setup"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"postinstall": "node
|
|
11
|
+
"postinstall": "node scripts/postinstall.cjs",
|
|
12
12
|
"preuninstall": "node core/uninstall.js",
|
|
13
|
-
"test": "echo \"ICE
|
|
13
|
+
"test": "echo \"ICE v15.0.0 installed successfully\" && exit 0"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"qwen",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"groq",
|
|
22
22
|
"gemini",
|
|
23
23
|
"multi-provider",
|
|
24
|
-
"
|
|
24
|
+
"compounding-intelligence"
|
|
25
25
|
],
|
|
26
26
|
"author": "anh3d0nic",
|
|
27
27
|
"license": "MIT",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"config/",
|
|
50
50
|
"memory/",
|
|
51
51
|
"logs/",
|
|
52
|
+
"scripts/",
|
|
52
53
|
"manifest.json"
|
|
53
54
|
]
|
|
54
55
|
}
|
package/scripts/build.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
// you may not use this file except in compliance with the License.
|
|
10
|
+
// You may obtain a copy of the License at
|
|
11
|
+
//
|
|
12
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
//
|
|
14
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
// See the License for the specific language governing permissions and
|
|
18
|
+
// limitations under the License.
|
|
19
|
+
|
|
20
|
+
import { execSync } from 'node:child_process';
|
|
21
|
+
import { existsSync } from 'node:fs';
|
|
22
|
+
import { dirname, join } from 'node:path';
|
|
23
|
+
import { fileURLToPath } from 'node:url';
|
|
24
|
+
|
|
25
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const root = join(__dirname, '..');
|
|
27
|
+
|
|
28
|
+
// npm install if node_modules was removed (e.g. via npm run clean or scripts/clean.js)
|
|
29
|
+
if (!existsSync(join(root, 'node_modules'))) {
|
|
30
|
+
execSync('npm install', { stdio: 'inherit', cwd: root });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// build all workspaces/packages in dependency order
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// Build in dependency order:
|
|
37
|
+
// 1. test-utils (no internal dependencies)
|
|
38
|
+
// 2. core (foundation package)
|
|
39
|
+
// 3. web-templates (embeddable web templates - used by cli)
|
|
40
|
+
// 4. cli (depends on core, test-utils, web-templates)
|
|
41
|
+
// 5. webui (shared UI components - used by vscode companion)
|
|
42
|
+
// 6. sdk (no internal dependencies)
|
|
43
|
+
// 7. vscode-ide-companion (depends on webui) - SKIPPED for Termux
|
|
44
|
+
const buildOrder = [
|
|
45
|
+
'packages/test-utils',
|
|
46
|
+
'packages/core',
|
|
47
|
+
'packages/web-templates',
|
|
48
|
+
'packages/cli',
|
|
49
|
+
'packages/webui',
|
|
50
|
+
'packages/sdk-typescript',
|
|
51
|
+
// 'packages/vscode-ide-companion', // Not needed for Termux
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
for (const workspace of buildOrder) {
|
|
55
|
+
execSync(`npm run build --workspace=${workspace}`, {
|
|
56
|
+
stdio: 'inherit',
|
|
57
|
+
cwd: root,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// After cli is built, generate the JSON Schema for settings
|
|
61
|
+
// so the vscode-ide-companion extension can provide IntelliSense
|
|
62
|
+
if (workspace === 'packages/cli') {
|
|
63
|
+
execSync('npx tsx scripts/generate-settings-schema.ts', {
|
|
64
|
+
stdio: 'inherit',
|
|
65
|
+
cwd: root,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// also build container image if sandboxing is enabled
|
|
71
|
+
// skip (-s) npm install + build since we did that above
|
|
72
|
+
try {
|
|
73
|
+
execSync('node scripts/sandbox_command.js -q', {
|
|
74
|
+
stdio: 'inherit',
|
|
75
|
+
cwd: root,
|
|
76
|
+
});
|
|
77
|
+
if (
|
|
78
|
+
process.env.BUILD_SANDBOX === '1' ||
|
|
79
|
+
process.env.BUILD_SANDBOX === 'true'
|
|
80
|
+
) {
|
|
81
|
+
execSync('node scripts/build_sandbox.js -s', {
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
cwd: root,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
// ignore
|
|
88
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
// you may not use this file except in compliance with the License.
|
|
10
|
+
// You may obtain a copy of the License at
|
|
11
|
+
//
|
|
12
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
//
|
|
14
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
// See the License for the specific language governing permissions and
|
|
18
|
+
// limitations under the License.
|
|
19
|
+
|
|
20
|
+
import { execSync } from 'node:child_process';
|
|
21
|
+
import { writeFileSync } from 'node:fs';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
|
|
24
|
+
if (!process.cwd().includes('packages')) {
|
|
25
|
+
console.error('must be invoked from a package directory');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// build typescript files
|
|
30
|
+
execSync('tsc --build', { stdio: 'inherit' });
|
|
31
|
+
|
|
32
|
+
// copy .{md,json} files
|
|
33
|
+
execSync('node ../../scripts/copy_files.js', { stdio: 'inherit' });
|
|
34
|
+
|
|
35
|
+
// touch dist/.last_build
|
|
36
|
+
writeFileSync(join(process.cwd(), 'dist', '.last_build'), '');
|
|
37
|
+
process.exit(0);
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
// you may not use this file except in compliance with the License.
|
|
10
|
+
// You may obtain a copy of the License at
|
|
11
|
+
//
|
|
12
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
//
|
|
14
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
// See the License for the specific language governing permissions and
|
|
18
|
+
// limitations under the License.
|
|
19
|
+
|
|
20
|
+
import { execSync } from 'node:child_process';
|
|
21
|
+
import {
|
|
22
|
+
existsSync,
|
|
23
|
+
readFileSync,
|
|
24
|
+
readdirSync,
|
|
25
|
+
rmSync,
|
|
26
|
+
writeFileSync,
|
|
27
|
+
} from 'node:fs';
|
|
28
|
+
import { join } from 'node:path';
|
|
29
|
+
import os from 'node:os';
|
|
30
|
+
import yargs from 'yargs';
|
|
31
|
+
import { hideBin } from 'yargs/helpers';
|
|
32
|
+
import cliPkgJson from '../packages/cli/package.json' with { type: 'json' };
|
|
33
|
+
|
|
34
|
+
const argv = yargs(hideBin(process.argv))
|
|
35
|
+
.option('s', {
|
|
36
|
+
alias: 'skip-npm-install-build',
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
default: false,
|
|
39
|
+
description: 'skip npm install + npm run build',
|
|
40
|
+
})
|
|
41
|
+
.option('f', {
|
|
42
|
+
alias: 'dockerfile',
|
|
43
|
+
type: 'string',
|
|
44
|
+
default: 'Dockerfile',
|
|
45
|
+
description: 'use <dockerfile> for custom image',
|
|
46
|
+
})
|
|
47
|
+
.option('i', {
|
|
48
|
+
alias: 'image',
|
|
49
|
+
type: 'string',
|
|
50
|
+
default: cliPkgJson.config.sandboxImageUri,
|
|
51
|
+
description: 'use <image> name for custom image',
|
|
52
|
+
})
|
|
53
|
+
.option('output-file', {
|
|
54
|
+
type: 'string',
|
|
55
|
+
description:
|
|
56
|
+
'Path to write the final image URI. Used for CI/CD pipeline integration.',
|
|
57
|
+
}).argv;
|
|
58
|
+
|
|
59
|
+
let sandboxCommand;
|
|
60
|
+
try {
|
|
61
|
+
sandboxCommand = execSync('node scripts/sandbox_command.js')
|
|
62
|
+
.toString()
|
|
63
|
+
.trim();
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.warn('ERROR: could not detect sandbox container command');
|
|
66
|
+
console.error(e);
|
|
67
|
+
process.exit(process.env.CI ? 1 : 0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (sandboxCommand === 'sandbox-exec') {
|
|
71
|
+
console.warn(
|
|
72
|
+
'WARNING: container-based sandboxing is disabled (see README.md#sandboxing)',
|
|
73
|
+
);
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`using ${sandboxCommand} for sandboxing`);
|
|
78
|
+
|
|
79
|
+
const image = argv.i;
|
|
80
|
+
const dockerFile = argv.f;
|
|
81
|
+
|
|
82
|
+
if (!image.length) {
|
|
83
|
+
console.warn(
|
|
84
|
+
'No default image tag specified in gemini-cli/packages/cli/package.json',
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!argv.s) {
|
|
89
|
+
execSync('npm install', { stdio: 'inherit' });
|
|
90
|
+
execSync('npm run build', { stdio: 'inherit' });
|
|
91
|
+
|
|
92
|
+
console.log('bundling...');
|
|
93
|
+
execSync('npm run bundle', { stdio: 'inherit' });
|
|
94
|
+
|
|
95
|
+
console.log('preparing package...');
|
|
96
|
+
execSync('npm run prepare:package', { stdio: 'inherit' });
|
|
97
|
+
|
|
98
|
+
console.log('packing...');
|
|
99
|
+
const distDir = join(process.cwd(), 'dist');
|
|
100
|
+
for (const f of readdirSync(distDir)) {
|
|
101
|
+
if (f.endsWith('.tgz')) {
|
|
102
|
+
rmSync(join(distDir, f), { force: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
execSync('npm pack', { stdio: 'ignore', cwd: distDir });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const buildStdout = process.env.VERBOSE ? 'inherit' : 'ignore';
|
|
109
|
+
|
|
110
|
+
// Determine the appropriate shell based on OS
|
|
111
|
+
const isWindows = os.platform() === 'win32';
|
|
112
|
+
const shellToUse = isWindows ? 'powershell.exe' : '/bin/bash';
|
|
113
|
+
|
|
114
|
+
function buildImage(imageName, dockerfile) {
|
|
115
|
+
console.log(`building ${imageName} ... (can be slow first time)`);
|
|
116
|
+
|
|
117
|
+
let buildCommandArgs = '';
|
|
118
|
+
let tempAuthFile = '';
|
|
119
|
+
|
|
120
|
+
if (sandboxCommand === 'podman') {
|
|
121
|
+
if (isWindows) {
|
|
122
|
+
// PowerShell doesn't support <() process substitution.
|
|
123
|
+
// Create a temporary auth file that we will clean up after.
|
|
124
|
+
tempAuthFile = join(os.tmpdir(), `qwen-auth-${Date.now()}.json`);
|
|
125
|
+
writeFileSync(tempAuthFile, '{}');
|
|
126
|
+
buildCommandArgs = `--authfile="${tempAuthFile}"`;
|
|
127
|
+
} else {
|
|
128
|
+
// Use bash-specific syntax for Linux/macOS
|
|
129
|
+
buildCommandArgs = `--authfile=<(echo '{}')`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const npmPackageVersion = JSON.parse(
|
|
134
|
+
readFileSync(join(process.cwd(), 'package.json'), 'utf-8'),
|
|
135
|
+
).version;
|
|
136
|
+
|
|
137
|
+
const imageTag =
|
|
138
|
+
process.env.QWEN_SANDBOX_IMAGE_TAG || imageName.split(':')[1];
|
|
139
|
+
const finalImageName = `${imageName.split(':')[0]}:${imageTag}`;
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
execSync(
|
|
143
|
+
`${sandboxCommand} build ${buildCommandArgs} ${
|
|
144
|
+
process.env.BUILD_SANDBOX_FLAGS || ''
|
|
145
|
+
} --build-arg CLI_VERSION_ARG=${npmPackageVersion} -f "${dockerfile}" -t "${finalImageName}" .`,
|
|
146
|
+
{ stdio: buildStdout, shell: shellToUse },
|
|
147
|
+
);
|
|
148
|
+
console.log(`built ${finalImageName}`);
|
|
149
|
+
|
|
150
|
+
// If an output file path was provided via command-line, write the final image URI to it.
|
|
151
|
+
if (argv.outputFile) {
|
|
152
|
+
console.log(
|
|
153
|
+
`Writing final image URI for CI artifact to: ${argv.outputFile}`,
|
|
154
|
+
);
|
|
155
|
+
// The publish step only supports one image. If we build multiple, only the last one
|
|
156
|
+
// will be published. Throw an error to make this failure explicit if the file already exists.
|
|
157
|
+
if (existsSync(argv.outputFile)) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`CI artifact file ${argv.outputFile} already exists. Refusing to overwrite.`,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
writeFileSync(argv.outputFile, finalImageName);
|
|
163
|
+
}
|
|
164
|
+
} finally {
|
|
165
|
+
// If we created a temp file, delete it now.
|
|
166
|
+
if (tempAuthFile) {
|
|
167
|
+
rmSync(tempAuthFile, { force: true });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
buildImage(image, dockerFile);
|
|
173
|
+
|
|
174
|
+
execSync(`${sandboxCommand} image prune -f`, { stdio: 'ignore' });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
//
|
|
8
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
// you may not use this file except in compliance with the License.
|
|
10
|
+
// You may obtain a copy of the License at
|
|
11
|
+
//
|
|
12
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
13
|
+
//
|
|
14
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
15
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
16
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
17
|
+
// See the License for the specific language governing permissions and
|
|
18
|
+
// limitations under the License.
|
|
19
|
+
|
|
20
|
+
import { execSync } from 'node:child_process';
|
|
21
|
+
import { dirname, join } from 'node:path';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
23
|
+
|
|
24
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
25
|
+
const root = join(__dirname, '..');
|
|
26
|
+
|
|
27
|
+
execSync('npm --workspace=qwen-code-vscode-ide-companion run package', {
|
|
28
|
+
stdio: 'inherit',
|
|
29
|
+
cwd: root,
|
|
30
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import os from 'node:os'; // Import os module
|
|
10
|
+
|
|
11
|
+
// --- Configuration ---
|
|
12
|
+
const cliPackageDir = path.resolve('packages', 'cli'); // Base directory for the CLI package
|
|
13
|
+
const buildTimestampPath = path.join(cliPackageDir, 'dist', '.last_build'); // Path to the timestamp file within the CLI package
|
|
14
|
+
const sourceDirs = [path.join(cliPackageDir, 'src')]; // Source directory within the CLI package
|
|
15
|
+
const filesToWatch = [
|
|
16
|
+
path.join(cliPackageDir, 'package.json'),
|
|
17
|
+
path.join(cliPackageDir, 'tsconfig.json'),
|
|
18
|
+
]; // Specific files within the CLI package
|
|
19
|
+
const buildDir = path.join(cliPackageDir, 'dist'); // Build output directory within the CLI package
|
|
20
|
+
const warningsFilePath = path.join(os.tmpdir(), 'qwen-code-warnings.txt'); // Temp file for warnings
|
|
21
|
+
// ---------------------
|
|
22
|
+
|
|
23
|
+
function getMtime(filePath) {
|
|
24
|
+
try {
|
|
25
|
+
return fs.statSync(filePath).mtimeMs; // Use mtimeMs for higher precision
|
|
26
|
+
} catch (err) {
|
|
27
|
+
if (err.code === 'ENOENT') {
|
|
28
|
+
return null; // File doesn't exist
|
|
29
|
+
}
|
|
30
|
+
console.error(`Error getting stats for ${filePath}:`, err);
|
|
31
|
+
process.exit(1); // Exit on unexpected errors getting stats
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function findSourceFiles(dir, allFiles = []) {
|
|
36
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const fullPath = path.join(dir, entry.name);
|
|
39
|
+
// Simple check to avoid recursing into node_modules or build dir itself
|
|
40
|
+
if (
|
|
41
|
+
entry.isDirectory() &&
|
|
42
|
+
entry.name !== 'node_modules' &&
|
|
43
|
+
fullPath !== buildDir
|
|
44
|
+
) {
|
|
45
|
+
findSourceFiles(fullPath, allFiles);
|
|
46
|
+
} else if (entry.isFile()) {
|
|
47
|
+
allFiles.push(fullPath);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return allFiles;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log('Checking build status...');
|
|
54
|
+
|
|
55
|
+
// Clean up old warnings file before check
|
|
56
|
+
try {
|
|
57
|
+
if (fs.existsSync(warningsFilePath)) {
|
|
58
|
+
fs.unlinkSync(warningsFilePath);
|
|
59
|
+
}
|
|
60
|
+
} catch (err) {
|
|
61
|
+
console.warn(
|
|
62
|
+
`[Check Script] Warning: Could not delete previous warnings file: ${err.message}`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const buildMtime = getMtime(buildTimestampPath);
|
|
67
|
+
if (!buildMtime) {
|
|
68
|
+
// If build is missing, write that as a warning and exit(0) so app can display it
|
|
69
|
+
const errorMessage = `ERROR: Build timestamp file (${path.relative(process.cwd(), buildTimestampPath)}) not found. Run \`npm run build\` first.`;
|
|
70
|
+
console.error(errorMessage); // Still log error here
|
|
71
|
+
try {
|
|
72
|
+
fs.writeFileSync(warningsFilePath, errorMessage);
|
|
73
|
+
} catch (writeErr) {
|
|
74
|
+
console.error(
|
|
75
|
+
`[Check Script] Error writing missing build warning file: ${writeErr.message}`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
process.exit(0); // Allow app to start and show the error
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let newerSourceFileFound = false;
|
|
82
|
+
const warningMessages = []; // Collect warnings here
|
|
83
|
+
const allSourceFiles = [];
|
|
84
|
+
|
|
85
|
+
// Collect files from specified directories
|
|
86
|
+
sourceDirs.forEach((dir) => {
|
|
87
|
+
const dirPath = path.resolve(dir);
|
|
88
|
+
if (fs.existsSync(dirPath)) {
|
|
89
|
+
findSourceFiles(dirPath, allSourceFiles);
|
|
90
|
+
} else {
|
|
91
|
+
console.warn(`Warning: Source directory "${dir}" not found.`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Add specific files
|
|
96
|
+
filesToWatch.forEach((file) => {
|
|
97
|
+
const filePath = path.resolve(file);
|
|
98
|
+
if (fs.existsSync(filePath)) {
|
|
99
|
+
allSourceFiles.push(filePath);
|
|
100
|
+
} else {
|
|
101
|
+
console.warn(`Warning: Watched file "${file}" not found.`);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Check modification times
|
|
106
|
+
for (const file of allSourceFiles) {
|
|
107
|
+
const sourceMtime = getMtime(file);
|
|
108
|
+
const relativePath = path.relative(process.cwd(), file);
|
|
109
|
+
const isNewer = sourceMtime && sourceMtime > buildMtime;
|
|
110
|
+
|
|
111
|
+
if (isNewer) {
|
|
112
|
+
const warning = `Warning: Source file "${relativePath}" has been modified since the last build.`;
|
|
113
|
+
console.warn(warning); // Keep console warning for script debugging
|
|
114
|
+
warningMessages.push(warning);
|
|
115
|
+
newerSourceFileFound = true;
|
|
116
|
+
// break; // Uncomment to stop checking after the first newer file
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (newerSourceFileFound) {
|
|
121
|
+
const finalWarning =
|
|
122
|
+
'\nRun "npm run build" to incorporate changes before starting.';
|
|
123
|
+
warningMessages.push(finalWarning);
|
|
124
|
+
console.warn(finalWarning);
|
|
125
|
+
|
|
126
|
+
// Write warnings to the temp file
|
|
127
|
+
try {
|
|
128
|
+
fs.writeFileSync(warningsFilePath, warningMessages.join('\n'));
|
|
129
|
+
// Removed debug log
|
|
130
|
+
} catch (err) {
|
|
131
|
+
console.error(`[Check Script] Error writing warnings file: ${err.message}`);
|
|
132
|
+
// Proceed without writing, app won't show warnings
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
console.log('Build is up-to-date.');
|
|
136
|
+
// Ensure no stale warning file exists if build is ok
|
|
137
|
+
try {
|
|
138
|
+
if (fs.existsSync(warningsFilePath)) {
|
|
139
|
+
fs.unlinkSync(warningsFilePath);
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
console.warn(
|
|
143
|
+
`[Check Script] Warning: Could not delete previous warnings file: ${err.message}`,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
process.exit(0); // Always exit successfully so the app starts
|