Your First Real Code Task — End to End

Walk through the complete cycle: create a dev issue, trigger the heartbeat, watch the agent edit files, and read the structured result with file diffs.

Your First Real Code Task — End to End

What you'll learn

Go from zero to watching the agent make a real file change in your project — creating the issue, triggering the heartbeat, monitoring the run, and reading the result.


Before you start

Confirm from the previous topics:
- [ ] Paperclip is running (pnpm dev)
- [ ] AGENT_WORKING_DIR points to your project
- [ ] Your project is on the paperclip-agent git branch
- [ ] A company and a claude-code agent have been created (Module 2)

Set these shell variables for convenience:

export BASE=http://localhost:3100/api
export COMPANY_ID=<your-company-id>
export AGENT_ID=<your-claude-code-agent-id>

Step 1 — Capture the current git state

Before any agent work, record the baseline so you can diff cleanly:

cd ~/projects/my-api
git status          # should be clean
git log --oneline -3
# e3a9f1c initial commit before paperclip agent work

Step 2 — Create a real dev issue

Use a concrete task from your actual project. For this walkthrough we'll add a health-check endpoint — a small, safe, verifiable change:

curl -X POST $BASE/companies/$COMPANY_ID/issues \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Add GET /health endpoint",
    "description": "## Task\nAdd a health-check endpoint to the Express app.\n\n## Spec\n- Method: GET\n- Path: /health\n- Response: `{ status: \"ok\", uptime: <process.uptime()>, timestamp: <Date.now()> }`\n- No auth required\n- Register in `src/app.ts`\n\n## Acceptance criteria\n- [ ] Endpoint responds with 200\n- [ ] Response matches the shape above\n- [ ] `npm test` passes\n\n## Do not change\n- Do not modify any existing routes\n- Do not change package.json",
    "assigned_agent_id": "'$AGENT_ID'",
    "priority": "medium"
  }'

Note the id in the response:

{ "id": "01929f3a-xxxx", "status": "open", "title": "Add GET /health endpoint" }
export ISSUE_ID=01929f3a-xxxx

Step 3 — Trigger the heartbeat manually

Don't wait for the cron tick — trigger it now:

curl -X POST $BASE/heartbeat/run \
  -H "Content-Type: application/json" \
  -d '{"company_id": "'$COMPANY_ID'"}'

Response:

{
  "run_id": "01929f40-yyyy",
  "status": "running",
  "agents_invoked": 1,
  "issues_claimed": 1
}
export RUN_ID=01929f40-yyyy

Step 4 — Watch it run in real time

Poll the run status while the agent works:

watch -n 2 "curl -s $BASE/heartbeat/runs/$RUN_ID | python3 -m json.tool"

You'll see status move through:

"running" → "running" → "completed"

While it's running, tail the Paperclip server logs in the other terminal:

[adapter:claude-code] Invoking agent on /Users/you/projects/my-api
[adapter:claude-code] Agent reading: src/app.ts
[adapter:claude-code] Agent reading: src/routes/
[adapter:claude-code] Agent writing: src/routes/health.ts
[adapter:claude-code] Agent editing: src/app.ts
[adapter:claude-code] Agent running: npm test
[adapter:claude-code] Run complete. 2 files changed. Cost: $0.031

Step 5 — Read the issue result

curl -s $BASE/companies/$COMPANY_ID/issues/$ISSUE_ID | python3 -m json.tool
{
  "id": "...",
  "status": "resolved",
  "result": "Added GET /health endpoint...\n\nFiles changed:\n- src/routes/health.ts (created)\n- src/app.ts (modified, line 23)",
  "result_structured": {
    "summary": "Added health endpoint returning status, uptime, and timestamp",
    "changedFiles": [
      { "path": "src/routes/health.ts", "action": "created" },
      { "path": "src/app.ts", "action": "modified" }
    ],
    "testsRan": true,
    "testsPassed": true
  },
  "cost_usd": "0.031"
}

Step 6 — See the actual file changes

cd ~/projects/my-api
git diff

You should see something like:

diff --git a/src/app.ts b/src/app.ts
index 3b2f1c9..a7e4d21 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -12,6 +12,7 @@ import { authRouter } from './routes/auth';
+import { healthRouter } from './routes/health';

 app.use('/api/auth', authRouter);
+app.use('/health', healthRouter);

diff --git a/src/routes/health.ts b/src/routes/health.ts
new file mode 100644
--- /dev/null
+++ b/src/routes/health.ts
@@ -0,0 +1,12 @@
+import { Router } from 'express';
+
+export const healthRouter = Router();
+
+healthRouter.get('/', (req, res) => {
+  res.json({
+    status: 'ok',
+    uptime: process.uptime(),
+    timestamp: Date.now(),
+  });
+});

The agent created a new file and wired it up — exactly what the issue asked for.


Step 7 — Verify it works

cd ~/projects/my-api
npm test
npm run dev &       # start the server
curl http://localhost:3000/health
# {"status":"ok","uptime":2.3,"timestamp":1748000000000}

Checkpoint ✓

Sign in for progress tracking & Q&A →