feat(flows): forge + agent nodes with rate-limit budget (NF-3) #349
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!349
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/324-nf3-forge-agent-nodes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Extends the Node Flows registry (NF-2) with the full forge + agent node
catalog so flow authors can reach for any
ForgePortmethod or anagent dispatch from graph JSON.
forge.*nodes — one perForgePortmethod. Generated from asingle declaration table in
forge-nodes.ts. Each handler resolvesits adapter through
createForgeAdapterForRepo(repo, args.token)oran injected
args.adapter(test path), then maps spec-shaped inputports onto the port method signature.
agent.*nodes —agent.dispatch,agent.cancel,agent.raise_cap. All three take an optional injection (args.dispatch/
args.cancel/args.raiseCap) so the nodes stay testable withoutstanding up a worker registry. Production wiring lands in NF-4.
rate-limit.ts) — default 20 mutatingcalls.
RateLimitExceededsurfaces as a node-level throw, which theNF-2 executor treats as any other handler error (aborts unless the
node sits behind
router.try). Read-only forge queries do not chargethe budget.
defaultRegistry()inregistry.tsnow callsregisterForgeNodes+registerAgentNodesso the shipped registry already exposes everynew type.
Design notes
ForgeNodeSpeclist so each node entry is 5-15 lines rather than afull
NodeDescriptorstanza. Adding a new forge method is one tablerow.
"any"— the spec called this out and NF-2'scompiler treats
anypermissively. Domain shape validation stays onthe
ForgePortside (TypeScript) rather than forcing the registry tocatalogue every
ForgeIssue/ForgePullRequestfield."owner/name"string and{ owner, name }object. Saves author-facing transformers betweenupstream trigger payloads and the forge nodes.
resolveRateLimiter(args)first checks
args.rateLimit, falls back to the module-level default.NF-4 will replace the default with a per-run instance built by the
executor front-end. Until then,
resetDefaultRateLimiter()keepstests hermetic.
agent.dispatchcompletion wiring is a documented TODO — thenode accepts an
args.onTaskResult(taskId, cb)injection thatNF-4 can route to the worker's
onFinishhook. The NF-3 commitstops at returning the
taskIdand invoking the hook with ano-op — the full task.completed / task.failed trigger re-entry
belongs to the executor plane, not this additive node layer.
Test plan
rate-limit (18). Cover: input mapping, output shape, error
propagation, rate-limit budget (consume path, exhaustion,
shared across nodes), adapter injection fallback, missing-token
guard, spec input aliases.
bun x turbo run typecheckclean.bun x biome check apps/server/src/clean.registry.test.ts+executor.test.tsremain greenafter the
defaultRegistry()extension.Out of scope
args.dispatch/args.cancel/args.raiseCapfrom
main.ts— NF-4.task.completed/task.failed) —NF-4/NF-5.
Closes #324.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com