fix(chat/runs): install global skills in the headless run path

Merged
SW
4mo ago
+93-0

What

Call installSessionGlobalSkills({ sessionRow, sandbox }) inside provisionRunSession — after connectSandbox / markSessionSandboxActive, before discoverSkills. Best-effort (try/catch + log), mirroring createSandboxHandler.

Why

Scheduled tasks (customer-prompt-task → generateChat → POST /api/chat/runs) provision their sandbox via provisionRunSession, which only discovered skills and never installed them. installSessionGlobalSkills (lays recoup-platform-api-access + roster skills into ${HOME}/.agents/skills/) ran only in createSandboxHandler (interactive POST /api/sandbox).

Headless result: empty .agents/skills/ → discoverSkills returns [] → buildAgentTools hasSkills=false → agent gets no skill tool → can't load recoup-platform-api-access, guesses endpoints, gets 404/empty, fabricates. Root cause for recoupable/chat#1822 (0/6 audited runs loaded any skill).

Tests (TDD, RED→GREEN)

New lib/chat/runs/__tests__/provisionRunSession.test.ts: asserts install is called with { sessionRow, sandbox } and ordered before discoverSkills (RED→GREEN), plus best-effort (rejected install still completes). Full domain suite green (370 passed), eslint clean, no new tsc errors in changed files.

Verify on preview (Done-when)

A scheduled run's trace shows a skill tool call loading recoup-platform-api-access (not curl-guessing). Gated on recoupable/skills#65 so the loaded skill points at api.recoupable.dev.

Refs recoupable/chat#1822 · merge order: skills#65 → this → api reliability · base test

🤖 Generated with Claude Code


Summary by cubic

Install global skills during headless run provisioning so scheduled runs load tools instead of guessing APIs. Fixes recoupable/chat#1822 by ensuring the agent gets the skill tool and avoiding an empty .agents/skills/ directory.

  • Bug Fixes
    • In provisionRunSession, call installSessionGlobalSkills after connectSandbox/markSessionSandboxActive and before discoverSkills; wrapped in try/catch to stay non-blocking.
    • Headless runs now discover installed skills and can load recoup-platform-api-access.
    • Added tests for call order and best‑effort behavior.