You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Summary
- split the challenge runtime Nix package into `runtime/platform`
- add a `runtime/workspace` build env with a Go workspace entrypoint,
supervisor, and uid 1000 agent
- add dynamic workspace services for tty, desktop, and code, proxied
over Unix sockets
- package `pwnshop` as a proper Python application in the Nix store and
remove the root wrapper
## Validation
- `tools/git-hooks/pre-commit`
- `nix fmt -- --fail-on-change`
- `nix shell nixpkgs#go nixpkgs#gcc --command go test ./...` in
`runtime/workspace/agent`
- `python -m py_compile tools/pwnshop/src/pwnshop/commands/run.py
tools/pwnshop/src/pwnshop/lib/__init__.py`
- Nix builds for `runtime/platform`, `runtime/workspace`, and
`tools/pwnshop`
- packaged `pwnshop --help` and `pwnshop list challenges/program-misuse`
`nix develop` is required for `pwnshop`. Always enter the dev shell before invoking `pwnshop`(or `./pwnshop`) -- if anything fails unexpectedly, your first check should be whether you are inside the dev shell.
80
+
`nix develop` is required for `pwnshop`. Always enter the dev shell before invoking `pwnshop` -- if anything fails unexpectedly, your first check should be whether you are inside the dev shell.
Copy file name to clipboardExpand all lines: README.md
+14-14Lines changed: 14 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,21 +32,21 @@ git crypt unlock
32
32
33
33
# Challenge CLI
34
34
35
-
All developer workflows now run through the `./pwnshop` command. The legacy `./build` helper has been removed, so every rendered, build, run, or test action should use the new CLI instead.
35
+
All developer workflows now run through the `pwnshop` command provided by `nix develop`. The legacy `./build` helper and root `./pwnshop` wrapper have been removed, so every rendered, build, run, or test action should use the packaged CLI instead.
36
36
37
37
The CLI is implemented with Click and Rich (`tools/pwnshop/src/pwnshop/commands/*.py`) on top of the core helper library in `tools/pwnshop/src/pwnshop/lib/__init__.py`. Keeping formatting/terminal logic in the commands and reusable challenge logic in `tools/pwnshop/src/pwnshop/lib` makes it easy to add or modify commands without duplicating functionality.
38
38
39
39
All CLI subcommands accept either a direct filesystem path or a challenge slug. Slugs must include the module (e.g., `web-security/path-traversal-1`); the tool searches under `./challenges` for that module/challenge pair and errors if nothing matches.
40
40
41
41
Primary entry points:
42
42
43
-
-`./pwnshop list` — enumerate challenges, optionally filtered via `--modified-since`.
44
-
-`./pwnshop render` — materialize a challenge directory or individual template (`--output` defaults to stdout and Rich labels each file when multiple outputs are rendered).
45
-
-`./pwnshop build` — render and build a challenge, returning the Docker image ID.
46
-
-`./pwnshop test` — render, build, and run all `test*/test_*` files inside the challenge.
47
-
-`./pwnshop run` — render, build, and drop into an interactive shell inside the challenge container (use `--user=<uid>` to control the interactive user, default `1000`, `--volume <path>` to mount host paths read-only, or append a command after the challenge to run it instead of `/bin/bash`).
43
+
-`pwnshop list` — enumerate challenges, optionally filtered via `--modified-since`.
44
+
-`pwnshop render` — materialize a challenge directory or individual template (`--output` defaults to stdout and Rich labels each file when multiple outputs are rendered).
45
+
-`pwnshop build` — render and build a challenge, returning the Docker image ID.
46
+
-`pwnshop test` — render, build, and run all `test*/test_*` files inside the challenge.
47
+
-`pwnshop run` — render, build, and drop into an interactive shell inside the challenge container (use `--user=<uid>` to control the interactive user, default `1000`, `--volume <path>` to mount host paths read-only, or append a command after the challenge to run it instead of `/bin/bash`).
48
48
49
-
Any future automation that renders, builds, runs, or tests challenges should shell out to `./pwnshop ...` rather than reimplementing those pieces of the workflow.
49
+
Any future automation that renders, builds, runs, or tests challenges should shell out to `pwnshop ...` rather than reimplementing those pieces of the workflow.
50
50
51
51
The standalone `discord-feedback` helper is available in `nix develop` for Discord-derived curriculum feedback automation.
52
52
@@ -122,7 +122,7 @@ nix develop
122
122
More details: `docs/development.md`.
123
123
124
124
If you are not using Nix, you will need a working Docker setup and the Python tooling for `pwnshop`.
125
-
At minimum, install `uv` and then use `./pwnshop ...` (it will manage Python deps from `tools/pwnshop/uv.lock`).
125
+
At minimum, install the Python dependencies for `tools/pwnshop` or run it with `uv run --project tools/pwnshop --with-editable tools/pwnshop pwnshop ...`.
126
126
127
127
For legacy/manual environments, you can still install a basic set of Python packages in a virtual environment:
# list challenges, optionally filtered by git history
149
-
./pwnshop list --modified-since origin/main
149
+
pwnshop list --modified-since origin/main
150
150
```
151
151
152
152
## Important Notes / Common Gotchas
@@ -181,7 +181,7 @@ The process of porting is:
181
181
6. If using templates, use `{% extends %}` and `{% block setup %}` for customization
182
182
7. Ensure all executable files are marked as such: `chmod +x ./$MODULE_ID/$CHALLENGE_ID/**/*.j2`. Rendered files inherit permissions from the template.
183
183
8. Port verification logic to `./$MODULE_ID/$CHALLENGE_ID/tests_public` (functionality) and `./$MODULE_ID/$CHALLENGE_ID/tests_private` (exploitation)
184
-
9. Test thoroughly: `./pwnshop test $MODULE_ID/$CHALLENGE_ID`
184
+
9. Test thoroughly: `pwnshop test $MODULE_ID/$CHALLENGE_ID`
185
185
10. Once testcases pass, double-check the template (both rendered and at rest) against the legacy challenge to ensure that the challenge has been ported without any functionality change.
0 commit comments