@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.
Files changed (69) hide show
  1. package/bin/qwen-ice +25 -5
  2. package/package.json +6 -5
  3. package/scripts/build.js +88 -0
  4. package/scripts/build_package.js +37 -0
  5. package/scripts/build_sandbox.js +174 -0
  6. package/scripts/build_vscode_companion.js +30 -0
  7. package/scripts/check-build-status.js +148 -0
  8. package/scripts/check-i18n.ts +462 -0
  9. package/scripts/check-lockfile.js +74 -0
  10. package/scripts/clean.js +59 -0
  11. package/scripts/copy_bundle_assets.js +90 -0
  12. package/scripts/copy_files.js +86 -0
  13. package/scripts/create_alias.sh +39 -0
  14. package/scripts/dev.js +109 -0
  15. package/scripts/esbuild-shims.js +29 -0
  16. package/scripts/generate-git-commit-info.js +71 -0
  17. package/scripts/generate-settings-schema.ts +146 -0
  18. package/scripts/get-release-version.js +411 -0
  19. package/scripts/ice-mobile.js +5 -0
  20. package/scripts/ice-session.js +6 -0
  21. package/scripts/ice-skills.js +31 -0
  22. package/scripts/ice-teams.js +34 -0
  23. package/scripts/ice-v10.js +276 -0
  24. package/scripts/ice-v11.js +276 -0
  25. package/scripts/ice-v12.js +568 -0
  26. package/scripts/ice-v13.js +824 -0
  27. package/scripts/ice-v14.js +1059 -0
  28. package/scripts/ice-v15.js +1501 -0
  29. package/scripts/ice-v2.js +26 -0
  30. package/scripts/ice-v3-core.js +261 -0
  31. package/scripts/ice-v3.js +46 -0
  32. package/scripts/ice-v4.js +657 -0
  33. package/scripts/ice-v5.js +371 -0
  34. package/scripts/ice-v6.js +305 -0
  35. package/scripts/ice-v7.js +291 -0
  36. package/scripts/ice-v8.js +550 -0
  37. package/scripts/ice-v9.js +546 -0
  38. package/scripts/install-ice.sh +70 -0
  39. package/scripts/install.sh +136 -0
  40. package/scripts/installation/INSTALLATION_GUIDE.md +250 -0
  41. package/scripts/installation/install-qwen-with-source.bat +302 -0
  42. package/scripts/installation/install-qwen-with-source.sh +570 -0
  43. package/scripts/lint.js +205 -0
  44. package/scripts/local_telemetry.js +219 -0
  45. package/scripts/postinstall.cjs +235 -0
  46. package/scripts/pre-commit.js +22 -0
  47. package/scripts/prepare-package.js +186 -0
  48. package/scripts/prepare-termux.cjs +26 -0
  49. package/scripts/sandbox_command.js +128 -0
  50. package/scripts/start.js +86 -0
  51. package/scripts/telemetry.js +85 -0
  52. package/scripts/telemetry_gcp.js +188 -0
  53. package/scripts/telemetry_utils.js +450 -0
  54. package/scripts/test-v10.js +18 -0
  55. package/scripts/test-v11.js +18 -0
  56. package/scripts/test-v12.js +18 -0
  57. package/scripts/test-v13.js +18 -0
  58. package/scripts/test-v14.js +18 -0
  59. package/scripts/test-v3.js +47 -0
  60. package/scripts/test-v4.js +47 -0
  61. package/scripts/test-v6.js +59 -0
  62. package/scripts/test-v8.js +42 -0
  63. package/scripts/test-v9.js +18 -0
  64. package/scripts/test-windows-paths.js +51 -0
  65. package/scripts/tests/get-release-version.test.js +186 -0
  66. package/scripts/tests/test-setup.ts +12 -0
  67. package/scripts/tests/vitest.config.ts +26 -0
  68. package/scripts/unused-keys-only-in-locales.json +62 -0
  69. package/scripts/version.js +112 -0
