icoa-cli 1.3.4 → 1.4.1
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/dist/index.js +3 -1
- package/dist/repl.js +32 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ ${B} ${B}
|
|
|
36
36
|
${B} ${chalk.white('Sydney, Australia')} ${chalk.gray('Jun 27 - Jul 2, 2026')} ${B}
|
|
37
37
|
${B} ${chalk.cyan.underline('https://icoa2026.au')} ${B}
|
|
38
38
|
${B} ${B}
|
|
39
|
-
${B} ${chalk.gray('CLI-Native Competition Terminal v1.
|
|
39
|
+
${B} ${chalk.gray('CLI-Native Competition Terminal v1.4.1')} ${B}
|
|
40
40
|
${B} ${B}
|
|
41
41
|
${chalk.cyan('╚══════════════════════════════════════════════════════════╝')}
|
|
42
42
|
`;
|
|
@@ -61,6 +61,8 @@ program
|
|
|
61
61
|
.description('ICOA CLI — CLI-Native CTF Competition Terminal')
|
|
62
62
|
.option('--resume', 'Resume previous session')
|
|
63
63
|
.action((opts) => {
|
|
64
|
+
// Force black background, white text across all platforms
|
|
65
|
+
process.stdout.write('\x1b[40m\x1b[37m\x1b[2J\x1b[H');
|
|
64
66
|
console.log(BANNER);
|
|
65
67
|
checkTerminal();
|
|
66
68
|
// If running interactively (no extra args or --resume), start REPL
|
package/dist/repl.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createInterface } from 'node:readline';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
2
3
|
import chalk from 'chalk';
|
|
3
4
|
import { isConnected, getConfig } from './lib/config.js';
|
|
4
5
|
import { isActivated, activateToken, isFreeCommand, isDeviceMatch, recordExit, recordResume } from './lib/access.js';
|
|
@@ -63,10 +64,11 @@ export function startRepl(program, resumeMode) {
|
|
|
63
64
|
rl.prompt();
|
|
64
65
|
return;
|
|
65
66
|
}
|
|
66
|
-
// Exit — record and quit
|
|
67
|
+
// Exit — record, reset terminal colors, and quit
|
|
67
68
|
if (input === 'exit' || input === 'quit' || input === 'q') {
|
|
68
69
|
recordExit();
|
|
69
70
|
console.log(chalk.gray(' Session saved. Use ') + chalk.white('icoa --resume') + chalk.gray(' to continue.'));
|
|
71
|
+
process.stdout.write('\x1b[0m\x1b[2J\x1b[H'); // Reset colors, clear screen
|
|
70
72
|
realExit(0);
|
|
71
73
|
return;
|
|
72
74
|
}
|
|
@@ -116,7 +118,7 @@ export function startRepl(program, resumeMode) {
|
|
|
116
118
|
rl.prompt();
|
|
117
119
|
return;
|
|
118
120
|
}
|
|
119
|
-
// Check if it's a known command
|
|
121
|
+
// Check if it's a known ICOA command or a system command
|
|
120
122
|
const knownCommands = [
|
|
121
123
|
'join', 'activate', 'challenges', 'ch', 'open', 'submit', 'flag',
|
|
122
124
|
'scoreboard', 'sb', 'status', 'time', 'hint', 'hint-b', 'hint-c',
|
|
@@ -124,7 +126,15 @@ export function startRepl(program, resumeMode) {
|
|
|
124
126
|
'lang', 'setup', 'model', 'ctf',
|
|
125
127
|
];
|
|
126
128
|
if (!knownCommands.includes(cmd)) {
|
|
127
|
-
|
|
129
|
+
// Pass through to system shell
|
|
130
|
+
processing = true;
|
|
131
|
+
try {
|
|
132
|
+
await runSystemCommand(input, rl);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
console.log(chalk.yellow(` Command failed: ${cmd}`));
|
|
136
|
+
}
|
|
137
|
+
processing = false;
|
|
128
138
|
console.log();
|
|
129
139
|
rl.prompt();
|
|
130
140
|
return;
|
|
@@ -158,9 +168,28 @@ export function startRepl(program, resumeMode) {
|
|
|
158
168
|
});
|
|
159
169
|
rl.on('close', () => {
|
|
160
170
|
recordExit();
|
|
171
|
+
process.stdout.write('\x1b[0m\x1b[2J\x1b[H');
|
|
161
172
|
realExit(0);
|
|
162
173
|
});
|
|
163
174
|
}
|
|
175
|
+
function runSystemCommand(input, rl) {
|
|
176
|
+
return new Promise((resolve) => {
|
|
177
|
+
// Pause readline so the child process gets full terminal control
|
|
178
|
+
rl.pause();
|
|
179
|
+
const child = spawn(input, {
|
|
180
|
+
shell: true,
|
|
181
|
+
stdio: 'inherit',
|
|
182
|
+
});
|
|
183
|
+
child.on('close', () => {
|
|
184
|
+
rl.resume();
|
|
185
|
+
resolve();
|
|
186
|
+
});
|
|
187
|
+
child.on('error', () => {
|
|
188
|
+
rl.resume();
|
|
189
|
+
resolve();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
}
|
|
164
193
|
function mapCommand(input) {
|
|
165
194
|
const parts = input.split(/\s+/);
|
|
166
195
|
const cmd = parts[0].toLowerCase();
|