icoa-cli 1.8.4 → 1.9.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.
@@ -21,7 +21,7 @@ const PYTHON_LIBS = [
21
21
  { name: 'paramiko', check: 'python3 -c "import paramiko"', install: 'paramiko==3.4.0', category: 'Web & Network' },
22
22
  // Crypto & Math
23
23
  { name: 'sympy', check: 'python3 -c "import sympy"', install: 'sympy==1.12', category: 'Crypto & Math' },
24
- { name: 'gmpy2', check: 'python3 -c "import gmpy2"', install: 'gmpy2>=2.2.0', category: 'Crypto & Math' },
24
+ { name: 'gmpy2', check: process.platform === 'darwin' ? '/opt/homebrew/opt/python@3.12/bin/python3.12 -c "import gmpy2"' : 'python3 -c "import gmpy2"', install: 'gmpy2>=2.2.0', category: 'Crypto & Math' },
25
25
  { name: 'cryptography', check: 'python3 -c "import cryptography"', install: 'cryptography==42.0.0', category: 'Crypto & Math' },
26
26
  // Binary & RE
27
27
  { name: 'capstone', check: 'python3 -c "import capstone"', install: 'capstone==5.0.1', category: 'Binary & RE' },
@@ -80,10 +80,14 @@ const SYSTEM_TOOLS = [
80
80
  { name: 'tshark', check: CMD('tshark'), brew: 'wireshark', apt: 'tshark', choco: 'wireshark', category: 'Networking' },
81
81
  // Debuggers & Tracing (5)
82
82
  { name: 'gdb', check: CMD('gdb'), brew: 'gdb', apt: 'gdb', choco: 'mingw', category: 'Debuggers' },
83
- { name: 'ltrace', check: CMD('ltrace'), apt: 'ltrace', category: 'Debuggers' },
84
- { name: 'strace', check: CMD('strace'), apt: 'strace', category: 'Debuggers' },
83
+ ...(process.platform !== 'darwin' ? [
84
+ { name: 'ltrace', check: CMD('ltrace'), apt: 'ltrace', category: 'Debuggers' },
85
+ { name: 'strace', check: CMD('strace'), apt: 'strace', category: 'Debuggers' },
86
+ ] : []),
85
87
  { name: 'objdump', check: CMD('objdump'), category: 'Debuggers' },
86
- { name: 'readelf', check: CMD('readelf'), category: 'Debuggers' },
88
+ ...(process.platform !== 'darwin' ? [
89
+ { name: 'readelf', check: CMD('readelf'), category: 'Debuggers' },
90
+ ] : []),
87
91
  // Reverse Engineering (4)
88
92
  { name: 'radare2', check: CMD('r2'), brew: 'radare2', apt: 'radare2', choco: 'radare2', category: 'Reverse Engineering' },
89
93
  { name: 'rabin2', check: CMD('rabin2'), category: 'Reverse Engineering' },
@@ -91,9 +95,13 @@ const SYSTEM_TOOLS = [
91
95
  { name: 'strings', check: CMD('strings'), category: 'Reverse Engineering' },
92
96
  // Forensics (7)
93
97
  { name: 'binwalk', check: CMD('binwalk'), brew: 'binwalk', apt: 'binwalk', category: 'Forensics' },
94
- { name: 'foremost', check: CMD('foremost'), apt: 'foremost', category: 'Forensics' },
98
+ ...(process.platform !== 'darwin' ? [
99
+ { name: 'foremost', check: CMD('foremost'), apt: 'foremost', category: 'Forensics' },
100
+ ] : []),
95
101
  { name: 'exiftool', check: CMD('exiftool'), brew: 'exiftool', apt: 'exiftool', choco: 'exiftool', category: 'Forensics' },
96
- { name: 'steghide', check: CMD('steghide'), apt: 'steghide', category: 'Forensics' },
102
+ ...(process.platform !== 'darwin' ? [
103
+ { name: 'steghide', check: CMD('steghide'), apt: 'steghide', category: 'Forensics' },
104
+ ] : []),
97
105
  { name: 'file', check: CMD('file'), category: 'Forensics' },
98
106
  { name: 'xxd', check: CMD('xxd'), brew: 'vim', apt: 'xxd', category: 'Forensics' },
99
107
  { name: 'pdftotext', check: CMD('pdftotext'), brew: 'poppler', apt: 'poppler-utils', category: 'Forensics' },
@@ -150,28 +158,83 @@ function isInstalled(check) {
150
158
  }
151
159
  }
152
160
  function getVersion(name) {
161
+ // Version commands for each tool
162
+ const versionCmds = {
163
+ 'python3': 'python3 --version',
164
+ 'pip3': 'pip3 --version',
165
+ 'gcc': 'gcc --version',
166
+ 'g++': 'g++ --version',
167
+ 'make': 'make --version',
168
+ 'nasm': 'nasm --version',
169
+ 'cmake': 'cmake --version',
170
+ 'vim': 'vim --version',
171
+ 'nano': 'nano --version',
172
+ 'tmux': 'tmux -V',
173
+ 'screen': 'screen --version',
174
+ 'curl': 'curl --version',
175
+ 'wget': 'wget --version',
176
+ 'nmap': 'nmap --version',
177
+ 'ssh': 'ssh -V',
178
+ 'socat': 'socat -V',
179
+ 'gdb': 'gdb --version',
180
+ 'radare2': 'r2 -v',
181
+ 'upx': 'upx --version',
182
+ 'binwalk': 'binwalk --help',
183
+ 'exiftool': 'exiftool -ver',
184
+ 'john': 'john --help',
185
+ 'hashcat': 'hashcat --version',
186
+ 'openssl': 'openssl version',
187
+ 'gpg': 'gpg --version',
188
+ 'jq': 'jq --version',
189
+ 'sqlite3': 'sqlite3 --version',
190
+ 'git': 'git --version',
191
+ 'docker': 'docker --version',
192
+ 'tshark': 'tshark --version',
193
+ 'tcpdump': 'tcpdump --version',
194
+ 'pdftotext': 'pdftotext -v',
195
+ 'pngcheck': 'pngcheck 2>&1',
196
+ };
197
+ const cmd = versionCmds[name];
198
+ if (!cmd)
199
+ return '';
153
200
  try {
154
- if (name === 'python3')
155
- return execSync('python3 --version', { encoding: 'utf-8' }).trim().replace('Python ', '');
156
- if (name === 'gcc') {
157
- const m = execSync('gcc --version', { encoding: 'utf-8' }).match(/(\d+\.\d+[\.\d]*)/);
158
- return m?.[1] || '';
159
- }
160
- if (name === 'docker') {
161
- const m = execSync('docker --version', { encoding: 'utf-8' }).match(/(\d+\.\d+\.\d+)/);
162
- return m?.[1] || '';
201
+ const out = execSync(cmd + ' 2>&1', { encoding: 'utf-8', timeout: 3000 }).trim();
202
+ // Extract version number pattern
203
+ const m = out.match(/(\d+\.\d+[\.\d]*)/);
204
+ return m?.[1] || '';
205
+ }
206
+ catch { /* ignore */ }
207
+ return '';
208
+ }
209
+ function getOsInfo() {
210
+ const os = platform();
211
+ try {
212
+ if (os === 'darwin') {
213
+ const ver = execSync('sw_vers -productVersion', { encoding: 'utf-8' }).trim();
214
+ const arch = execSync('uname -m', { encoding: 'utf-8' }).trim();
215
+ return `macOS ${ver} (${arch})`;
163
216
  }
164
- if (name === 'pip3') {
165
- const m = execSync('pip3 --version', { encoding: 'utf-8' }).match(/(\d+\.\d+[\.\d]*)/);
166
- return m?.[1] || '';
217
+ else if (os === 'linux') {
218
+ try {
219
+ const pretty = execSync('cat /etc/os-release | grep PRETTY_NAME', { encoding: 'utf-8' });
220
+ const m = pretty.match(/PRETTY_NAME="(.+)"/);
221
+ const arch = execSync('uname -m', { encoding: 'utf-8' }).trim();
222
+ return m ? `${m[1]} (${arch})` : `Linux (${arch})`;
223
+ }
224
+ catch {
225
+ return 'Linux';
226
+ }
167
227
  }
168
- if (name === 'nmap') {
169
- const m = execSync('nmap --version', { encoding: 'utf-8' }).match(/(\d+\.\d+)/);
170
- return m?.[1] || '';
228
+ else if (os === 'win32') {
229
+ const ver = execSync('ver', { encoding: 'utf-8' }).trim();
230
+ return ver || 'Windows';
171
231
  }
172
232
  }
173
233
  catch { /* ignore */ }
174
- return '';
234
+ return os;
235
+ }
236
+ function getNodeInfo() {
237
+ return `Node.js ${process.version}`;
175
238
  }
176
239
  function getPythonMajorMinor() {
177
240
  try {
@@ -190,10 +253,13 @@ export function registerEnvCommand(program) {
190
253
  function showStatus() {
191
254
  console.log();
192
255
  const os = platform();
193
- const osName = os === 'darwin' ? 'macOS' : os === 'linux' ? 'Linux' : 'Windows';
194
256
  const pm = os === 'darwin' ? 'brew' : os === 'linux' ? 'apt' : 'choco';
195
- console.log(chalk.bold.white(' ICOA Competition Environment (109 commands)'));
196
- console.log(chalk.gray(` Platform: ${osName} | Package Manager: ${pm} | Python: ${PYTHON_TARGET}.x`));
257
+ console.log(chalk.bold.white(' ICOA Competition Environment'));
258
+ console.log(chalk.gray(' ─────────────────────────────────────────────'));
259
+ console.log(chalk.gray(' OS: ') + chalk.white(getOsInfo()));
260
+ console.log(chalk.gray(' Node: ') + chalk.white(getNodeInfo()));
261
+ console.log(chalk.gray(' Package: ') + chalk.white(pm));
262
+ console.log(chalk.gray(' Target: ') + chalk.white(`Python ${PYTHON_TARGET}.x`));
197
263
  console.log(chalk.gray(' ─────────────────────────────────────────────'));
198
264
  // Python version check
199
265
  const pyVer = getPythonMajorMinor();
@@ -234,6 +300,7 @@ function showStatus() {
234
300
  }
235
301
  }
236
302
  currentCategory = '';
303
+ const pipExe = os === 'darwin' ? '/opt/homebrew/opt/python@3.12/bin/pip3.12' : 'pip3';
237
304
  for (const lib of PYTHON_LIBS) {
238
305
  if (lib.category !== currentCategory) {
239
306
  currentCategory = lib.category;
@@ -241,7 +308,21 @@ function showStatus() {
241
308
  }
242
309
  const ok = isInstalled(lib.check);
243
310
  if (ok) {
244
- console.log(chalk.green(` ✓ ${lib.name}`) + chalk.gray(` (${lib.install || 'latest'})`));
311
+ // Get actual installed version — try pip3.12, then pip3
312
+ let ver = '';
313
+ for (const pip of [pipExe, 'pip3']) {
314
+ try {
315
+ const pkgName = lib.name.replace('python-magic', 'python_magic').replace('beautifulsoup4', 'beautifulsoup4');
316
+ const out = execSync(`${pip} show ${pkgName} 2>/dev/null | grep Version`, { encoding: 'utf-8', timeout: 3000 });
317
+ const m = out.match(/Version:\s*(\S+)/);
318
+ if (m) {
319
+ ver = m[1];
320
+ break;
321
+ }
322
+ }
323
+ catch { /* try next */ }
324
+ }
325
+ console.log(chalk.green(` ✓ ${lib.name}`) + chalk.gray(ver ? ` (${ver})` : ''));
245
326
  installed++;
246
327
  }
247
328
  else {
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ ${LINE}
36
36
  ${chalk.white('Sydney, Australia')} ${chalk.gray('Jun 27 - Jul 2, 2026')}
37
37
  ${chalk.cyan.underline('https://icoa2026.au')}
38
38
 
39
- ${chalk.gray('CLI-Native Competition Terminal v1.8.4')}
39
+ ${chalk.gray('CLI-Native Competition Terminal v1.9.0')}
40
40
 
41
41
  ${LINE}
42
42
  `;
package/dist/repl.js CHANGED
@@ -8,7 +8,7 @@ import { ensureSandbox, runInSandbox, isDockerAvailable } from './lib/sandbox.js
8
8
  import { logCommand } from './lib/logger.js';
9
9
  import { startLogSync, stopLogSync } from './lib/log-sync.js';
10
10
  const INTERCEPT = '__REPL_NO_EXIT__';
11
- const VERSION = '1.8.4';
11
+ const VERSION = '1.9.0';
12
12
  export async function startRepl(program, resumeMode) {
13
13
  const config = getConfig();
14
14
  const connected = isConnected();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "icoa-cli",
3
- "version": "1.8.4",
3
+ "version": "1.9.0",
4
4
  "description": "ICOA CLI — The world's first CLI-native CTF competition terminal",
5
5
  "type": "module",
6
6
  "bin": {