@anh3d0nic/qwen-code-termux-ice 7.0.0 → 8.0.0
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/README.md +141 -108
- package/package.json +7 -6
- package/scripts/ice-v8.js +550 -0
- package/scripts/test-v8.js +42 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @anh3d0nic/qwen-code-termux-ice
|
|
1
|
+
# @anh3d0nic/qwen-code-termux-ice v8.0.0
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Intent-aware mobile-first AI coding validation for Termux.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -16,152 +16,185 @@ qwen-code-ice # Main interactive CLI
|
|
|
16
16
|
qwen-ice # Alias
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
###
|
|
19
|
+
### v8.0 New Systems
|
|
20
20
|
```bash
|
|
21
|
-
ice-
|
|
22
|
-
ice-
|
|
23
|
-
ice-
|
|
24
|
-
ice-
|
|
25
|
-
ice-v7 session clear # Clear saved session
|
|
26
|
-
ice-v7 validate "code" # Context-aware validation (skips ORM)
|
|
27
|
-
ice-v7 pushback "code" # Pushback on dangerous code
|
|
28
|
-
ice-v7 honest # Honest limitations demo
|
|
29
|
-
ice-v7 layers "code" # Four-layer validation
|
|
30
|
-
ice-v7 debt "code" # Technical debt detection
|
|
31
|
-
ice-v7 response "text" # Format response (auto-detects mobile)
|
|
21
|
+
ice-v8 intent [text] # Analyze user intent (literal vs actual)
|
|
22
|
+
ice-v8 context [show|clear] # Active context engine
|
|
23
|
+
ice-v8 gate [task] # Code quality gate
|
|
24
|
+
ice-v8 philosophy # Response philosophy
|
|
32
25
|
```
|
|
33
26
|
|
|
34
|
-
|
|
27
|
+
### v8.0 Validation Tools
|
|
28
|
+
```bash
|
|
29
|
+
ice-v8 mobile # Mobile-optimized UI
|
|
30
|
+
ice-v8 theme [amoled|termux] # Apply dark theme
|
|
31
|
+
ice-v8 session [save|restore|clear]
|
|
32
|
+
ice-v8 validate [code] # Context-aware validation (skips ORM)
|
|
33
|
+
ice-v8 pushback [code] # Pushback on dangerous code
|
|
34
|
+
ice-v8 honest # Honest limitations (confidence <60%)
|
|
35
|
+
ice-v8 layers [code] # Four-layer validation
|
|
36
|
+
ice-v8 debt [code] # Technical debt detection
|
|
37
|
+
ice-v8 response [text] # Format response (auto-detects mobile)
|
|
38
|
+
```
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
- Detects Termux via `process.env.TERMUX_VERSION`
|
|
38
|
-
- Detects small screens (<80 columns)
|
|
39
|
-
- Formats responses differently for mobile vs desktop
|
|
40
|
+
## NEW in v8.0.0
|
|
40
41
|
|
|
41
|
-
###
|
|
42
|
-
|
|
43
|
-
- Shows tip to use desktop for full output
|
|
42
|
+
### 1. Intent Engine
|
|
43
|
+
Decodes what user literally said vs what they actually want.
|
|
44
44
|
|
|
45
|
-
### AMOLED Theme
|
|
46
45
|
```bash
|
|
47
|
-
ice-
|
|
46
|
+
ice-v8 intent "How do I fix this error?"
|
|
48
47
|
```
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
### Session Management
|
|
52
|
-
```bash
|
|
53
|
-
ice-v7 session save # Saves to ~/.qwen/ice_session.json
|
|
54
|
-
ice-v7 session restore # Restores from ~/.qwen/ice_session.json
|
|
48
|
+
Output:
|
|
55
49
|
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
# Skips SQL injection warning when ORM detected
|
|
50
|
+
Literal: "How do I fix this error?..."
|
|
51
|
+
Intent: user wants step-by-step instructions
|
|
52
|
+
Strategy: Provide numbered steps with examples
|
|
53
|
+
Confidence: 85%
|
|
61
54
|
```
|
|
62
55
|
|
|
63
|
-
|
|
64
|
-
- `
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
- `
|
|
56
|
+
**Detected Patterns:**
|
|
57
|
+
- `how to/do i` → wants step-by-step instructions
|
|
58
|
+
- `why isn't/doesn't` → frustrated, needs root cause
|
|
59
|
+
- `can you/could you` → wants action, not permission
|
|
60
|
+
- `fix/broken/error` → needs working solution now
|
|
61
|
+
- `termux/android` → needs mobile-specific advice
|
|
69
62
|
|
|
70
|
-
###
|
|
71
|
-
|
|
72
|
-
ice-v7 pushback "SELECT * FROM users WHERE id = '' + userId"
|
|
73
|
-
```
|
|
74
|
-
Blocks and explains why for:
|
|
75
|
-
- SQL injection patterns
|
|
76
|
-
- Hardcoded passwords
|
|
77
|
-
- eval() usage
|
|
78
|
-
- Infinite loops
|
|
63
|
+
### 2. Active Context Engine
|
|
64
|
+
Maintains compressed context block (200 tokens max).
|
|
79
65
|
|
|
80
|
-
### Honest Limitations
|
|
81
66
|
```bash
|
|
82
|
-
ice-
|
|
67
|
+
ice-v8 context show
|
|
68
|
+
```
|
|
69
|
+
Output:
|
|
83
70
|
```
|
|
84
|
-
|
|
71
|
+
ACTIVE_CONTEXT:
|
|
72
|
+
goal: Build Termux validation tool
|
|
73
|
+
decisions: Using context-aware rules
|
|
74
|
+
blockers: none
|
|
75
|
+
last_action: User request
|
|
76
|
+
turn: 1
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Auto-saves to `~/.qwen/ice_active_context.json`
|
|
80
|
+
|
|
81
|
+
### 3. Code Quality Gate
|
|
82
|
+
Before writing any code:
|
|
83
|
+
- States what code must do (1 sentence)
|
|
84
|
+
- Lists edge cases
|
|
85
|
+
- Lists Termux constraints (PREFIX=/data/data/com.termux/files/usr)
|
|
86
|
+
- Writes code
|
|
87
|
+
- Verifies against requirements
|
|
85
88
|
|
|
86
|
-
### Four-Layer Validation
|
|
87
89
|
```bash
|
|
88
|
-
ice-
|
|
90
|
+
ice-v8 gate "Create validation function"
|
|
91
|
+
```
|
|
92
|
+
Output:
|
|
89
93
|
```
|
|
90
|
-
|
|
94
|
+
🔒 Code Quality Gate
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
96
|
+
Task: Create validation function
|
|
97
|
+
|
|
98
|
+
Termux Constraints:
|
|
99
|
+
• PREFIX = /data/data/com.termux/files/usr
|
|
100
|
+
• No sudo/root access
|
|
101
|
+
• ARM64 architecture only
|
|
102
|
+
• Limited RAM (2-4GB typical)
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
🔍 Verification:
|
|
106
|
+
Uses hardcoded paths: ✅ No
|
|
107
|
+
Uses sudo: ✅ No
|
|
108
|
+
Has error handling: ✅ Yes
|
|
109
|
+
|
|
110
|
+
Gate ✅ PASSED
|
|
95
111
|
```
|
|
96
|
-
|
|
112
|
+
|
|
113
|
+
### 4. Response Philosophy
|
|
114
|
+
Embedded in all responses:
|
|
115
|
+
- ✅ Decode intent, not literal words
|
|
116
|
+
- ✅ Dense and surgical, no filler
|
|
117
|
+
- ✅ If uncertain: confidence [0-100%] + reason
|
|
118
|
+
- ✅ Code always production-ready, never stubbed
|
|
119
|
+
- ✅ Always state next step before user asks
|
|
120
|
+
- ✅ Termux-first always
|
|
121
|
+
|
|
122
|
+
## Termux Constraints
|
|
123
|
+
|
|
124
|
+
All code respects:
|
|
125
|
+
- `PREFIX=/data/data/com.termux/files/usr`
|
|
126
|
+
- No sudo/root access
|
|
127
|
+
- ARM64 architecture only
|
|
128
|
+
- Limited RAM (2-4GB typical)
|
|
129
|
+
- No systemd or init services
|
|
130
|
+
- Storage via ~/storage or termux-setup-storage
|
|
97
131
|
|
|
98
132
|
## Configuration Files
|
|
99
133
|
|
|
100
134
|
| File | Location | Purpose |
|
|
101
135
|
|------|----------|---------|
|
|
102
136
|
| Session | `~/.qwen/ice_session.json` | Auto-saved conversations |
|
|
137
|
+
| Active Context | `~/.qwen/ice_active_context.json` | Compressed context block |
|
|
103
138
|
| Config | `~/.qwen/ice_config.json` | User preferences |
|
|
104
139
|
|
|
105
140
|
## Package Info
|
|
106
141
|
|
|
107
|
-
- **Version:**
|
|
142
|
+
- **Version:** 8.0.0
|
|
108
143
|
- **License:** MIT
|
|
109
144
|
- **Dependencies:** None
|
|
110
145
|
- **Size:** 13.1 MB (compressed)
|
|
111
|
-
- **Binaries:** qwen-code-ice, qwen-ice, ice-
|
|
146
|
+
- **Binaries:** qwen-code-ice, qwen-ice, ice-v8
|
|
112
147
|
|
|
113
148
|
## Changelog
|
|
114
149
|
|
|
115
|
-
###
|
|
116
|
-
|
|
117
|
-
**
|
|
118
|
-
|
|
119
|
-
**
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
**
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
|
|
142
|
-
|
|
150
|
+
### v8.0.0 (2026-03-21)
|
|
151
|
+
|
|
152
|
+
**ADDED - 4 New Systems:**
|
|
153
|
+
|
|
154
|
+
**1. Intent Engine (`IntentEngine` class)**
|
|
155
|
+
- 7 intent patterns (how-to, why-not, can-you, fix, best, termux)
|
|
156
|
+
- Analyzes literal vs actual intent
|
|
157
|
+
- Returns confidence score (60-85%)
|
|
158
|
+
- File: `scripts/ice-v8.js` lines 88-118
|
|
159
|
+
|
|
160
|
+
**2. Active Context Engine (`ActiveContextEngine` class)**
|
|
161
|
+
- Maintains: goal, decisions, blockers, last_action, turn_count
|
|
162
|
+
- Auto-compresses to 200 tokens (~1000 chars)
|
|
163
|
+
- Persists to `~/.qwen/ice_active_context.json`
|
|
164
|
+
- File: `scripts/ice-v8.js` lines 24-85
|
|
165
|
+
|
|
166
|
+
**3. Code Quality Gate (`CodeQualityGate` class)**
|
|
167
|
+
- 8 Termux-specific constraints
|
|
168
|
+
- Pre-code checklist (task, one_sentence, edge_cases)
|
|
169
|
+
- Post-code verification (paths, sudo, error handling)
|
|
170
|
+
- File: `scripts/ice-v8.js` lines 121-168
|
|
171
|
+
|
|
172
|
+
**4. Response Philosophy (`RESPONSE_PHILOSOPHY` constant)**
|
|
173
|
+
- 6 principles embedded in all responses
|
|
174
|
+
- `applyResponsePhilosophy()` function adds next step
|
|
175
|
+
- `getNextStep()` infers user's next action
|
|
176
|
+
- File: `scripts/ice-v8.js` lines 171-195
|
|
177
|
+
|
|
178
|
+
**KEPT from v7.0.0:**
|
|
179
|
+
- Mobile detection (v6.0)
|
|
180
|
+
- AMOLED theme (v6.0)
|
|
181
|
+
- Session management (v6.0)
|
|
182
|
+
- Context-aware validation (v5.0)
|
|
183
|
+
- Pushback mode (v5.0)
|
|
184
|
+
- Honest limitations (v5.0)
|
|
185
|
+
- Four-layer validation (v3.0)
|
|
186
|
+
- Technical debt detection (v3.0)
|
|
187
|
+
|
|
188
|
+
**REMOVED:**
|
|
189
|
+
- None (all v7.0.0 features retained)
|
|
143
190
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
### v5.0.0 (2026-03-21)
|
|
147
|
-
|
|
148
|
-
Added context-aware validation, pushback mode, honest limitations.
|
|
149
|
-
|
|
150
|
-
### v4.0.0 (2026-03-21)
|
|
151
|
-
|
|
152
|
-
Added pattern rules with CWE/OWASP references.
|
|
153
|
-
|
|
154
|
-
### v3.0.0 (2026-03-21)
|
|
155
|
-
|
|
156
|
-
Added four-layer validation, technical debt detection.
|
|
157
|
-
|
|
158
|
-
### v1.1.0 (2026-03-21)
|
|
191
|
+
### v7.0.0 (2026-03-21)
|
|
159
192
|
|
|
160
|
-
|
|
193
|
+
Consolidated mobile-first validation from v1.0-v6.0.
|
|
161
194
|
|
|
162
|
-
### v1.0.1
|
|
195
|
+
### v1.0.1-v6.0.0
|
|
163
196
|
|
|
164
|
-
|
|
197
|
+
See previous releases for history.
|
|
165
198
|
|
|
166
199
|
## Repository
|
|
167
200
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anh3d0nic/qwen-code-termux-ice",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Qwen Code ICE
|
|
3
|
+
"version": "8.0.0",
|
|
4
|
+
"description": "Qwen Code ICE v8.0 - Intent-Aware Mobile Validation",
|
|
5
5
|
"engines": { "node": ">=20.0.0" },
|
|
6
6
|
"type": "module",
|
|
7
7
|
"workspaces": [ "packages/*" ],
|
|
@@ -14,19 +14,20 @@
|
|
|
14
14
|
"bin": {
|
|
15
15
|
"qwen-code-ice": "./scripts/start.js",
|
|
16
16
|
"qwen-ice": "./scripts/start.js",
|
|
17
|
-
"ice-
|
|
17
|
+
"ice-v8": "./scripts/ice-v8.js"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"start": "node scripts/start.js",
|
|
21
21
|
"dev": "node scripts/dev.js",
|
|
22
22
|
"build": "node scripts/build.js",
|
|
23
|
-
"ice-
|
|
24
|
-
"test-
|
|
23
|
+
"ice-v8": "node scripts/ice-v8.js",
|
|
24
|
+
"test-v8": "node scripts/test-v8.js"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"qwen", "code", "termux", "ice", "ai", "assistant", "android",
|
|
28
28
|
"groq", "gemini", "mobile-ux", "amoled", "session-resume",
|
|
29
|
-
"context-aware", "pushback", "validation"
|
|
29
|
+
"context-aware", "pushback", "validation", "intent-engine",
|
|
30
|
+
"active-context", "code-quality"
|
|
30
31
|
],
|
|
31
32
|
"dependencies": {}
|
|
32
33
|
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ICE v8.0.0 Test Suite
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
|
|
9
|
+
console.log('❄️ ICE v8.0.0 Test Suite\n');
|
|
10
|
+
console.log('='.repeat(60));
|
|
11
|
+
|
|
12
|
+
const tests = [
|
|
13
|
+
{ name: 'Intent Engine', cmd: 'node scripts/ice-v8.js intent "How do I fix this?"' },
|
|
14
|
+
{ name: 'Active Context', cmd: 'node scripts/ice-v8.js context show' },
|
|
15
|
+
{ name: 'Code Quality Gate', cmd: 'node scripts/ice-v8.js gate "test"' },
|
|
16
|
+
{ name: 'Response Philosophy', cmd: 'node scripts/ice-v8.js philosophy' },
|
|
17
|
+
{ name: 'Mobile UI', cmd: 'node scripts/ice-v8.js mobile' },
|
|
18
|
+
{ name: 'AMOLED Theme', cmd: 'node scripts/ice-v8.js theme amoled' },
|
|
19
|
+
{ name: 'Context-Aware Validation', cmd: 'node scripts/ice-v8.js validate "prisma.user.findUnique()"' },
|
|
20
|
+
{ name: 'Pushback Mode', cmd: 'node scripts/ice-v8.js pushback "SELECT * + userId"' },
|
|
21
|
+
{ name: 'Four-Layer Validation', cmd: 'node scripts/ice-v8.js layers "function test() {}"' },
|
|
22
|
+
{ name: 'Technical Debt', cmd: 'node scripts/ice-v8.js debt "class God { a(){} b(){} c(){} d(){} e(){} f(){} g(){} h(){} i(){} j(){} k(){} l(){} m(){} n(){} o(){} p(){} }"' }
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
let passed = 0, failed = 0;
|
|
26
|
+
|
|
27
|
+
tests.forEach((t, i) => {
|
|
28
|
+
console.log(`\nTest ${i + 1}: ${t.name}`);
|
|
29
|
+
console.log('-'.repeat(60));
|
|
30
|
+
try {
|
|
31
|
+
execSync(t.cmd, { stdio: 'inherit' });
|
|
32
|
+
console.log('✅ PASS\n');
|
|
33
|
+
passed++;
|
|
34
|
+
} catch (e) {
|
|
35
|
+
console.log('❌ FAIL\n');
|
|
36
|
+
failed++;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
console.log('='.repeat(60));
|
|
41
|
+
console.log(`\nResults: ${passed}/${tests.length} passed\n`);
|
|
42
|
+
process.exit(failed > 0 ? 1 : 0);
|