Workspaces
Download sample cases
cpg download (cpg d) downloads one problem's samples into ./test/.
It does not require a workspace root or copy templates, run setup commands, or write metadata.
Use -d / --directory to choose another sample directory. Existing sample files
are never overwritten; unrelated files in the directory are preserved.
cpg d https://atcoder.jp/contests/abc473/tasks/abc473_f
cpg d https://atcoder.jp/contests/abc473/tasks/abc473_f -d samples
Workspace root
The directory you downloaded a single problem or contest problems will be called a "workspace".
Workspaces will be located under the workspace root, which is configured in ~/.config/cpg/config.toml.
For example, if the workspace root is ~/competitive-programming, a single problem
downloaded from AtCoder will be located at ~/competitive-programming/atcoder/problems/abc473_f, and a
contest will be located at ~/competitive-programming/atcoder/contests/abc473.
This feature is heavily inspired by ghq, a git repository management tool
which fixes the directory structure for git repositories. ($root/$host/$path, like ~/ghq/github.com/sevenc-nanashi/competitive-programming-cli)
After using cpg for a while, your workspace root will look like this:
~/cpg/
atcoder/
contests/
- aalc001/
- abc465/
- abc466/
- abc467/
- .../
- adt_all_20260908_1/
- adt_all_20260909_1/
- .../
problems/
- abc294_g/
- abc313_d/
- .../
yukicoder/
contests/
- 594/
- .../
share-oj/
contests/
- dc6fc9dd-4019-463a-a486-12c3fc10af59/
problems/
- 898f6783-900e-4035-9a03-500571a20d06/
- 796156e7-bc25-4b68-82ec-494135b75dc5/
- .../
- .../
Prepare a single problem
You can download a single problem from a contest. The directory will contain:
.cpg.tomlfile, which contains metadata of the problem.- Workspace template files.
- Problem template files.
- Single problem template files.
- Test cases (stored in
test/sample-1.inandtest/sample-1.out).
Samples are always numbered starting at 1, even when there is only one.
Additional samples are named sample-2.in, sample-2.out, etc.
The .cpg.toml metadata records the service, problem ID, canonical URL, title,
and original contest/internal IDs where applicable.
Check Templates and Setup Commands for more information about templates and setup commands.
# Download a problem from AtCoder
cpg prepare https://atcoder.jp/contests/abc473/tasks/abc473_f
# Or shorthand
cpg p https://atcoder.jp/contests/abc473/tasks/abc473_f
Your single problem directory will look like this:
abc473_f/
- .cpg.toml
- ac-library/
test/
- sample-1.in
- sample-1.out
- sample-2.in
- sample-2.out
- sample-3.in
- sample-3.out
- sample-4.in
- sample-4.out
- Gemfile
- Gemfile.lock
- compile_flags.txt
- judge.rb
- main.cpp
- main.rb
- naive.rb
Prepare contest
You can download all problems from a contest. The contest directory will contain:
.cpg.tomlfile, which contains metadata of the contest.- Workspace template files.
- Contest template files.
The problem directories will contain:
- Problem template files.
- Problem metadata and sample test cases.
- (Note that this does not contain workspace template files)
Contest metadata retains the ordered problem list.
Refer to Templates and Setup Commands for more information about templates and setup commands.
# Download contest problems from AtCoder
cpg prepare https://atcoder.jp/contests/abc473
# Or shorthand
cpg p https://atcoder.jp/contests/abc473
Your contest directory will look like this:
abc479/
- .cpg.toml
- ac-library/
1_abc479_a/
- .cpg.toml
test/
- sample-1.in
- sample-1.out
- sample-2.in
- sample-2.out
- sample-3.in
- sample-3.out
- main.cpp
- main.rb
- naive.rb
- judge.rb
- 2_abc479_b/
- 3_abc479_c/
- 4_abc479_d/
- 5_abc479_e/
- 6_abc479_f/
- 7_abc479_g/
- Gemfile
- Gemfile.lock
- compile_flags.txt
Open the current problem or contest in your browser
cpg open
# Or shorthand
cpg o
Opens the problem or contest URL from the nearest .cpg.toml in your default
browser. This also works from subdirectories. A problem directory inside a
contest opens that problem; the contest directory opens the contest page.
Use --url-only to print just the URL to stdout without opening a browser:
cpg open --url-only
# Or shorthand
cpg o -n
Or use --clipboard to copy the URL to the clipboard instead of opening a browser:
cpg open --clipboard
# Or shorthand
cpg o -c
List workspaces
You can list the workspaces you've downloaded using the list command.
By default, list shows workspace directories: contests and single problems.
Paths are relative to the workspace root, which you can get with cpg config --root.
Choose one of the following mutually exclusive filters:
| Option | Directories listed |
|---|---|
--workspace (default) |
Contests and single problems |
--contests |
Contests |
--problems |
Single problems |
--all-problems |
Single problems and individual contest problems |
# List workspaces you've downloaded
cpg list
# Show the workspace root
cpg config --root
# List contest directories
cpg list --contests
# List single problem directories
cpg list --problems
# Include individual problems within contests
cpg list --all-problems
Use --format (-f) to customize each output line.
| Placeholder | Description |
|---|---|
{path} |
Relative path from the workspace root |
{service} |
Online judge service name |
{id} |
Problem or contest ID |
{title} |
Problem or contest title |
{url} |
Problem or contest URL |
\t |
Tab character |
cpg list --format '{path}\t{path} ({title})'
Use --delimiter to choose the separator appended after each record:
line (the default newline), null (NUL), tab, or any single character.
For example, pass NUL-separated records to fzf --read0:
cpg list -f '{path}\t{path} ({title})' --delimiter null |
fzf --read0 --delimiter=$'\t' --with-nth=2..
This command is for piping the output to other commands, such as fzf.
If you need more advanced formatting, you can use --json to output JSON for each record
and parse it with jq or other JSON tools.
For example, you can create ccd command which changes the current working directory to the selected problem's directory.
ccd() {
local root dir
root="$(CPG_LOG=none cpg config --root)" || return
dir="$(CPG_LOG=none cpg list -f '{path}\t{path} ({title})' | fzf --delimiter=$'\t' --with-nth=2..)" || return
dir="${dir%%$'\t'*}"
[ -n "$dir" ] && cd -- "$root/$dir"
}