@@ -0,0 +1,550 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * ❄️ ICE v8.0.0 - Intent-Aware Mobile Validation
5
+ *
6
+ * NEW SYSTEMS:
7
+ * 1. Intent Engine - Decodes literal vs actual intent
8
+ * 2. Active Context Engine - Maintains compressed context block
9
+ * 3. Code Quality Gate - Pre-code checklist + verification
10
+ * 4. Response Philosophy - Dense, surgical, Termux-first
11
+ */
12
+
13
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+
16
+ const SESSION_FILE = join(process.env.HOME, '.qwen', 'ice_session.json');
17
+ const CONTEXT_FILE = join(process.env.HOME, '.qwen', 'ice_active_context.json');
18
+ const TERMUX_PREFIX = '/data/data/com.termux/files/usr';
19
+
20
+ // ============================================
21
+ // SYSTEM 2 — ACTIVE CONTEXT ENGINE
22
+ // ============================================
23
+
24
+ class ActiveContextEngine {
25
+ constructor() {
26
+ this.context = {
27
+ goal: '',
28
+ decisions: [],
29
+ blockers: [],
30
+ last_action: '',
31
+ turn_count: 0
32
+ };
33
+ this.load();
34
+ }
35
+
36
+ load() {
37
+ if (existsSync(CONTEXT_FILE)) {
38
+ try {
39
+ this.context = JSON.parse(readFileSync(CONTEXT_FILE, 'utf-8'));
40
+ } catch (e) { this.context = { goal: '', decisions: [], blockers: [], last_action: '', turn_count: 0 }; }
41
+ }
42
+ }
43
+
44
+ save() {
45
+ writeFileSync(CONTEXT_FILE, JSON.stringify(this.context, null, 2));
46
+ }
47
+
48
+ update(goal, decision, blocker, action) {
49
+ if (goal) this.context.goal = goal;
50
+ if (decision) this.context.decisions.push(decision);
51
+ if (blocker && !this.context.blockers.includes(blocker)) this.context.blockers.push(blocker);
52
+ if (action) this.context.last_action = action;
53
+ this.context.turn_count++;
54
+ this.compress();
55
+ this.save();
56
+ }
57
+
58
+ compress() {
59
+ // Compress to 200 tokens max (~1000 chars)
60
+ const maxLen = 1000;
61
+ const json = JSON.stringify(this.context);
62
+ if (json.length > maxLen) {
63
+ // Keep goal, trim decisions/blockers to last 3
64
+ this.context.decisions = this.context.decisions.slice(-3);
65
+ this.context.blockers = this.context.blockers.slice(-3);
66
+ }
67
+ }
68
+
69
+ get() {
70
+ return this.context;
71
+ }
72
+
73
+ format() {
74
+ const c = this.context;
75
+ return `
76
+ ACTIVE_CONTEXT:
77
+ goal: ${c.goal || 'not set'}
78
+ decisions: ${c.decisions.length > 0 ? c.decisions.join(', ') : 'none'}
79
+ blockers: ${c.blockers.length > 0 ? c.blockers.join(', ') : 'none'}
80
+ last_action: ${c.last_action || 'none'}
81
+ turn: ${c.turn_count}`;
82
+ }
83
+
84
+ clear() {
85
+ this.context = { goal: '', decisions: [], blockers: [], last_action: '', turn_count: 0 };
86
+ if (existsSync(CONTEXT_FILE)) writeFileSync(CONTEXT_FILE, JSON.stringify(this.context, null, 2));
87
+ }
88
+ }
89
+
90
+ // ============================================
91
+ // SYSTEM 1 — INTENT ENGINE
92
+ // ============================================
93
+
94
+ class IntentEngine {
95
+ constructor() {
96
+ this.intentPatterns = [
97
+ { literal: /how (to|do i)/i, intent: 'user wants step-by-step instructions', response: 'Provide numbered steps with examples' },
98
+ { literal: /why (isn't|doesn't|not)/i, intent: 'user is frustrated, needs root cause', response: 'Explain root cause first, then fix' },
99
+ { literal: /can you|could you/i, intent: 'user is asking for action, not permission', response: 'Take action immediately, don\'t ask' },
100
+ { literal: /what (is|are)|explain/i, intent: 'user needs understanding, not just answer', response: 'Explain concept, then show example' },
101
+ { literal: /fix|broken|error|fail/i, intent: 'user needs working solution now', response: 'Provide working fix first, explain after' },
102
+ { literal: /best|optimal|recommended/i, intent: 'user wants expert judgment', response: 'Give clear recommendation with tradeoffs' },
103
+ { literal: /termux|android|mobile/i, intent: 'user is on Termux, needs mobile-specific advice', response: 'Always consider Termux constraints' }
104
+ ];
105
+ }
106
+
107
+ analyze(input) {
108
+ const literal = input;
109
+ let detected = null;
110
+
111
+ for (const p of this.intentPatterns) {
112
+ if (p.literal.test(literal)) {
113
+ detected = p;
114
+ break;
115
+ }
116
+ }
117
+
118
+ return {
119
+ literal: literal,
120
+ intent: detected ? detected.intent : 'user needs help with their request',
121
+ response_strategy: detected ? detected.response : 'Provide clear, actionable help',
122
+ confidence: detected ? 85 : 60
123
+ };
124
+ }
125
+
126
+ shouldSay(intent, actualResponse) {
127
+ // Filter: only return what matches the response strategy
128
+ return actualResponse;
129
+ }
130
+ }
131
+
132
+ // ============================================
133
+ // SYSTEM 3 — CODE QUALITY GATE
134
+ // ============================================
135
+
136
+ class CodeQualityGate {
137
+ constructor() {
138
+ this.termuxConstraints = [
139
+ `PREFIX = ${TERMUX_PREFIX}`,
140
+ 'No sudo/root access',
141
+ 'ARM64 architecture only',
142
+ 'Limited RAM (2-4GB typical)',
143
+ 'No systemd or init services',
144
+ 'Storage access via ~/storage or termux-setup-storage',
145
+ 'Node.js via pkg install nodejs-lts',
146
+ 'Python via pkg install python'
147
+ ];
148
+ }
149
+
150
+ beforeCode(task) {
151
+ const gate = {
152
+ task: task,
153
+ one_sentence: '',
154
+ edge_cases: [],
155
+ termux_constraints: this.termuxConstraints,
156
+ code: '',
157
+ verified: false
158
+ };
159
+
160
+ console.log('\n🔒 Code Quality Gate\n');
161
+ console.log('Task: ' + task);
162
+ console.log('\nTermux Constraints:');
163
+ this.termuxConstraints.forEach(c => console.log(' • ' + c));
164
+ console.log('\nEdge Cases to Consider:');
165
+ console.log(' • Permission denied errors');
166
+ console.log(' • Path differences from standard Linux');
167
+ console.log(' • Memory limitations');
168
+ console.log(' • ARM64-specific binaries');
169
+ console.log();
170
+
171
+ return gate;
172
+ }
173
+
174
+ verify(code, oneSentence) {
175
+ console.log('🔍 Verification:');
176
+ console.log(' Original requirement: ' + oneSentence);
177
+ console.log(' Code length: ' + code.length + ' chars');
178
+ console.log(' Uses hardcoded paths: ' + (code.includes('/usr/') || code.includes('/bin/') ? '❌ Yes (will fail on Termux)' : '✅ No'));
179
+ console.log(' Uses sudo: ' + (code.includes('sudo') ? '❌ Yes (not available)' : '✅ No'));
180
+ console.log(' Has error handling: ' + (code.includes('try') || code.includes('catch') || code.includes('if') ? '✅ Yes' : '⚠️ Partial'));
181
+ console.log();
182
+
183
+ const passes = !code.includes('sudo') && !code.includes('/usr/bin/') && !code.includes('/bin/');
184
+ return passes;
185
+ }
186
+ }
187
+
188
+ // ============================================
189
+ // SYSTEM 4 — RESPONSE PHILOSOPHY (embedded)
190
+ // ============================================
191
+
192
+ const RESPONSE_PHILOSOPHY = {
193
+ decode_intent: true, // Not literal words
194
+ dense_surgical: true, // No filler
195
+ confidence_required: true,// If uncertain: [0-100%] + reason
196
+ code_production_ready: true, // Never stubbed
197
+ state_next_step: true, // Before user asks
198
+ termux_first: true // Always
199
+ };
200
+
201
+ function applyResponsePhilosophy(response, uncertainty = null) {
202
+ // Remove filler words
203
+ response = response.replace(/(basically|essentially|just|simply|hopefully)/gi, '').trim();
204
+
205
+ // Add confidence if uncertain
206
+ if (uncertainty) {
207
+ response += `\n\n⚠️ Confidence: ${uncertainty.confidence}%\nReason: ${uncertainty.reason}`;
208
+ }
209
+
210
+ // Always state next step
211
+ response += '\n\n→ Next: ' + getNextStep(response);
212
+
213
+ return response;
214
+ }
215
+
216
+ function getNextStep(response) {
217
+ if (response.includes('validate') || response.includes('check')) return 'Run the validation and review results';
218
+ if (response.includes('install') || response.includes('setup')) return 'Execute the installation command';
219
+ if (response.includes('fix') || response.includes('error')) return 'Apply the fix and test';
220
+ return 'Review and provide feedback';
221
+ }
222
+
223
+ // ============================================
224
+ // MOBILE DETECTION (v6.0)
225
+ // ============================================
226
+
227
+ function detectMobile() {
228
+ const isTermux = !!process.env.TERMUX_VERSION;
229
+ const columns = process.stdout.columns || 80;
230
+ return { isTermux, isSmallScreen: columns < 80, columns };
231
+ }
232
+
233
+ function formatMobileResponse(content) {
234
+ const maxLength = 500;
235
+ console.log('\n📱 Mobile Mode\n');
236
+ console.log('─'.repeat(Math.min(60, process.stdout.columns || 60)));
237
+ if (content.length > maxLength) {
238
+ console.log(content.substring(0, maxLength) + '...');
239
+ console.log('\n⋯ Full response in desktop mode');
240
+ } else {
241
+ console.log(content);
242
+ }
243
+ console.log('─'.repeat(Math.min(60, process.stdout.columns || 60)));
244
+ }
245
+
246
+ function formatDesktopResponse(content) {
247
+ console.log('\n💻 Desktop Mode\n');
248
+ console.log('═'.repeat(80));
249
+ console.log(content);
250
+ console.log('═'.repeat(80));
251
+ }
252
+
253
+ function formatResponse(content) {
254
+ const device = detectMobile();
255
+ if (device.isSmallScreen || device.isTermux) {
256
+ formatMobileResponse(content);
257
+ } else {
258
+ formatDesktopResponse(content);
259
+ }
260
+ }
261
+
262
+ // ============================================
263
+ // AMOLED THEME (v6.0)
264
+ // ============================================
265
+
266
+ const THEMES = {
267
+ amoled: { bg: '#000000', fg: '#E0E0E0', accent: '#00E676', error: '#FF5252' },
268
+ termux: { bg: '#000000', fg: '#FFFFFF', accent: '#00FF00', error: '#FF0000' }
269
+ };
270
+
271
+ function hexToRgb(hex) {
272
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
273
+ return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [255, 255, 255];
274
+ }
275
+
276
+ function applyTheme(themeName = 'amoled') {
277
+ const theme = THEMES[themeName] || THEMES.amoled;
278
+ const c = {
279
+ reset: '\x1b[0m',
280
+ fg: `\x1b[38;2;${hexToRgb(theme.fg).join(';')}m`,
281
+ accent: `\x1b[38;2;${hexToRgb(theme.accent).join(';')}m`,
282
+ error: `\x1b[38;2;${hexToRgb(theme.error).join(';')}m`,
283
+ bg: `\x1b[48;2;${hexToRgb(theme.bg).join(';')}m`
284
+ };
285
+ console.log(`${c.bg}${c.fg}\n🎨 Theme: ${themeName}\n─`.repeat(40));
286
+ console.log(`${c.accent}✓ Accent${c.reset} ${c.error}✗ Error${c.reset}`);
287
+ console.log(`─`.repeat(40) + `${c.reset}`);
288
+ }
289
+
290
+ // ============================================
291
+ // SESSION MANAGEMENT (v6.0)
292
+ // ============================================
293
+
294
+ class SessionManager {
295
+ constructor() {
296
+ const dir = join(process.env.HOME, '.qwen');
297
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
298
+ }
299
+
300
+ save(data = {}) {
301
+ const session = { timestamp: Date.now(), conversation: data.conversation || [], context: data.context || {} };
302
+ try {
303
+ writeFileSync(SESSION_FILE, JSON.stringify(session, null, 2));
304
+ console.log('💾 Session saved');
305
+ } catch (e) { console.log('⚠️ Could not save session'); }
306
+ }
307
+
308
+ restore() {
309
+ if (!existsSync(SESSION_FILE)) { console.log('ℹ️ No previous session'); return null; }
310
+ try {
311
+ const s = JSON.parse(readFileSync(SESSION_FILE, 'utf-8'));
312
+ const age = Math.floor((Date.now() - s.timestamp) / (1000 * 60 * 60));
313
+ console.log(`📋 Found session (${age}h ago, ${s.conversation.length} messages)`);
314
+ return s;
315
+ } catch (e) { console.log('⚠️ Could not restore'); return null; }
316
+ }
317
+
318
+ clear() {
319
+ if (existsSync(SESSION_FILE)) {
320
+ writeFileSync(SESSION_FILE, JSON.stringify({ timestamp: Date.now(), conversation: [] }, null, 2));
321
+ console.log('🗑️ Session cleared');
322
+ }
323
+ }
324
+ }
325
+
326
+ // ============================================
327
+ // CONTEXT-AWARE VALIDATION (v5.0)
328
+ // ============================================
329
+
330
+ const CONTEXT_RULES = [
331
+ { id: 'SEC-001', name: 'SQL Injection', severity: 'CRITICAL', pattern: /['"]SELECT.*\+.*['"]/i, skip_if: [/prisma\./i, /sequelize\./i, /typeorm\./i, /knex\./i, /\.query\(\?/i], fix: 'Use parameterized queries' },
332
+ { id: 'SEC-002', name: 'XSS via innerHTML', severity: 'HIGH', pattern: /innerHTML\s*=/i, skip_if: [], fix: 'Use textContent or DOMPurify' },
333
+ { id: 'SEC-003', name: 'Hardcoded Secret', severity: 'CRITICAL', pattern: /(password|secret|api[_-]?key|token)\s*=\s*["'][^"']+["']/i, skip_if: [/process\.env/i, /config\./i, /\.test\./i], fix: 'Use environment variables' },
334
+ { id: 'PERF-001', name: 'N+1 Query', severity: 'HIGH', pattern: /for\s*\(.*\)\s*\{[^}]*\.(find|get|query)/i, skip_if: [/\.include\(/i, /\.join\(/i], fix: 'Use eager loading' }
335
+ ];
336
+
337
+ function contextValidate(code, filePath = '') {
338
+ console.log('🎯 Context-Aware Validation\n');
339
+ const issues = [];
340
+ CONTEXT_RULES.forEach(rule => {
341
+ if (!rule.pattern.test(code)) return;
342
+ const skip = rule.skip_if.some(p => p.test(code) || p.test(filePath));
343
+ if (skip) { console.log(` ⏭️ Skipped ${rule.id}: Safe context detected`); return; }
344
+ issues.push(rule);
345
+ });
346
+ if (issues.length > 0) {
347
+ console.log(`\n⚠️ Found ${issues.length} issues:\n`);
348
+ issues.forEach(i => console.log(` 🔴 ${i.id}: ${i.name} (${i.severity})\n 💡 ${i.fix}\n`));
349
+ } else { console.log('\n ✅ No issues detected\n'); }
350
+ return issues;
351
+ }
352
+
353
+ // ============================================
354
+ // PUSHBACK MODE (v5.0)
355
+ // ============================================
356
+
357
+ const PUSHBACK_TRIGGERS = [
358
+ { pattern: /SELECT.*FROM.*\+.*user/i, problem: 'SQL Injection', why: 'Attackers can steal your database', fix: 'Use parameterized queries', blocking: true },
359
+ { pattern: /password\s*=\s*["'][^"']+["']/i, problem: 'Hardcoded Password', why: 'Passwords in code get committed to git', fix: 'Use process.env.PASSWORD', blocking: true },
360
+ { pattern: /eval\s*\(/i, problem: 'eval() Usage', why: 'Arbitrary code execution risk', fix: 'Use JSON.parse() or Function constructor', blocking: true },
361
+ { pattern: /while\s*\(true\)/i, problem: 'Infinite Loop', why: 'Will crash your server', fix: 'Add exit condition', blocking: true }
362
+ ];
363
+
364
+ function pushback(code) {
365
+ console.log('🛑 Pushback Mode\n');
366
+ const triggers = PUSHBACK_TRIGGERS.filter(t => t.pattern.test(code));
367
+ if (triggers.length === 0) { console.log(' ✅ No critical issues\n'); return { blocked: false }; }
368
+ console.log('⚠️ I need to push back:\n');
369
+ triggers.forEach((t, i) => console.log(`${i + 1}. ${t.problem} (${t.blocking ? 'BLOCKING' : 'WARNING'})\n Why: ${t.why}\n Fix: ${t.fix}\n`));
370
+ const blocked = triggers.some(t => t.blocking);
371
+ if (blocked) console.log('❌ Cannot proceed with this request.\n');
372
+ return { blocked, triggers };
373
+ }
374
+
375
+ // ============================================
376
+ // HONEST LIMITATIONS (v5.0)
377
+ // ============================================
378
+
379
+ function honestMode(confidence = 0.5, reasons = []) {
380
+ console.log('🤷 Honest Limitations\n');
381
+ if (confidence < 0.6) {
382
+ console.log(`⚠️ Confidence: ${(confidence * 100).toFixed(0)}%\n`);
383
+ if (reasons.length > 0) { console.log('Reasons:'); reasons.forEach(r => console.log(` - ${r}`)); }
384
+ console.log('\nPlease verify before production use.\n');
385
+ return { uncertain: true };
386
+ }
387
+ console.log('✅ Confidence is high\n');
388
+ return { uncertain: false };
389
+ }
390
+
391
+ // ============================================
392
+ // FOUR-LAYER VALIDATION (v3.0)
393
+ // ============================================
394
+
395
+ function fourLayerValidate(code) {
396
+ console.log('🛡️ Four-Layer Validation\n');
397
+ console.log('1️⃣ Security...');
398
+ const sec = [{ p: /['"]SELECT.*\+.*['"]/i, n: 'SQL Injection' }, { p: /innerHTML\s*=/i, n: 'XSS' }, { p: /(password|secret|api[_-]?key)\s*=\s*["']/i, n: 'Hardcoded Secret' }].filter(c => c.p.test(code));
399
+ console.log(` ${sec.length === 0 ? '✅' : '❌'} ${sec.length === 0 ? 'Pass' : sec.map(i => i.n).join(', ')}`);
400
+ console.log('2️⃣ Architecture...');
401
+ const arch = (code.split('\n').length < 100 && (code.match(/def /g) || []).length > 10) ? ['God Function'] : [];
402
+ console.log(` ${arch.length === 0 ? '✅' : '❌'} ${arch.length === 0 ? 'Pass' : arch.join(', ')}`);
403
+ console.log('3️⃣ Performance...');
404
+ const perf = [/for.*in.*for/i, /while\s*\(true\)/i].filter(p => p.test(code)).map(() => 'Issue');
405
+ console.log(` ${perf.length === 0 ? '✅' : '❌'} ${perf.length === 0 ? 'Pass' : perf.join(', ')}`);
406
+ console.log('4️⃣ Maintainability...');
407
+ const maint = [code.length > 500 ? 'Long File' : null, !/("""|'''|\/\/)/.test(code) ? 'No Documentation' : null].filter(x => x);
408
+ console.log(` ${maint.length === 0 ? '✅' : '❌'} ${maint.length === 0 ? 'Pass' : maint.join(', ')}`);
409
+ const pass = sec.length === 0 && arch.length === 0 && perf.length === 0 && maint.length === 0;
410
+ console.log(`\n${pass ? '✅' : '❌'} Overall: ${pass ? 'PASS' : 'FAIL'}\n`);
411
+ return pass;
412
+ }
413
+
414
+ // ============================================
415
+ // TECHNICAL DEBT DETECTION (v3.0)
416
+ // ============================================
417
+
418
+ function detectDebt(code) {
419
+ console.log('⚠️ Technical Debt Detection\n');
420
+ const debts = [];
421
+ if ((code.match(/def /g) || []).length > 15 && /class /i.test(code)) debts.push({ t: 'God Class', s: 'HIGH', f: 'Split into focused classes' });
422
+ if ((code.match(/for /g) || []).length > 5 && !/class /i.test(code)) debts.push({ t: 'Missing Abstraction', s: 'MEDIUM', f: 'Create utility module' });
423
+ if (/TODO|FIXME/i.test(code)) debts.push({ t: 'Unresolved Debt', s: 'LOW', f: 'Address or create ticket' });
424
+ if (debts.length > 0) {
425
+ console.log(`Found ${debts.length} items:\n`);
426
+ debts.forEach(d => console.log(` 🔴 ${d.t} (${d.s})\n 💡 ${d.f}\n`));
427
+ } else { console.log(' ✅ No significant debt\n'); }
428
+ return debts;
429
+ }
430
+
431
+ // ============================================
432
+ // MOBILE UI (v6.0)
433
+ // ============================================
434
+
435
+ function showMobileUI() {
436
+ const device = detectMobile();
437
+ console.log('\n❄️ ICE v8.0 - Intent-Aware\n');
438
+ if (device.isSmallScreen) {
439
+ console.log('┌────────────────────────────────┐\n│ ICE v8.0 │ 📱 Mobile │ ^q Quit │\n└────────────────────────────────┘');
440
+ console.log('\nType your message:\n┌────────────────────────────────┐\n│ > _ │\n└────────────────────────────────┘\nShortcuts: ^s Send ^c Clear\n');
441
+ } else {
442
+ console.log('╔════════════════════════════════════════╗\n║ ICE v8.0 │ 💻 Desktop │ :q Quit ║\n╠════════════════════════════════════════╣\n║ Type your message: ║\n║ > _ ║\n╚════════════════════════════════════════╝\nShortcuts: :w Save :r Regenerate :c Clear\n');
443
+ }
444
+ }
445
+
446
+ // ============================================
447
+ // NEW SYSTEMS DEMO
448
+ // ============================================
449
+
450
+ function demoIntentEngine(input) {
451
+ const engine = new IntentEngine();
452
+ const analysis = engine.analyze(input);
453
+ console.log('\n🧠 Intent Engine Analysis\n');
454
+ console.log('Literal: "' + analysis.literal.substring(0, 60) + '..."');
455
+ console.log('Intent: ' + analysis.intent);
456
+ console.log('Strategy: ' + analysis.response_strategy);
457
+ console.log('Confidence: ' + analysis.confidence + '%\n');
458
+ return analysis;
459
+ }
460
+
461
+ function demoActiveContext(action) {
462
+ const engine = new ActiveContextEngine();
463
+ engine.update('Build Termux validation tool', 'Using context-aware rules', null, action);
464
+ console.log(engine.format() + '\n');
465
+ return engine.get();
466
+ }
467
+
468
+ function demoCodeQualityGate(task) {
469
+ const gate = new CodeQualityGate();
470
+ const g = gate.beforeCode(task);
471
+ g.one_sentence = 'Create a function that validates user input safely';
472
+ g.code = 'function validate(input) { if (!input) throw new Error("Required"); return input.trim(); }';
473
+ const passes = gate.verify(g.code, g.one_sentence);
474
+ console.log('Gate ' + (passes ? '✅ PASSED' : '❌ FAILED') + '\n');
475
+ return passes;
476
+ }
477
+
478
+ function demoResponsePhilosophy() {
479
+ console.log('\n📋 Response Philosophy\n');
480
+ Object.entries(RESPONSE_PHILOSOPHY).forEach(([k, v]) => {
481
+ console.log(' ' + (v ? '✅' : '❌') + ' ' + k.replace(/_/g, ' '));
482
+ });
483
+ console.log();
484
+ }
485
+
486
+ // ============================================
487
+ // MAIN CLI
488
+ // ============================================
489
+
490
+ const args = process.argv.slice(2);
491
+ const command = args[0];
492
+ const input = args.slice(1).join(' ');
493
+ const sessionManager = new SessionManager();
494
+ const contextEngine = new ActiveContextEngine();
495
+ const intentEngine = new IntentEngine();
496
+ const qualityGate = new CodeQualityGate();
497
+
498
+ if (!command) {
499
+ console.log('❄️ ICE v8.0 - Intent-Aware Mobile Validation\n');
500
+ console.log('NEW in v8.0:');
501
+ console.log(' 🧠 Intent Engine - Decodes literal vs actual intent');
502
+ console.log(' 📋 Active Context - Maintains compressed context block');
503
+ console.log(' 🔒 Code Quality Gate - Pre-code checklist + verification');
504
+ console.log(' 📋 Response Philosophy - Dense, surgical, Termux-first\n');
505
+ console.log('Usage:');
506
+ console.log(' ice-v8 mobile # Mobile UI');
507
+ console.log(' ice-v8 theme [amoled|termux]');
508
+ console.log(' ice-v8 session [save|restore|clear]');
509
+ console.log(' ice-v8 context [show|clear] # Active context');
510
+ console.log(' ice-v8 intent [text] # Analyze intent');
511
+ console.log(' ice-v8 gate [task] # Code quality gate');
512
+ console.log(' ice-v8 philosophy # Response philosophy');
513
+ console.log(' ice-v8 validate [code] # Context-aware validation');
514
+ console.log(' ice-v8 pushback [code] # Pushback mode');
515
+ console.log(' ice-v8 honest # Honest limitations');
516
+ console.log(' ice-v8 layers [code] # Four-layer validation');
517
+ console.log(' ice-v8 debt [code] # Technical debt');
518
+ console.log(' ice-v8 response [text] # Format for mobile/desktop\n');
519
+ console.log('Termux Constraints:');
520
+ console.log(' PREFIX=' + TERMUX_PREFIX);
521
+ console.log(' No sudo/root access');
522
+ console.log(' ARM64 architecture only\n');
523
+ process.exit(0);
524
+ }
525
+
526
+ switch (command) {
527
+ case 'mobile': showMobileUI(); break;
528
+ case 'theme': applyTheme(args[1] || 'amoled'); break;
529
+ case 'session':
530
+ if (args[1] === 'save') sessionManager.save({ conversation: [] });
531
+ else if (args[1] === 'restore') sessionManager.restore();
532
+ else if (args[1] === 'clear') sessionManager.clear();
533
+ else console.log('Usage: ice-v8 session [save|restore|clear]');
534
+ break;
535
+ case 'context':
536
+ if (args[1] === 'show') { console.log(contextEngine.format() + '\n'); }
537
+ else if (args[1] === 'clear') { contextEngine.clear(); console.log('🗑️ Context cleared\n'); }
538
+ else { demoActiveContext(input || 'User request'); }
539
+ break;
540
+ case 'intent': demoIntentEngine(input || 'How do I fix this error?'); break;
541
+ case 'gate': demoCodeQualityGate(input || 'Create validation function'); break;
542
+ case 'philosophy': demoResponsePhilosophy(); break;
543
+ case 'validate': contextValidate(input || '// Example code'); break;
544
+ case 'pushback': pushback(input || '// Example code'); break;
545
+ case 'honest': honestMode(0.45, ['Limited context', 'Demo mode']); break;
546
+ case 'layers': fourLayerValidate(input || '// Example code'); break;
547
+ case 'debt': detectDebt(input || '// Example code'); break;
548
+ case 'response': formatResponse(input || 'This is a test response for mobile/desktop formatting'); break;
549
+ default: console.log(`Unknown command: ${command}`); process.exit(1);
550
+ }