* surface agent failures in job summary (#632)
when the agent harness returns `{success: false, error}`, main.ts went
through the success path so the catch block — which renders the
`### ❌ Pullfrog failed` banner via renderRunError — never fired. result:
the GitHub Actions job summary showed only the partial body + usage
table, no error block. the progress comment had a narrow workaround
that re-implemented the api-key classifier inline.
unify: in finalizeSuccessRun, call renderRunError once when `!success`,
use `.summary` for the job summary (prepended to the existing
body/usage parts) and `.comment` for the progress comment. removes the
duplicated isApiKeyAuthError / formatApiKeyErrorSummary branch and
picks up BillingError reclassification + hang body for free.
* docs: note dual-surface failure rendering in finalizeSuccessRun
* fix copilot review nit: clarify which renderRunError classifications carry the H3 banner
* refactor: extract helpers out of action/main.ts so non-orchestration churn stops touching the file
main.ts had grown to ~1240 lines holding ~500 lines of helpers that have
nothing to do with the resolver pipeline — billing-error UI/copy, proxy
minting, summary/learnings persistence, log formatters, end-of-run
cleanup waterfalls. any PR adding a new billing code branch or a new
log line was forced to edit main.ts, and since main.ts is in
ALWAYS_RUN_ALL the entire 52-job LLM CI matrix fired on what should
have been a 0-job change (e.g. #748).
extractions:
- action/utils/billingErrors.ts — BillingError, TransientError, the
format*Summary renderers, billingConsoleUrl
- action/utils/proxy.ts — mintProxyKey, buildProxyTokenHeaders,
resolveProxyModel, plus runProxyResolution wrapper that renders +
rethrows BillingError/TransientError before the outer catch
- action/utils/prSummary.ts — fetchPreviousSnapshot, persistSummary
co-located with the existing seed/read file helpers
- action/utils/learnings.ts — persistLearnings co-located with the
existing seed/read file helpers
- action/utils/runStartupLog.ts — resolveOutputSchema + logRunStartup
(the model/agent/push/shell/timeout block)
- action/utils/runErrorRenderer.ts — renderRunError classifies
(BillingError reclassify / hang detect / API-key auth) and emits
{summary, comment} markdown bodies
- action/utils/runLifecycle.ts — persistRunArtifacts, finalizeSuccessRun,
writeRunErrorOutputs — the three end-of-run cleanup phases shared
between the success path and the error catch path
main.ts is now ~570 lines — the irreducible orchestrator: disposables
(`await using` for tokenRef / gitAuthServer / mcpHttpServer), the
toolContext construction, the agent-timeout race, the catch/finally
shape, and the named phase calls. behavior is preserved verbatim
(verified: pnpm -r typecheck + pnpm test 695/695 pass, action/test
596/596 pass).
wiki/main.md gets a new "file layout" section describing the split.
AGENTS.md gets a single line pointing future edits at the helpers
instead of main.ts.
* anneal: address review findings
- restore MainResult.result?: string (accidental removal in initial commit;
field was unused in current code but is part of the exported interface
surface — keep the diff truly behavior-preserving)
- move resolveOutputSchema from runStartupLog.ts to payload.ts (it's an
action-input resolver alongside resolvePromptInput / resolvePayload, not
a log helper — was placed in runStartupLog.ts for matrix-churn pragmatism
but the domain fit is in payload.ts)
- un-export resolveProxyModel (only used internally by runProxyResolution
in proxy.ts; no external importer)
- fix runErrorRenderer.ts JSDoc "Three classifications" → four (Billing,
hang, API-key, default)
- expand runLifecycle.ts module banner to note that finalizeSuccessRun
calls persistRunArtifacts first, and to explain why the catch path
splits writeRunErrorOutputs + persistRunArtifacts
- update billingErrors.ts header to point at proxy.ts and
runErrorRenderer.ts as the actual origin sites (was stale "main.ts")
- expand proxy.ts header to spell out the runProxyResolution entrypoint
contract (was stale "main.ts can render")
- update wiki/main.md resolver chain + dependency table to name
runProxyResolution as the actual call site and document the early
BillingError/TransientError rendering branch
- update wiki/main.md file-layout table to lead with runProxyResolution
and describe mintProxyKey/buildProxyTokenHeaders/resolveProxyModel
as internal helpers (was implying they were public surface)