@jutge.org/toolkit 4.1.0 → 4.2.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/assets/prompts/ask/ask.md +13 -0
- package/dist/index.js +397 -393
- package/docs/getting-started-guide.md +526 -0
- package/docs/jutge-ai.md +82 -0
- package/docs/windows.md +114 -0
- package/package.json +3 -1
- package/toolkit/about.ts +40 -0
- package/toolkit/ai.ts +56 -0
- package/toolkit/ask.ts +42 -0
- package/toolkit/clean.ts +25 -0
- package/toolkit/clone.ts +12 -0
- package/toolkit/compilers.ts +29 -0
- package/toolkit/config.ts +113 -0
- package/toolkit/create.ts +36 -0
- package/toolkit/doctor.ts +22 -0
- package/toolkit/generate.ts +213 -0
- package/toolkit/index.ts +63 -0
- package/toolkit/make.ts +92 -0
- package/toolkit/quiz.ts +44 -0
- package/toolkit/upgrade.ts +9 -0
- package/toolkit/upload.ts +20 -0
- package/toolkit/verify.ts +15 -0
package/docs/windows.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Notes for Windows
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
- Use PowerShell as terminal. Remember to reopen the terminal after the installation of each tool.
|
|
6
|
+
|
|
7
|
+
- Bun is a JavaScript runtime like Node.js but faster and lighter.
|
|
8
|
+
It is required to run the toolkit on Windows. Install `bun` from https://bun.sh/. It is easy.
|
|
9
|
+
|
|
10
|
+
- Install the toolkit using `bun`:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
bun install --global "@jutge.org/toolkit"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The first time may take a while as `bun` needs to download and compile some dependencies. If it fails with a `mkdir` error, just try again, it seems to be a transient error.
|
|
17
|
+
|
|
18
|
+
- Check that the installation was successful:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
jtk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
It should show the help message. You can always add a `--help` flag to any command to get more information.
|
|
25
|
+
|
|
26
|
+
- Check the tools required by the toolkit:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
jtk doctor
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
It should print information about the installed tools. If any tool is missing, consider installing it and try again. Depending on your workflow, some dependencies may not be necessary.
|
|
33
|
+
|
|
34
|
+
## Upgrade
|
|
35
|
+
|
|
36
|
+
Try to use the latest version of the toolkit. Upgrade the toolkit to the latest version with the following command:
|
|
37
|
+
|
|
38
|
+
```powershell
|
|
39
|
+
jtk upgrade
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Check the version after upgrading:
|
|
43
|
+
|
|
44
|
+
```powershell
|
|
45
|
+
jtk --version
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Dependencies
|
|
49
|
+
|
|
50
|
+
- LaTeX: A LaTeX distribution is required to compile problem statements and get their PDFs. It is not necessary but strongly recommended.
|
|
51
|
+
|
|
52
|
+
For Windows, install MiKTeX from https://miktex.org/download. During installation, select the option to install missing packages on-the-fly.
|
|
53
|
+
|
|
54
|
+
- Pandoc: Pandoc with Lua support is required to convert problem statements to Markdown, Text and HTML. It is not necessary but recommended.
|
|
55
|
+
|
|
56
|
+
Install it easily using the Windows Package Manager (`winget`):
|
|
57
|
+
|
|
58
|
+
```powershell
|
|
59
|
+
winget install --id JohnMacFarlane.Pandoc
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- Image Magick: ImageMagick is required to process images in problem statements. It is not necessary but recommended.
|
|
63
|
+
|
|
64
|
+
Install it easily using the Windows Package Manager (`winget`):
|
|
65
|
+
|
|
66
|
+
```powershell
|
|
67
|
+
winget install --id ImageMagick.ImageMagick
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- Python 3: You only need Python 3 if you plan to use Python scripts in your problems.
|
|
71
|
+
|
|
72
|
+
Install Python from https://www.python.org/downloads/windows/. Make sure to check the option to add Python to the system PATH during installation. The toolkit uses `python3` command to run Python scripts.
|
|
73
|
+
|
|
74
|
+
- C/C++ Compiler: You only need a C/C++ compiler if you plan to use C/C++ programs in your problems. The toolkit uses `gcc` and `g++` commands to compile C and C++ programs, respectively.
|
|
75
|
+
|
|
76
|
+
We suggest using [w64devkit](https://github.com/skeeto/w64devkit), a portable C and C++ development kit for Windows. Here are the steps to install it:
|
|
77
|
+
1. **Download** the latest `.exe` file from https://github.com/skeeto/w64devkit/releases.
|
|
78
|
+
|
|
79
|
+
2. **Extract** by double-clicking the downloaded file and choosing a destination (e.g., `C:\w64devkit`).
|
|
80
|
+
|
|
81
|
+
3. **Run** `w64devkit.exe` from the extracted folder to open a terminal with gcc and g++ available.
|
|
82
|
+
|
|
83
|
+
4. **Test** by typing `gcc --version` in the terminal.
|
|
84
|
+
|
|
85
|
+
5. **Compile programs:**
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
gcc myprogram.c -o myprogram.exe
|
|
89
|
+
g++ myprogram.cpp -o myprogram.exe
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Other options are to install [MinGW-w64](http://mingw-w64.org/doku.php) or use the compiler provided by [MSYS2](https://www.msys2.org/).
|
|
93
|
+
|
|
94
|
+
- Java: You only need Java if you plan to use Java programs in your problems. The toolkit uses the `java` and `javac` commands to run and compile Java programs, respectively.
|
|
95
|
+
|
|
96
|
+
Install the Java Runtime Environment (JRE) from https://www.java.com/en/download/manual.jsp. Make sure to download the Windows version.
|
|
97
|
+
|
|
98
|
+
- Likewise, you may need to install Rust, Haskell and Clojure if you plan to use these languages in your problems. If you know how to install them on Windows, please consider contributing to the documentation.
|
|
99
|
+
|
|
100
|
+
## Miscellaneous tips
|
|
101
|
+
|
|
102
|
+
- Open a file with its associated application with `start filename.extension`.
|
|
103
|
+
|
|
104
|
+
- Show environment variables with `echo $env:VARIABLE`.
|
|
105
|
+
|
|
106
|
+
- Set environment temporarly variables with `$env:VARIABLE=value`.
|
|
107
|
+
|
|
108
|
+
- Set environment variables permanently with `[System.Environment]::SetEnvironmentVariable('VARIABLE', 'value', 'User')`.
|
|
109
|
+
|
|
110
|
+
- Console font doesn't support Unicode: The default console font (Raster Fonts) doesn't support many Unicode characters. Change to a font like "Consolas", "Lucida Console", or "Cascadia Code" in your PowerShell window properties.
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jutge.org/toolkit",
|
|
3
3
|
"description": "Toolkit to prepare problems for Jutge.org",
|
|
4
|
-
"version": "4.1
|
|
4
|
+
"version": "4.2.1",
|
|
5
5
|
"homepage": "https://jutge.org",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Jutge.org",
|
|
@@ -40,6 +40,8 @@
|
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
42
42
|
"dist",
|
|
43
|
+
"toolkit",
|
|
44
|
+
"docs",
|
|
43
45
|
"assets"
|
|
44
46
|
],
|
|
45
47
|
"dependencies": {
|
package/toolkit/about.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
import tui from '../lib/tui.ts'
|
|
4
|
+
import { nothing } from '../lib/utils.ts'
|
|
5
|
+
import { packageJson } from '../lib/versions.ts'
|
|
6
|
+
|
|
7
|
+
export const aboutCmd = new Command('about')
|
|
8
|
+
.description('Get information about jutge-toolkit')
|
|
9
|
+
|
|
10
|
+
.action(async () => {
|
|
11
|
+
await nothing()
|
|
12
|
+
tui.print(chalk.bold(`jutge-toolkit ${packageJson.version}`))
|
|
13
|
+
tui.print(packageJson.description)
|
|
14
|
+
tui.print('')
|
|
15
|
+
tui.url(packageJson.homepage!)
|
|
16
|
+
tui.print('')
|
|
17
|
+
tui.print('Author:')
|
|
18
|
+
showPerson(packageJson.author!)
|
|
19
|
+
tui.print('')
|
|
20
|
+
tui.print('Contributors:')
|
|
21
|
+
for (const contributor of packageJson.contributors!) {
|
|
22
|
+
showPerson(contributor)
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
function showPerson(person: string | { name: string; email?: string; url?: string }) {
|
|
27
|
+
let line = ' - '
|
|
28
|
+
if (typeof person === 'string') {
|
|
29
|
+
line += person
|
|
30
|
+
} else {
|
|
31
|
+
line += person.name
|
|
32
|
+
if (person.email) {
|
|
33
|
+
line += ` <${tui.link('mailto://' + person.email, person.email)}>`
|
|
34
|
+
}
|
|
35
|
+
if (person.url) {
|
|
36
|
+
line += ` (${tui.link(person.url)})`
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
tui.print(line)
|
|
40
|
+
}
|
package/toolkit/ai.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings'
|
|
2
|
+
import sharp from 'sharp'
|
|
3
|
+
import z from 'zod'
|
|
4
|
+
import { complete, generateImage, listModels } from '../lib/ai.ts'
|
|
5
|
+
import { settings } from '../lib/settings.ts'
|
|
6
|
+
import tui from '../lib/tui.ts'
|
|
7
|
+
import { convertStringToItsType } from '../lib/utils.ts'
|
|
8
|
+
|
|
9
|
+
export const aiCmd = new Command('ai')
|
|
10
|
+
.description('Query AI models')
|
|
11
|
+
|
|
12
|
+
.action(() => {
|
|
13
|
+
aiCmd.help()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
aiCmd
|
|
17
|
+
.command('models')
|
|
18
|
+
.description('Show available AI models')
|
|
19
|
+
|
|
20
|
+
.action(async () => {
|
|
21
|
+
const models = await listModels()
|
|
22
|
+
tui.yaml(models)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
aiCmd
|
|
26
|
+
.command('complete')
|
|
27
|
+
.description('Complete a prompt using an AI model')
|
|
28
|
+
|
|
29
|
+
.argument('<prompt>', 'the user prompt to complete')
|
|
30
|
+
.option('-s, --system-prompt <system>', 'the system prompt to use', 'You are a helpful assistant.')
|
|
31
|
+
.option('-m, --model <model>', 'the AI model to use', settings.defaultModel)
|
|
32
|
+
|
|
33
|
+
.action(async (prompt, { model, systemPrompt }) => {
|
|
34
|
+
prompt = prompt.trim()
|
|
35
|
+
systemPrompt = systemPrompt.trim()
|
|
36
|
+
const answer = await complete(model, systemPrompt, prompt)
|
|
37
|
+
tui.print(answer)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// TODO: generate with different aspect ratios
|
|
41
|
+
aiCmd
|
|
42
|
+
.command('image')
|
|
43
|
+
.description('Generate a square image using an AI model')
|
|
44
|
+
|
|
45
|
+
.argument('<prompt>', 'description of the image to generate')
|
|
46
|
+
.option('-m, --model <model>', 'the graphic AI model to use', 'openai/dall-e-3')
|
|
47
|
+
.option('-s, --size <size>', 'the size of the image (in pixels)', '1024')
|
|
48
|
+
.option('-o, --output <path>', 'the output image path', 'image.png')
|
|
49
|
+
|
|
50
|
+
.action(async (prompt, { model, size, output }) => {
|
|
51
|
+
const sizeInt = z.int().min(16).max(2048).parse(convertStringToItsType(size))
|
|
52
|
+
const image = await generateImage(model, prompt)
|
|
53
|
+
await sharp(image).resize(sizeInt, sizeInt).toFile(output)
|
|
54
|
+
tui.success(`Generated image saved to ${output}`)
|
|
55
|
+
await tui.image(output, 20, 10)
|
|
56
|
+
})
|
package/toolkit/ask.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings'
|
|
2
|
+
import { glob } from 'fs/promises'
|
|
3
|
+
import { complete } from '../lib/ai'
|
|
4
|
+
import { settings } from '../lib/settings'
|
|
5
|
+
import tui from '../lib/tui'
|
|
6
|
+
import { projectDir, readTextInDir } from '../lib/utils'
|
|
7
|
+
import { join } from 'path'
|
|
8
|
+
import { all } from 'radash'
|
|
9
|
+
|
|
10
|
+
export const askCmd = new Command('ask')
|
|
11
|
+
.description('Ask questions about jutge-toolkit to JutgeAI')
|
|
12
|
+
|
|
13
|
+
.argument('[question]', 'your question about the toolkit')
|
|
14
|
+
.option('-m, --model <model>', 'AI model to use', settings.defaultModel)
|
|
15
|
+
|
|
16
|
+
.action(async (question, { model }) => {
|
|
17
|
+
console.log()
|
|
18
|
+
|
|
19
|
+
const systemPrompt = await readTextInDir(join(projectDir(), 'assets', 'prompts', 'ask'), 'ask.md')
|
|
20
|
+
|
|
21
|
+
const docs = await loadDocumentation() // Load your markdown files
|
|
22
|
+
const fullPrompt = `${docs}\n\nUser question: ${question}`
|
|
23
|
+
|
|
24
|
+
const answer = await complete(model, systemPrompt, fullPrompt)
|
|
25
|
+
await tui.markdown(answer)
|
|
26
|
+
tui.warning(`This answer was generated by JutgeAI using ${model} in good faith.`)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
export async function loadDocumentation(): Promise<string> {
|
|
30
|
+
const documentsDir = join(projectDir(), 'docs')
|
|
31
|
+
const toolkitDir = join(projectDir(), 'toolkit')
|
|
32
|
+
|
|
33
|
+
const documentPaths = await Array.fromAsync(glob('*.md', { cwd: documentsDir }))
|
|
34
|
+
const sourcePaths = await Array.fromAsync(glob('*.ts', { cwd: toolkitDir }))
|
|
35
|
+
|
|
36
|
+
const documents = await all(documentPaths.map((file) => readTextInDir(documentsDir, file)))
|
|
37
|
+
const sources = await all(sourcePaths.map((file) => readTextInDir(toolkitDir, file)))
|
|
38
|
+
|
|
39
|
+
const texts = [...documents, ...sources]
|
|
40
|
+
|
|
41
|
+
return texts.join('\n\n')
|
|
42
|
+
}
|
package/toolkit/clean.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Command, Option } from '@commander-js/extra-typings'
|
|
2
|
+
import { cleanDirectory } from '../lib/cleaner'
|
|
3
|
+
import tui from '../lib/tui'
|
|
4
|
+
import { findRealDirectories } from '../lib/helpers'
|
|
5
|
+
|
|
6
|
+
export const cleanCmd = new Command('clean')
|
|
7
|
+
.description('Clean disposable files')
|
|
8
|
+
|
|
9
|
+
.option('-d, --directories <directories...>', 'problem directories', ['.'])
|
|
10
|
+
.option('-a, --all', 'clean all disposable files (including generated statement and correct files', false)
|
|
11
|
+
.addOption(new Option('-f, --force', 'force removal').conflicts('dryRun'))
|
|
12
|
+
.addOption(new Option('-n, --dry-run', 'show but do not remove files').conflicts('force'))
|
|
13
|
+
|
|
14
|
+
.action(async ({ directories, all, force, dryRun }) => {
|
|
15
|
+
const isForce = force || false // default to dry-run if neither option is specified
|
|
16
|
+
|
|
17
|
+
await tui.section(`Cleaning generated files`, async () => {
|
|
18
|
+
const realDirectories = await findRealDirectories(directories)
|
|
19
|
+
for (const directory of realDirectories) {
|
|
20
|
+
await tui.section(`Cleaning directory ${tui.hyperlink(directory)}`, async () => {
|
|
21
|
+
await cleanDirectory(isForce, all, directory)
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
})
|
package/toolkit/clone.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings'
|
|
2
|
+
import { createProblemWithTemplate } from '../lib/create-with-template'
|
|
3
|
+
|
|
4
|
+
export const cloneCmd = new Command('clone')
|
|
5
|
+
.description('Clone a template into a new problem')
|
|
6
|
+
|
|
7
|
+
.argument('[template]', 'template to use (empty to interactive selection)')
|
|
8
|
+
.option('-d, --directory <path>', 'output directory', 'new-problem.pbm')
|
|
9
|
+
|
|
10
|
+
.action(async (template, { directory }) => {
|
|
11
|
+
await createProblemWithTemplate(directory, template)
|
|
12
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getAvailableCompilers, getCompilersInfo, getDefinedCompilerIds } from '../lib/compilers'
|
|
2
|
+
import { Command } from '@commander-js/extra-typings'
|
|
3
|
+
|
|
4
|
+
export const compilersCmd = new Command('compilers')
|
|
5
|
+
.description('Query compiler information')
|
|
6
|
+
// default action is to list all compilers because of older compatibility
|
|
7
|
+
|
|
8
|
+
.action(async () => {
|
|
9
|
+
const info = await getCompilersInfo()
|
|
10
|
+
console.dir(info)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
compilersCmd
|
|
14
|
+
.command('list-defined')
|
|
15
|
+
.description('List all defined compiler names')
|
|
16
|
+
|
|
17
|
+
.action(async () => {
|
|
18
|
+
const items = await getDefinedCompilerIds()
|
|
19
|
+
console.dir(items)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
compilersCmd
|
|
23
|
+
.command('list-available')
|
|
24
|
+
.description('List all available compiler names')
|
|
25
|
+
|
|
26
|
+
.action(async () => {
|
|
27
|
+
const items = await getAvailableCompilers()
|
|
28
|
+
console.dir(items)
|
|
29
|
+
})
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings'
|
|
2
|
+
import { confirm } from '@inquirer/prompts'
|
|
3
|
+
import { editor } from '@inquirer/prompts'
|
|
4
|
+
import YAML from 'yaml'
|
|
5
|
+
import { ZodError } from 'zod'
|
|
6
|
+
import { fromError } from 'zod-validation-error'
|
|
7
|
+
import { configPath, loadSettings, saveSettings, settings } from '../lib/settings'
|
|
8
|
+
import { Settings } from '../lib/types.ts'
|
|
9
|
+
import tui from '../lib/tui.ts'
|
|
10
|
+
import { convertStringToItsType } from '../lib/utils.ts'
|
|
11
|
+
|
|
12
|
+
export const configCmd = new Command('config')
|
|
13
|
+
.summary('Manage configuration')
|
|
14
|
+
.description(
|
|
15
|
+
`Manage configuration
|
|
16
|
+
|
|
17
|
+
The actual configuration file is stored at ${configPath()}`,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
.action(() => {
|
|
21
|
+
configCmd.help()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
configCmd
|
|
25
|
+
.command('show')
|
|
26
|
+
.alias('list')
|
|
27
|
+
.description('Show configuration options')
|
|
28
|
+
|
|
29
|
+
.action(async () => {
|
|
30
|
+
const settings = await loadSettings()
|
|
31
|
+
tui.yaml(settings)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
configCmd
|
|
35
|
+
.command('get <key>')
|
|
36
|
+
.description('Get the value of a configuration option')
|
|
37
|
+
|
|
38
|
+
.action((key: string) => {
|
|
39
|
+
if (!(key in settings)) {
|
|
40
|
+
throw new Error(`Configuration key ${key} does not exist`)
|
|
41
|
+
}
|
|
42
|
+
console.log((settings as any)[key])
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
configCmd
|
|
46
|
+
.command('set <key> <value>')
|
|
47
|
+
.description('Set the value of a configuration option')
|
|
48
|
+
|
|
49
|
+
.action(async (key: string, value: string) => {
|
|
50
|
+
if (!(key in settings)) {
|
|
51
|
+
throw new Error(`Configuration key ${key} does not exist`)
|
|
52
|
+
}
|
|
53
|
+
const convertedValue = convertStringToItsType(value)
|
|
54
|
+
const newSettings = Settings.parse({ ...settings, [key]: convertedValue })
|
|
55
|
+
await saveSettings(newSettings)
|
|
56
|
+
tui.success(`Configuration key ${key} updated successfully`)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
configCmd
|
|
60
|
+
.command('edit')
|
|
61
|
+
.description('Open an editor (uses $EDITOR or $VISUAL) to modify the configuration options')
|
|
62
|
+
|
|
63
|
+
.action(async () => {
|
|
64
|
+
let data = YAML.stringify(settings, null, 4)
|
|
65
|
+
while (true) {
|
|
66
|
+
const newData = await editor({
|
|
67
|
+
message: 'Edit configuration',
|
|
68
|
+
default: data,
|
|
69
|
+
postfix: '.yml',
|
|
70
|
+
waitForUserInput: false,
|
|
71
|
+
})
|
|
72
|
+
try {
|
|
73
|
+
const newSettings = Settings.parse(YAML.parse(newData))
|
|
74
|
+
await saveSettings(newSettings)
|
|
75
|
+
tui.success('Configuration options updated successfully')
|
|
76
|
+
return
|
|
77
|
+
} catch (error) {
|
|
78
|
+
if (error instanceof ZodError) {
|
|
79
|
+
console.error(fromError(error).toString())
|
|
80
|
+
} else {
|
|
81
|
+
console.error(error)
|
|
82
|
+
}
|
|
83
|
+
const again = await confirm({ message: 'Edit again?', default: true })
|
|
84
|
+
if (!again) {
|
|
85
|
+
tui.warning('No changes made to the configuration options')
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
data = newData
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
configCmd
|
|
94
|
+
.command('reset')
|
|
95
|
+
.description('Reset configuration to default values')
|
|
96
|
+
|
|
97
|
+
.option('-f, --force', 'force reset without confirmation', false)
|
|
98
|
+
|
|
99
|
+
.action(async ({ force }) => {
|
|
100
|
+
if (!force) {
|
|
101
|
+
const confirmReset = await confirm({
|
|
102
|
+
message: 'Are you sure you want to reset the configuration to default values?',
|
|
103
|
+
default: false,
|
|
104
|
+
})
|
|
105
|
+
if (!confirmReset) {
|
|
106
|
+
tui.warning('Reset cancelled')
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const defaultSettings = Settings.parse({})
|
|
111
|
+
await saveSettings(defaultSettings)
|
|
112
|
+
tui.success('Configuration reset to default values successfully')
|
|
113
|
+
})
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings'
|
|
2
|
+
import { createProblemWithJutgeAI } from '../lib/create-with-jutgeai'
|
|
3
|
+
import { createProblemWithTemplate } from '../lib/create-with-template'
|
|
4
|
+
import { settings } from '../lib/settings'
|
|
5
|
+
|
|
6
|
+
export const createCmd = new Command('create')
|
|
7
|
+
.description('Create a new problem')
|
|
8
|
+
|
|
9
|
+
.action(() => {
|
|
10
|
+
createCmd.help()
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
createCmd
|
|
14
|
+
.command('with-template')
|
|
15
|
+
.description('Create a problem with a template')
|
|
16
|
+
|
|
17
|
+
.argument('[template]', 'template to use (empty to interactive selection)')
|
|
18
|
+
.option('-d, --directory <path>', 'output directory', 'new-problem.pbm')
|
|
19
|
+
|
|
20
|
+
.action(async (template, { directory }) => {
|
|
21
|
+
await createProblemWithTemplate(directory, template)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
createCmd
|
|
25
|
+
.command('with-ai')
|
|
26
|
+
.description('Create a problem with JutgeAI')
|
|
27
|
+
|
|
28
|
+
.option('-d, --directory <path>', 'output directory', 'new-problem.pbm')
|
|
29
|
+
.option('-i, --input <path>', 'input specification file')
|
|
30
|
+
.option('-o, --output <path>', 'output specification file')
|
|
31
|
+
.option('-n, --do-not-ask', 'do not ask interactively if --input given', false)
|
|
32
|
+
.option('-m, --model <model>', 'AI model to use', settings.defaultModel)
|
|
33
|
+
|
|
34
|
+
.action(async ({ input, output, directory, model, doNotAsk }) => {
|
|
35
|
+
await createProblemWithJutgeAI(model, directory, input, output, doNotAsk)
|
|
36
|
+
})
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as doc from '../lib/doctor'
|
|
2
|
+
import { Command } from '@commander-js/extra-typings'
|
|
3
|
+
import tui from '../lib/tui'
|
|
4
|
+
|
|
5
|
+
export const doctorCmd = new Command('doctor')
|
|
6
|
+
.description('Diagnose status of the environment')
|
|
7
|
+
|
|
8
|
+
.action(async () => {
|
|
9
|
+
await tui.section('Perform checks', async () => {
|
|
10
|
+
await tui.section('Checking Python3 installation', doc.checkPython3)
|
|
11
|
+
await tui.section('Checking C/C++ installation', doc.checkGCC)
|
|
12
|
+
await tui.section('Checking Haskell installation', doc.checkHaskell)
|
|
13
|
+
await tui.section('Checking Clojure installation', doc.checkClojure)
|
|
14
|
+
await tui.section('Checking Java installation', doc.checkJava)
|
|
15
|
+
await tui.section('Checking Rust installation', doc.checkRust)
|
|
16
|
+
await tui.section('Checking XeLaTeX installation', doc.checkXeLaTeX)
|
|
17
|
+
await tui.section('Checking Pandoc installation', doc.checkPandoc)
|
|
18
|
+
await tui.section('Checking ImageMagick installation', doc.checkImageMagick)
|
|
19
|
+
await tui.section('Checking AI models', doc.checkAIEnvVars)
|
|
20
|
+
await tui.section('Checking terminal', doc.checkTerminal)
|
|
21
|
+
})
|
|
22
|
+
})
|