New src/git/pr.ts helper wraps 'gh pr create'; returns { url } or { error }.
maybeCreateAutoPr() in update-job-status checks product.auto_pr, builds title
from story.code + task.title, writes pr_url to DB. Non-fatal: gh failure logs
a warning and leaves DONE status intact. Also syncs schema: auto_pr on Product,
pr_url on ClaudeJob.
resetStaleClaimedJobs now uses $queryRaw with RETURNING so it can send pg_notify
claude_job_status events per transitioned job. Jobs under the retry limit are
re-queued with retry_count incremented; jobs at ≥2 retries are marked FAILED.
Runs git push -u origin <branch> in the worktree. Detects no-changes
(HEAD = origin/main) before pushing. Classifies push failures into
no-credentials, conflict, or unknown via stderr pattern matching.
5 unit tests covering all paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On DONE/FAILED, resolves repoRoot and calls removeWorktreeForJob (best-effort).
keepBranch=true when status=done and agent reported a branch (push assumed);
false otherwise. Cleanup failures are logged as warnings — DB status is preserved.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After claiming a job, resolves repoRoot (env SCRUM4ME_REPO_ROOT_<productId>
or ~/.scrum4me-agent-config.json), creates a git worktree, and returns
worktree_path + branch_name in the response. Rolls back claim to QUEUED
on failure. Tool description updated to instruct agent to work in worktree.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes worktree dir via `git worktree remove --force` and deletes
the local branch by default; keepBranch=true preserves the branch.
Returns { removed: false } when the worktree path doesn't exist.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Points to the merge commit of PR #23 on Scrum4Me/main so the submodule
tracks origin instead of the local-only pre-merge commit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
23 unit tests covering parseAcceptanceCriteria, extractKeywords,
checkACStatus, computeDriftScore, lineDiff, and 4 end-to-end scenarios
(plan unchanged, edited, AC missed, no baseline). README documents the
tool with example output and heuristic limitations.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Read-only tool that compares frozen plan_snapshot against current
task.implementation_plan + story logs + commits. Returns markdown report
with per-AC ✓/✗/? keyword heuristic, drift-score, and plan diff.
Demo users allowed (readOnlyHint: true).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Keeps prisma/schema.prisma in sync with vendor/scrum4me so
prisma:generate produces the updated ClaudeJob client types.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- resetStaleClaimedJobs: also sets plan_snapshot = NULL on reset
- tryClaimJob: JOINs tasks table to read implementation_plan in the
same atomic transaction, writes it to claude_jobs.plan_snapshot
- Empty-plan edge case: NULL becomes '' (non-null) in snapshot
- Exports both functions for unit testing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Points submodule to Scrum4Me a3af2dd which adds ClaudeJob.plan_snapshot
field; regenerated Prisma client includes the new column.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tasks-status-update.test.ts: 7 tests covering promote, idempotent
promote, partial-siblings no-promote, demote, no-demote-when-not-done,
task-always-updated, and custom tx client pass-through.
get-claude-context-filter.test.ts: 3 tests verifying the OR tasks
filter is passed, sprint_id/status filter is present, and no story
query fires when there is no active sprint.
update_task_status now delegates to updateTaskStatusWithStoryPromotion
and surfaces story_status_change ('promoted' | 'demoted' | null) in the
response so Claude Code can act on story completion without a separate
read call.
get_claude_context adds an OR-filter on tasks so stories where every
task is DONE are skipped — only surfaces stories that still have work to
do (no tasks, or at least one non-DONE task).
Ported transactional story-promotion logic from Scrum4Me app. Promotes
parent story to DONE when all sibling tasks transition to DONE; demotes
back to IN_SPRINT when a task is re-opened on a DONE story. Accepts an
optional tx client to support existing transaction contexts.
- wait_for_job: blocks ≤600s, claims QUEUED job atomically via FOR UPDATE
SKIP LOCKED, resets stale CLAIMED jobs (>30min), registers ClaudeWorker
presence with heartbeat, emits worker_connected/disconnected via NOTIFY
- update_job_status: agent reports running|done|failed, validates token
ownership (claimed_by_token_id), emits claude_job_status via NOTIFY
- auth.ts extended with tokenId so tools can set claimed_by_token_id
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tot nu toe konden MCP-tools alleen bestaande stories/tasks bewerken
(update_task_status, log_*). Met deze drie tools kan Claude Code een
volledige backlog vanaf nul opbouwen — handig voor nieuwe projecten waar
het Scrum4Me-product nog leeg is.
- create_pbi: { product_id, title, description?, priority, sort_order? }
Auto sort_order = last+1 binnen prio-groep. Code-veld blijft null
(Scrum4Me-app genereert auto-codes via UI/seed).
- create_story: { pbi_id, title, description?, acceptance_criteria?, priority,
sort_order? } — product_id afgeleid uit PBI (denormalized FK conform CLAUDE.md
convention; nooit op client-input vertrouwen). Status='OPEN' default →
landt in product-backlog, niet auto in een sprint.
- create_task: { story_id, title, description?, implementation_plan?, priority,
sort_order? } — sprint_id geërfd van story. Status='TO_DO' default.
Alle drie achter `requireWriteAccess` (PERMISSION_DENIED voor demo) +
`userCanAccessProduct` op de relevante parent-product. Mirror van het
create-todo-patroon.
scripts/smoke-test.ts: tool-count check 13 → 16. README.md: tool-tabel
uitgebreid.
Quality gates: typecheck clean, build success, smoke-test toont 16 tools.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Was: 79367dd (M11 ST-1101 op feature-branch — niet meer reachable na squash-merge)
Nu: 9587ff4 (M11 squash-merge op origin/main — stabiele referentie)
prisma/schema.prisma is byte-identical (geen schema-drift; alleen submodule-
pointer gewijzigd zodat de pin verwijst naar een commit die op origin reachable
blijft).
npm run sync-schema + npm run typecheck beide clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Vier nieuwe tools voor het Claude vraag-antwoord-kanaal:
- ask_user_question (write): post een gestructureerde vraag aan de actieve
Scrum4Me-gebruiker over een story; default async (returnt direct met
question_id + status='open'); optionele wait_seconds (max 600) polt elke 2s
tot het antwoord er is of timeout — daarna status='pending' zodat Claude met
get_question_answer later kan ophalen
- get_question_answer (read): huidige status + antwoord van een eerder
gestelde vraag
- list_open_questions (read): eigen vragen met status open/answered, max 50,
meest recente eerst
- cancel_question (write, asker-only): atomic UPDATE WHERE asked_by + status=
'open' zodat alleen eigen open vragen geannuleerd worden
Allemaal achter access-check via userCanAccessStory/Product en demo-blok via
requireWriteAccess (volgt patroon van create-todo en bestaande log-tools).
Submodule vendor/scrum4me bumpt naar Scrum4Me commit 79367dd (M11 ST-1101) —
bevat het ClaudeQuestion-model en notify_question_change-trigger waar deze
tools tegen werken.
scripts/smoke-test.ts: 13 tools verwacht (was 9); list_open_questions
toegevoegd als read-tool-coverage. Build + tools/list groen — verdere e2e via
MCP Inspector na PR-merge omdat de seed een nieuwe API-token heeft
gegenereerd en .env een nieuwe waarde nodig heeft.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps vendor/scrum4me submodule from 43a4294 (ST-509/511/512/513) naar 7461643
en daarmee picks de schema-wijzigingen op uit:
- M8 (ST-801): notify_solo_change-trigger op tasks/stories
- M9 (ST-901): User.active_product_id + UserActiveProduct relation
- M10 (ST-1001): LoginPairing model + login_pairings_notify-trigger op
scrum4me_pairing channel; User.login_pairings back-relation
Verificatie: npm run sync-schema + npm run prisma:generate + npm run typecheck
allemaal groen. Sluit de wekelijkse drift-check (trig_015FFUnxjz9WMuhhWNGBQKFD)
voor deze drie milestones.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #2 merged, so the StoryLog.metadata JSONB column is live. Sync
the vendored schema and wire `metadata` through to prisma.create in
log_implementation, log_test_result and log_commit. Cast via
Prisma.InputJsonValue because Zod parses the input as a generic
record while Prisma's JSON input type is invariant.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The MCP SDK rejects tools/call results where structuredContent is not a
record — array returns from list_products triggered an MCP error code
-32602. toolJson now wraps arrays/primitives as { result: <value> }.
scripts/smoke-test.ts spawns the built server over stdio, calls each
read-side tool against the live DB and asserts shape — surfaces this
bug class before regressions ship.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Documents the 9 tools, 1 prompt, environment variables, schema-sync
workflow, mcp_servers.json snippet and known risks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
End-to-end workflow prompt for Claude Code: fetch context, log a plan,
walk the tasks (in_progress → done), run tests, log result, commit.
Takes product_id as the only argument.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>