v2.0.0: Built-in Termux — full Linux environment, no external app needed

This commit is contained in:
admin
2026-05-19 17:37:40 +04:00
Unverified
parent a9f53e45dd
commit e7015b129a
8 changed files with 504 additions and 100 deletions

View File

@@ -166,8 +166,10 @@
<p class="subtitle">Set up on-device build tools</p>
</div>
<div id="devsetup-status" class="devsetup-status">
<p>Downloads build tools to compile &amp; install APKs directly on your device.</p>
<p>Required: ~50MB download (aapt2, d8, ecj, android.jar, apksigner)</p>
<p>Downloads and sets up a complete <strong>Termux Linux environment</strong> inside the app.</p>
<p>No external apps needed — bash, coreutils, package manager all included.</p>
<p>Download size: ~30MB (one-time). Architecture auto-detected.</p>
<p>After install, use <code>pkg install aapt2 ecj dx apksigner</code> to add build tools.</p>
</div>
<div id="devsetup-progress" style="display:none">
<div class="devsetup-progress-bar">
@@ -272,13 +274,27 @@
</div>
<div class="settings-section">
<h3>About</h3>
<p class="about-text">Z.AI Chat v1.4.0</p>
<p class="about-text">Z.AI Chat v2.0.0</p>
<p class="about-text">Built with Z.AI SDK &amp; GLM-5.1</p>
<p class="about-text">Compatible with Android 15/16</p>
</div>
<div class="settings-section">
<h3>Changelog</h3>
<ul class="changelog-list">
<li>
<span class="changelog-version">v2.0.0</span>
<span class="changelog-date">2026-05-19</span>
<ul>
<li><strong>Built-in Termux</strong> — full Linux environment inside the app, no external Termux needed</li>
<li>One-time download (~30MB) of Termux bootstrap (bash, coreutils, apt package manager)</li>
<li>Auto-detects CPU architecture (ARM64, ARM, x86, x86_64)</li>
<li>Path patching — fixes all Termux paths to work from our app prefix</li>
<li>BootstrapPlugin — native download, extract, symlink, patch pipeline</li>
<li>ShellPlugin upgraded — uses bundled bash instead of limited /system/bin/sh</li>
<li>Install build tools via: <code>pkg install aapt2 ecj dx apksigner</code></li>
<li>APK stays tiny (~1MB) — bootstrap downloaded on first use, not embedded</li>
</ul>
</li>
<li>
<span class="changelog-version">v1.4.0</span>
<span class="changelog-date">2026-05-19</span>

View File

