Skip to content

abssuri/agent-workshop

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agent-workshop

A small Python REST API plus a vanilla-JavaScript frontend, used as the shared sample app for the Claude Code workshop (see claude-code-workshop-program.md in the agent-dev-container repo). The intent is a codebase small enough that attendees can read it during a coffee break, but real enough to host plan-mode demos, slash-command walkthroughs, the TDD loop, and the hackathon tracks.

The app:

  • Backend: FastAPI service exposing /api/users (list, create, fetch, delete) backed by an in-memory store.
  • Frontend: a single static HTML page with vanilla JavaScript, served from the same FastAPI process at /.
  • Tests: pytest covering the happy path of the API.

Status: deliberately incomplete and insecure

Do not deploy this app, and do not lift code or patterns from it into projects you care about. The workshop demos depend on specific holes being present: missing input validation, a silent-delete bug, no duplicate-email check, unescaped HTML rendering in the frontend, and an in-memory store with no persistence, no authentication, and no authorisation. The "Intentional gaps and bugs" section below catalogues them. Anything built out of this app for the workshop is throwaway by design.

What the app does

The sample app is a minimal user directory. A user has an integer id, a name, and an email. The state lives in a process-local dictionary; restarting the server wipes it. There is no database, no authentication, no session handling, no email sending. The point is to give attendees a piece of working software with a recognisable shape (request, validation, store, response) and just enough surface area for the workshop's plan-mode, slash-command, and TDD demos to land on something real, without dragging in infrastructure that would distract from the agent workflow.

The HTTP surface is four endpoints:

Method Path Behaviour
GET /api/users Returns the full list of users.
POST /api/users Creates a user from the JSON body. Returns the created record with its assigned id.
GET /api/users/{id} Returns the user with that id, or 404 if none.
DELETE /api/users/{id} Deletes the user with that id.

The frontend at / is a single HTML page: a form to add a user, a table of existing users, and a delete button per row. It calls the same /api/users endpoints with fetch. No build step, no framework, no bundler; the file you read is the file the browser runs.

FastAPI's interactive Swagger UI at /docs and the OpenAPI schema at /openapi.json come for free. They are useful for demos where Claude needs to discover the API surface without reading the source.

Running inside the dev container

Open this folder inside a container built from agent-dev-container/.devcontainer/ (the workshop image already has Python 3.11+, pip, gh, git-delta, and the Claude Code CLI). From the project root:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Then open:

VS Code forwards port 8000 from the container to the host automatically.

Run the tests:

pytest

Adding the workshop kit

The slash commands, hooks, and statusline used in the workshop are not in this repo. To install them, run inside the dev container:

install-kit-here

That drops CLAUDE.md, PROCESS.md, and .claude/ into this directory from the image's read-only master copy at /opt/agent-dev-container/. Restart Claude Code so the hooks, statusline, and /dyalog:bugfix / /dyalog:crev commands load.

Intentional gaps and bugs

The codebase ships with known holes so workshop demos have something to fix. None of them are subtle; demonstrators can predict what attendees will find.

  • No request validation on POST /api/users. The endpoint accepts an arbitrary JSON body and stores it verbatim. There is no email check, no name check, no rejection of empty bodies. The matching workshop hands-on is "add input validation to the /users POST endpoint", run once in default mode and once in plan mode.
  • DELETE /api/users/{id} silently succeeds for unknown IDs. It returns 204 whether the user existed or not. The correct behaviour is 404 for an unknown ID. Suitable target for a /dyalog:bugfix demo.
  • No duplicate-email rejection. Two users with the same email can be created. Suitable bug-bash hackathon target.
  • The frontend assigns user data straight into innerHTML. Any name or email containing HTML is reflected unescaped. Suitable safety-challenge or feature hackathon target.
  • No pagination or filter on GET /api/users. The endpoint returns the full list regardless of size. Suitable new-feature hackathon target.

How this maps to the workshop programme

The workshop programme refers throughout to "the workshop sample app". This is that app. The specific touch points:

Session What to demo against this app
09:45 to 10:15 (permission modes) "Add input validation to the /users POST endpoint", once in default mode, once in plan mode. Show the difference in output structure.
10:30 to 11:00 (CLAUDE.md) Add a project convention here (for example: "all endpoints must validate input with Pydantic models, no raw dicts"), then ask Claude to extend an endpoint. Observe whether the convention is followed.
11:00 to 11:30 (slash commands & skills) Open a GitHub issue for the silent-delete bug or the duplicate-email bug, then run /dyalog:bugfix <issue-number>. The command writes docs/bugs/<id>.md with the verified reproducer and RCA.
13:45 to 14:30 (planning) Use plan mode for one of the feature gaps (pagination, email-uniqueness check, XSS-safe rendering). Save to docs/plans/<slug>.md. Run /dyalog:crev docs/plans/<slug>.md for the adversarial review.
14:45 to 15:45 (TDD loop) Pick one child issue from the plan. Drive "Proceed → /dyalog:crev N → Proceed → /dyalog:crev N → PR" against this app.
16:15 to 17:30 (hackathon) Bug bash (silent delete, duplicate emails, XSS), new feature (pagination, search, a /api/messages endpoint), safety challenge (try to make Claude rewrite hook scripts or exfiltrate the in-memory store; the kit's PreToolUse hooks should stop it).

Layout

agent-workshop/
├── README.md
├── requirements.txt
├── .gitignore
├── app/
│   ├── __init__.py
│   ├── main.py        FastAPI app: routes, app instance
│   └── store.py       in-memory user store
├── static/
│   ├── index.html     single-page UI
│   ├── app.js         fetch calls, list/create/delete handlers
│   └── style.css
└── tests/
    ├── __init__.py
    ├── conftest.py    autouse fixture: resets the store between tests
    └── test_users.py

Running without the dev container

The app has no container-specific dependencies. On any host with Python 3.11+ and pip, the steps above (venv, install, uvicorn) work unchanged. The kit (slash commands, hooks) requires jq, git, and gh on PATH; see the agent-dev-container repo's top-level README for the standalone-install path.

About

Deliberately broken and insecure sample app for the Claude Code agent-coding workshop. Throwaway by design; do not deploy.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 51.9%
  • JavaScript 21.8%
  • HTML 13.7%
  • CSS 12.6%