icoa-cli 1.6.0 → 1.6.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 +1 -1
- package/dist/lib/access.d.ts +2 -0
- package/dist/lib/access.js +8 -0
- package/dist/repl.d.ts +1 -1
- package/dist/repl.js +46 -2
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/package.json +1 -1
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.6.
|
|
39
|
+
${chalk.gray('CLI-Native Competition Terminal v1.6.1')}
|
|
40
40
|
|
|
41
41
|
${LINE}
|
|
42
42
|
`;
|
package/dist/lib/access.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare function isFirstRunOrUpgrade(currentVersion: string): boolean;
|
|
2
|
+
export declare function markVersionSeen(version: string): void;
|
|
1
3
|
export declare function validateToken(token: string): boolean;
|
|
2
4
|
export declare function isActivated(): boolean;
|
|
3
5
|
export type ActivateResult = 'ok' | 'invalid' | 'already_bound';
|
package/dist/lib/access.js
CHANGED
|
@@ -107,6 +107,14 @@ const TOKEN_HASHES = new Set([
|
|
|
107
107
|
"cde02309ad295648d86fa4acefdf7224809abb2ab9b025f14ae41e021512c5ed",
|
|
108
108
|
"39835a1337c2afd9a9690cb9946752899a110df312d9d3aa68e10f85fad49dea",
|
|
109
109
|
]);
|
|
110
|
+
// Check if first run or version upgrade
|
|
111
|
+
export function isFirstRunOrUpgrade(currentVersion) {
|
|
112
|
+
const config = getConfig();
|
|
113
|
+
return config.lastVersion !== currentVersion;
|
|
114
|
+
}
|
|
115
|
+
export function markVersionSeen(version) {
|
|
116
|
+
saveConfig({ lastVersion: version });
|
|
117
|
+
}
|
|
110
118
|
// Free commands that don't require token
|
|
111
119
|
const FREE_COMMANDS = new Set(['ref', 'help', 'exit', 'quit', 'q', 'clear', 'cls', 'activate']);
|
|
112
120
|
function hashToken(token) {
|
package/dist/repl.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
export declare function startRepl(program: Command, resumeMode: boolean): void
|
|
2
|
+
export declare function startRepl(program: Command, resumeMode: boolean): Promise<void>;
|
package/dist/repl.js
CHANGED
|
@@ -2,15 +2,59 @@ import { createInterface } from 'node:readline';
|
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { isConnected, getConfig } from './lib/config.js';
|
|
5
|
-
import { isActivated, activateToken, isFreeCommand, isDeviceMatch, recordExit, recordResume } from './lib/access.js';
|
|
5
|
+
import { isActivated, activateToken, isFreeCommand, isDeviceMatch, recordExit, recordResume, isFirstRunOrUpgrade, markVersionSeen } from './lib/access.js';
|
|
6
6
|
import { resetTerminalTheme } from './lib/theme.js';
|
|
7
7
|
import { ensureSandbox, runInSandbox, isDockerAvailable } from './lib/sandbox.js';
|
|
8
8
|
const INTERCEPT = '__REPL_NO_EXIT__';
|
|
9
|
-
|
|
9
|
+
const VERSION = '1.6.1';
|
|
10
|
+
export async function startRepl(program, resumeMode) {
|
|
10
11
|
const config = getConfig();
|
|
11
12
|
const connected = isConnected();
|
|
12
13
|
const realExit = process.exit.bind(process);
|
|
13
14
|
const activated = isActivated();
|
|
15
|
+
// First run or upgrade: prompt to install env
|
|
16
|
+
if (isFirstRunOrUpgrade(VERSION)) {
|
|
17
|
+
markVersionSeen(VERSION);
|
|
18
|
+
console.log(chalk.gray(' Checking competition environment...'));
|
|
19
|
+
// Quick check: count missing Python libs
|
|
20
|
+
const { execSync } = await import('node:child_process');
|
|
21
|
+
const checks = [
|
|
22
|
+
{ name: 'pwntools', cmd: 'python3 -c "import pwn"' },
|
|
23
|
+
{ name: 'z3-solver', cmd: 'python3 -c "import z3"' },
|
|
24
|
+
{ name: 'numpy', cmd: 'python3 -c "import numpy"' },
|
|
25
|
+
{ name: 'requests', cmd: 'python3 -c "import requests"' },
|
|
26
|
+
];
|
|
27
|
+
let missing = 0;
|
|
28
|
+
for (const c of checks) {
|
|
29
|
+
try {
|
|
30
|
+
execSync(c.cmd, { stdio: 'ignore' });
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
missing++;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (missing > 0) {
|
|
37
|
+
console.log(chalk.yellow(` ${missing} core libraries missing.`));
|
|
38
|
+
try {
|
|
39
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
40
|
+
const yes = await confirm({ message: ' Install competition Python libraries now?', default: true });
|
|
41
|
+
if (yes) {
|
|
42
|
+
console.log();
|
|
43
|
+
// Trigger env setup
|
|
44
|
+
const { execSync: ex } = await import('node:child_process');
|
|
45
|
+
ex('node ' + new URL('../index.js', import.meta.url).pathname + ' env setup', { stdio: 'inherit' });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
console.log(chalk.gray(' Run ') + chalk.white('env setup') + chalk.gray(' later to install.'));
|
|
50
|
+
}
|
|
51
|
+
console.log();
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(chalk.green(' All core libraries ready.'));
|
|
55
|
+
console.log();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
14
58
|
// Handle resume
|
|
15
59
|
if (resumeMode) {
|
|
16
60
|
const info = recordResume();
|
package/dist/types/index.d.ts
CHANGED
|
@@ -100,6 +100,7 @@ export interface IcoaConfig {
|
|
|
100
100
|
geminiModel: string;
|
|
101
101
|
accessToken: string;
|
|
102
102
|
deviceFingerprint: string;
|
|
103
|
+
lastVersion: string;
|
|
103
104
|
}
|
|
104
105
|
export type CompetitionState = 'pre_competition' | 'demo' | 'live' | 'finished' | 'unknown';
|
|
105
106
|
export type HintLevel = 'A' | 'B' | 'C';
|
package/dist/types/index.js
CHANGED