@@ -1043,6 +1043,7 @@
var Shell = null;
var Installer = null;
var Wake = null;
var Bootstrap = null;
var termState = {
history: [],
historyIndex: -1,
@@ -1062,10 +1063,12 @@
Shell = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Shell;
Installer = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Installer;
Wake = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Wake;
Bootstrap = window.Capacitor && window.Capacitor.Plugins && window.Capacitor.Plugins.Bootstrap;
} catch(e) {}
if (!Shell) console.warn('Shell plugin not available');
if (!Installer) console.warn('Installer plugin not available');
if (!Wake) console.warn('Wake plugin not available');
if (!Bootstrap) console.warn('Bootstrap plugin not available');
}
async function setWakeLock(on) {
@@ -1710,17 +1713,16 @@
];
async function checkDevTools() {
if (!Shell) return false;
if (!Bootstrap) return false;
try {
var result = await shellExec('which aapt2 2>/dev/null && echo "OK" || echo "MISSING"', termState.homeDir, false);
termState.devToolsInstalled = result.output && result.output.indexOf('OK') >= 0;
return termState.devToolsInstalled;
var status = await Bootstrap.getStatus();
return status.installed === true;
} catch(e) { return false; }
}
async function setupDevTools() {
if (!Shell) {
alert('Shell plugin not available');
if (!Bootstrap) {
alert('Bootstrap plugin not available');
return;
}
@@ -1734,94 +1736,38 @@
btn.querySelector('.btn-text').textContent = 'Installing...';
btn.querySelector('.btn-loader').style.display = 'inline-block';
progress.style.display = 'block';
progressText.textContent = 'Starting...';
var toolsDir = termState.toolsDir || (termState.homeDir + '/tools');
var binDir = toolsDir + '/bin';
var steps = [
{ label: 'Creating directories...', cmd: 'mkdir -p ' + binDir + ' ' + toolsDir + '/lib ' + toolsDir + '/java' },
{ label: 'Setting up shell...', cmd: 'cp /system/bin/sh ' + binDir + '/sh 2>/dev/null; chmod +x ' + binDir + '/* 2>/dev/null; echo OK' },
{ label: 'Checking environment...', cmd: 'ls -la ' + binDir + '/ && echo "Environment ready"' }
];
Bootstrap.addListener('bootstrap-progress', function(event) {
if (progressFill) progressFill.style.width = event.percent + '%';
if (progressText) progressText.textContent = event.message;
});
for (var i = 0; i < steps.length; i++) {
progressText.textContent = steps[i].label;
progressFill.style.width = ((i + 1) / (steps.length + 1) * 100) + '%';
var result = await shellExec(steps[i].cmd, termState.homeDir, false);
if (result.exitCode !== 0 && result.exitCode !== undefined) {
progressText.textContent = 'Warning: ' + steps[i].label + ' had issues';
try {
var result = await Bootstrap.install();
statusEl.innerHTML = '<p style="color:var(--success);font-size:16px;font-weight:700">&#10004; Termux environment installed!</p>' +
'<p>Full Linux shell with bash, coreutils, and package manager ready.</p>' +
'<p>Install build tools: open Terminal → type <code>pkg install aapt2 ecj dx apksigner</code></p>';
btn.querySelector('.btn-text').textContent = 'Installed';
btn.querySelector('.btn-loader').style.display = 'none';
termState.homeDir = result.prefixDir ? result.prefixDir.replace('/usr', '') : termState.homeDir;
termState.cwd = termState.homeDir + '/home';
if (Shell) {
var env = await Shell.getEnv();
termState.homeDir = env.HOME;
termState.toolsDir = env.TOOLS;
termState.projectsDir = env.PROJECTS;
termState.cwd = env.CWD || env.HOME;
}
updateCwdDisplay();
} catch(e) {
statusEl.innerHTML = '<p style="color:var(--danger)">Install failed: ' + e.message + '</p>' +
'<p>Check your internet connection and try again.</p>';
btn.disabled = false;
btn.querySelector('.btn-text').textContent = 'Retry Install';
btn.querySelector('.btn-loader').style.display = 'none';
}
progressText.textContent = 'Writing setup scripts...';
progressFill.style.width = '80%';
var setupScript = '#!/system/bin/sh\n' +
'TOOLS_DIR="' + toolsDir + '"\n' +
'BIN_DIR="' + binDir + '"\n' +
'echo "[*] Z.AI Dev Tools Setup"\n' +
'echo "[*] Tools directory: $TOOLS_DIR"\n' +
'echo "[*] For full build support, install these via Termux:"\n' +
'echo " pkg install aapt2 openjdk-17 dx ecj"\n' +
'echo ""\n' +
'echo "[*] Checking available tools..."\n' +
'for tool in aapt2 d8 ecj java apksigner zipalign; do\n' +
' if which $tool 2>/dev/null; then\n' +
' echo " [+] $tool: $(which $tool)"\n' +
' else\n' +
' echo " [-] $tool: not found"\n' +
' fi\n' +
'done\n' +
'echo ""\n' +
'echo "[*] For on-device APK building, you need:"\n' +
'echo " 1. Install Termux from F-Droid or GitHub"\n' +
'echo " 2. In Termux: pkg install aapt2 openjdk-17 dx ecj apksigner"\n' +
'echo " 3. Set TOOLS_PATH in terminal to point to Termux binaries"\n' +
'echo ""\n' +
'echo "[*] Device info:"\n' +
'uname -a\n' +
'echo "Arch: $(uname -m)"\n' +
'echo "[*] Done"\n';
await shellWriteFile(toolsDir + '/setup.sh', setupScript);
await shellExec('chmod +x ' + toolsDir + '/setup.sh', termState.homeDir, false);
var projectTemplate = '#!/system/bin/sh\n' +
'# Z.AI Quick Project Creator\n' +
'PROJECT_NAME="${1:-myapp}"\n' +
'PROJECT_DIR="' + (termState.projectsDir || termState.homeDir + '/projects') + '/$PROJECT_NAME"\n' +
'mkdir -p "$PROJECT_DIR"/app/src/main/java/ai/z/app\n' +
'mkdir -p "$PROJECT_DIR"/app/src/main/res/values\n' +
'mkdir -p "$PROJECT_DIR"/app/src/main/res/layout\n' +
'mkdir -p "$PROJECT_DIR"/app/src/main/res/mipmap-hdpi\n' +
'mkdir -p "$PROJECT_DIR"/build\n' +
'# AndroidManifest.xml\n' +
'cat > "$PROJECT_DIR"/app/src/main/AndroidManifest.xml << \'MANIFEST\'\n' +
'<?xml version="1.0" encoding="utf-8"?>\n' +
'<manifest xmlns:android="http://schemas.android.com/apk/res/android"\n' +
' package="ai.z.app">\n' +
' <application android:label="$PROJECT_NAME" android:theme="@android:style/Theme.Material.Light">\n' +
' <activity android:name=".MainActivity" android:exported="true">\n' +
' <intent-filter>\n' +
' <action android:name="android.intent.action.MAIN"/>\n' +
' <category android:name="android.intent.category.LAUNCHER"/>\n' +
' </intent-filter>\n' +
' </activity>\n' +
' </application>\n' +
'</manifest>\n' +
'MANIFEST\n' +
'echo "[OK] Project created: $PROJECT_DIR"\n' +
'echo "[*] Next: Ask AI to generate the Java code, then build with Deploy"\n';
await shellWriteFile(toolsDir + '/create-project.sh', projectTemplate);
await shellExec('chmod +x ' + toolsDir + '/create-project.sh', termState.homeDir, false);
progressFill.style.width = '100%';
progressText.textContent = 'Setup complete!';
statusEl.innerHTML = '<p style="color:var(--success)">Dev environment ready!</p>' +
'<p>Use the terminal to build apps. Install Termux for full tool support (aapt2, d8, ecj).</p>';
btn.querySelector('.btn-text').textContent = 'Installed';
btn.querySelector('.btn-loader').style.display = 'none';
}
// ---- Init Terminal ----