@jpetit/toolkit 3.0.4 → 3.0.5
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/lib/doctor.ts +17 -16
- package/lib/maker.ts +6 -18
- package/lib/tui.ts +4 -3
- package/package.json +1 -2
- package/toolkit/ai.ts +1 -1
- package/toolkit/create-wizard.ts +1 -1
- package/toolkit/create.ts +3 -13
- package/toolkit/doctor.ts +1 -1
- package/toolkit/index.ts +18 -1
- package/toolkit/init.ts +4 -11
- package/toolkit/verify.ts +1 -1
package/lib/doctor.ts
CHANGED
|
@@ -45,9 +45,9 @@ export async function checkPython3(): Promise<void> {
|
|
|
45
45
|
if (await probePython3(true)) {
|
|
46
46
|
tui.success('Python3 seems installed')
|
|
47
47
|
} else {
|
|
48
|
-
tui.
|
|
49
|
-
tui.
|
|
50
|
-
tui.
|
|
48
|
+
tui.warning('Python3 does not appear to be installed')
|
|
49
|
+
tui.print('This is not a problem if you do not plan to use Python solutions')
|
|
50
|
+
tui.print('See https://www.python.org/downloads/')
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -55,9 +55,9 @@ export async function checkGCC(): Promise<void> {
|
|
|
55
55
|
if (await probeGCC(true)) {
|
|
56
56
|
tui.success('C/C++ seems installed')
|
|
57
57
|
} else {
|
|
58
|
-
tui.
|
|
59
|
-
tui.
|
|
60
|
-
tui.
|
|
58
|
+
tui.warning('C/C++ does not appear to be installed')
|
|
59
|
+
tui.print('This is not a problem if you do not plan to use C or C++ solutions')
|
|
60
|
+
tui.print('Please install GCC or Clang')
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -65,9 +65,9 @@ export async function checkLaTeX(): Promise<void> {
|
|
|
65
65
|
if (await probeLaTeX(true)) {
|
|
66
66
|
tui.success('LaTeX seems installed')
|
|
67
67
|
} else {
|
|
68
|
-
tui.
|
|
69
|
-
tui.
|
|
70
|
-
tui.
|
|
68
|
+
tui.warning('LaTeX does not appear to be installed')
|
|
69
|
+
tui.print('You will not be able to generate PDF statements')
|
|
70
|
+
tui.print('TODO: Provide instructions for installing LaTeX')
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -75,9 +75,9 @@ export async function checkPandoc(): Promise<void> {
|
|
|
75
75
|
if (await probePandoc(true)) {
|
|
76
76
|
tui.success('Pandoc with Lua support seems installed')
|
|
77
77
|
} else {
|
|
78
|
-
tui.
|
|
79
|
-
tui.
|
|
80
|
-
tui.
|
|
78
|
+
tui.warning('Pandoc with Lua support does not appear to be installed')
|
|
79
|
+
tui.print('You will not be able to generate text statements (HTML, TXT, MD)')
|
|
80
|
+
tui.print('See https://pandoc.org/installing.html')
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -85,9 +85,9 @@ export async function checkImageMagick(): Promise<void> {
|
|
|
85
85
|
if (await probeImageMagick(true)) {
|
|
86
86
|
tui.success('ImageMagick seems installed')
|
|
87
87
|
} else {
|
|
88
|
-
tui.
|
|
89
|
-
tui.
|
|
90
|
-
tui.
|
|
88
|
+
tui.warning('ImageMagick does not appear to be installed')
|
|
89
|
+
tui.print('You will not be able to convert images for text statements')
|
|
90
|
+
tui.print('See https://imagemagick.org/script/download.php')
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -98,7 +98,8 @@ export async function checkEnvVars(): Promise<void> {
|
|
|
98
98
|
if (process.env[v]) {
|
|
99
99
|
tui.success(`${v} is set`)
|
|
100
100
|
} else {
|
|
101
|
-
tui.
|
|
101
|
+
tui.warning(`${v} is not set`)
|
|
102
|
+
tui.print(`You will not be able to use related AI models`)
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
}
|
package/lib/maker.ts
CHANGED
|
@@ -60,13 +60,7 @@ export class Maker {
|
|
|
60
60
|
private async loadHandler() {
|
|
61
61
|
await tui.section('Loading handler.yml', async () => {
|
|
62
62
|
const data = await readYaml(`${this.directory}/handler.yml`)
|
|
63
|
-
|
|
64
|
-
this.handler = ZHandler.parse(data)
|
|
65
|
-
} catch (e) {
|
|
66
|
-
tui.error(`Invalid handler.yml format`)
|
|
67
|
-
console.dir(e)
|
|
68
|
-
process.exit(1)
|
|
69
|
-
}
|
|
63
|
+
this.handler = ZHandler.parse(data)
|
|
70
64
|
tui.print(Bun.YAML.stringify(this.handler, null, 2))
|
|
71
65
|
})
|
|
72
66
|
}
|
|
@@ -108,14 +102,12 @@ export class Maker {
|
|
|
108
102
|
const solutionProglang = this.handler.solution
|
|
109
103
|
const extension = proglangExtensions[solutionProglang]
|
|
110
104
|
if (!extension) {
|
|
111
|
-
|
|
112
|
-
process.exit(1)
|
|
105
|
+
throw new Error(`Unknown programming language '${solutionProglang}' for solution`)
|
|
113
106
|
}
|
|
114
107
|
const goldenSolutionPath = join(this.directory, `solution.${extension}`)
|
|
115
108
|
const fileExists = await exists(goldenSolutionPath)
|
|
116
109
|
if (!fileExists) {
|
|
117
|
-
|
|
118
|
-
process.exit(1)
|
|
110
|
+
throw new Error(`Golden solution file '${goldenSolutionPath}' not found`)
|
|
119
111
|
}
|
|
120
112
|
this.goldenSolution = `solution.${extension}`
|
|
121
113
|
tui.print(this.goldenSolution)
|
|
@@ -155,9 +147,7 @@ export class Maker {
|
|
|
155
147
|
try {
|
|
156
148
|
await compiler.compile(this.directory, program)
|
|
157
149
|
} catch (error) {
|
|
158
|
-
|
|
159
|
-
console.error(error)
|
|
160
|
-
process.exit(1)
|
|
150
|
+
throw new Error(`Compilation failed`)
|
|
161
151
|
}
|
|
162
152
|
})
|
|
163
153
|
}
|
|
@@ -224,8 +214,7 @@ export class Maker {
|
|
|
224
214
|
|
|
225
215
|
const errors = results.filter((result) => result.error).length
|
|
226
216
|
if (errors > 0) {
|
|
227
|
-
|
|
228
|
-
process.exit(1)
|
|
217
|
+
throw new Error(`${errors} errors occurred while making correct answers`)
|
|
229
218
|
}
|
|
230
219
|
})
|
|
231
220
|
})
|
|
@@ -489,8 +478,7 @@ Draft generated with \\textbf{new-jutge-toolkit}.
|
|
|
489
478
|
try {
|
|
490
479
|
await compiler.compile(this.directory, program)
|
|
491
480
|
} catch (error) {
|
|
492
|
-
|
|
493
|
-
process.exit(1)
|
|
481
|
+
throw new Error(`Compilation failed`)
|
|
494
482
|
}
|
|
495
483
|
})
|
|
496
484
|
|
package/lib/tui.ts
CHANGED
|
@@ -2,6 +2,7 @@ import boxen from 'boxen'
|
|
|
2
2
|
import chalk from 'chalk'
|
|
3
3
|
import { marked } from 'marked'
|
|
4
4
|
import { markedTerminal } from 'marked-terminal'
|
|
5
|
+
import { th } from 'zod/locales'
|
|
5
6
|
|
|
6
7
|
let indentation = 0
|
|
7
8
|
|
|
@@ -39,15 +40,15 @@ export function command(text: string) {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
export function warning(text: string) {
|
|
42
|
-
console.log(chalk.yellow(
|
|
43
|
+
console.log(chalk.yellow(text))
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
export function error(text: string) {
|
|
46
|
-
console.log(chalk.red(
|
|
47
|
+
console.log(chalk.red(text))
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
export function success(text: string) {
|
|
50
|
-
console.log(chalk.green(
|
|
51
|
+
console.log(chalk.green(text))
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export function action(text: string) {
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jpetit/toolkit",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
7
|
"module": "index.ts",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"private": false,
|
|
10
9
|
"bin": "toolkit/index.ts",
|
|
11
10
|
"scripts": {
|
|
12
11
|
"build": "bun run build-assets && bun build toolkit --compile --outfile toolkit.exe",
|
package/toolkit/ai.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { complete, listModels } from '@/lib/ai.ts'
|
|
|
4
4
|
export const ai = new Command('ai').description('Query AI models')
|
|
5
5
|
|
|
6
6
|
ai.command('complete')
|
|
7
|
-
.description('Complete a prompt')
|
|
7
|
+
.description('Complete a prompt using an AI model')
|
|
8
8
|
|
|
9
9
|
.argument('prompt', 'the user prompt to complete')
|
|
10
10
|
.option('-s, --system-prompt <system>', 'the system prompt to use', 'You are a helpful assistant.')
|
package/toolkit/create-wizard.ts
CHANGED
package/toolkit/create.ts
CHANGED
|
@@ -33,13 +33,8 @@ async function selectOutputDir(): Promise<string> {
|
|
|
33
33
|
default: false,
|
|
34
34
|
})
|
|
35
35
|
if (!remove) continue
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
await rm(dir, { recursive: true, force: true })
|
|
39
|
-
} catch (err) {
|
|
40
|
-
tui.warning(`Failed to remove directory ${dir}. Please try again.`)
|
|
41
|
-
continue
|
|
42
|
-
}
|
|
36
|
+
tui.action(`Removing directory ${dir}`)
|
|
37
|
+
await rm(dir, { recursive: true, force: true })
|
|
43
38
|
tui.success(`Removed directory ${dir}`)
|
|
44
39
|
}
|
|
45
40
|
if (!dir.endsWith('.pbm')) {
|
|
@@ -47,12 +42,7 @@ async function selectOutputDir(): Promise<string> {
|
|
|
47
42
|
dir += '.pbm'
|
|
48
43
|
continue
|
|
49
44
|
}
|
|
50
|
-
|
|
51
|
-
await mkdir(dir, { recursive: true })
|
|
52
|
-
} catch (err) {
|
|
53
|
-
tui.warning(`Failed to create directory ${dir}. Please try again.`)
|
|
54
|
-
continue
|
|
55
|
-
}
|
|
45
|
+
await mkdir(dir, { recursive: true })
|
|
56
46
|
tui.success(`Created directory ${dir}`)
|
|
57
47
|
return dir
|
|
58
48
|
}
|
package/toolkit/doctor.ts
CHANGED
|
@@ -13,5 +13,5 @@ export const doctor = new Command('doctor')
|
|
|
13
13
|
await tui.section('Checking LaTeX installation', doc.checkLaTeX)
|
|
14
14
|
await tui.section('Checking Pandoc installation', doc.checkPandoc)
|
|
15
15
|
await tui.section('Checking ImageMagick installation', doc.checkImageMagick)
|
|
16
|
-
await tui.section('Checking
|
|
16
|
+
await tui.section('Checking AI models', doc.checkEnvVars)
|
|
17
17
|
})
|
package/toolkit/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
import { confirm } from '@inquirer/prompts'
|
|
4
|
+
|
|
3
5
|
import { program } from '@commander-js/extra-typings'
|
|
4
6
|
import { ai } from './ai'
|
|
5
7
|
import { compilers } from './compilers'
|
|
@@ -25,4 +27,19 @@ program.addCommand(compilers)
|
|
|
25
27
|
program.addCommand(doctor)
|
|
26
28
|
program.addCommand(ai)
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
try {
|
|
31
|
+
await program.parseAsync()
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('An unexpected error occurred:')
|
|
34
|
+
if (error instanceof Error) {
|
|
35
|
+
if (error.name === 'ExitPromptError') {
|
|
36
|
+
console.error('Operation cancelled by the user')
|
|
37
|
+
} else {
|
|
38
|
+
console.error(error.message)
|
|
39
|
+
const showTrace = await confirm({ message: 'Show stack trace?', default: false })
|
|
40
|
+
if (showTrace) console.error(error)
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
console.error(error)
|
|
44
|
+
}
|
|
45
|
+
}
|
package/toolkit/init.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { decompressAssets } from '@/lib/assets'
|
|
|
2
2
|
import { initializePaths, loadSettings, paths, saveSettings, settingsExist } from '@/lib/settings'
|
|
3
3
|
import { guessUserEmail, guessUserName } from '@/lib/utils'
|
|
4
4
|
import { Command } from '@commander-js/extra-typings'
|
|
5
|
-
import { input,
|
|
5
|
+
import { input, confirm } from '@inquirer/prompts'
|
|
6
6
|
import chalk from 'chalk'
|
|
7
7
|
import * as tui from '@/lib/tui.js'
|
|
8
8
|
|
|
@@ -10,9 +10,10 @@ async function initialize() {
|
|
|
10
10
|
await tui.section('Initialize', async () => {
|
|
11
11
|
let name = (await guessUserName()) || 'John Doe'
|
|
12
12
|
let email = (await guessUserEmail()) || 'john.doe@example.com'
|
|
13
|
+
|
|
13
14
|
name = await input({ message: 'What is your name?', default: name })
|
|
14
15
|
email = await input({ message: 'What is your email?', default: email })
|
|
15
|
-
const notifications = true
|
|
16
|
+
const notifications = await confirm({ message: 'Enable notifications?', default: true })
|
|
16
17
|
|
|
17
18
|
await initializePaths()
|
|
18
19
|
await saveSettings({ name, email, notifications })
|
|
@@ -27,15 +28,7 @@ async function configure() {
|
|
|
27
28
|
|
|
28
29
|
const name = await input({ message: 'What is your name?', default: settings.name })
|
|
29
30
|
const email = await input({ message: 'What is your email?', default: settings.email })
|
|
30
|
-
const
|
|
31
|
-
message: 'Enable notifications?',
|
|
32
|
-
choices: [
|
|
33
|
-
{ name: 'Yes', value: 'yes' },
|
|
34
|
-
{ name: 'No', value: 'no' },
|
|
35
|
-
],
|
|
36
|
-
default: settings.notifications ? 'yes' : 'no',
|
|
37
|
-
})
|
|
38
|
-
const notifications = notificationsInput === 'yes'
|
|
31
|
+
const notifications = await confirm({ message: 'Enable notifications?', default: settings.notifications })
|
|
39
32
|
|
|
40
33
|
await saveSettings({ name, email, notifications })
|
|
41
34
|
|
package/toolkit/verify.ts
CHANGED