feat(core): control-plane action registry for host-UI dispatch#105
Merged
feat(core): control-plane action registry for host-UI dispatch#105
Conversation
Adds @agentage/core/control — a transport-agnostic action registry that lets host UIs (desktop, web, MCP clients) dispatch actions into the local env (e.g. update CLI, add project from origin, install agent). - action() builder + createRegistry() with list/get/invoke - Streaming InvokeEvent envelope (accepted → progress* → result|error) - Capability-based auth, idempotency dedup, versioning, deprecation, cancellation via AbortSignal - Three reference actions as factories with injected ShellExec: cli:update, project:addFromOrigin, agent:install - 22 new tests; full verify green (145 tests total)
Contributor
|
🎉 PR Validation ✅ PASSED Commit: Checks:
Ready to merge! ✨ 🔗 View workflow run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
@agentage/core/control— a transport-agnostic action registry so host UIs (desktop, web dashboard, future MCP clients) can dispatch control-plane actions into the local env. First three proof-of-shape actions:cli:update,project:addFromOrigin,agent:install.Motivation: today there's no unified way for a UI to ask "what actions can I invoke on this machine?" and dispatch them with validation, auth, idempotency, and streaming progress. The CLI daemon, web backend, and desktop IPC each have ad-hoc route handlers. This module gives all of them one shape to wire up.
Design
InvokeEvent(accepted→progress*→result | error). REST, WS, Electron IPC, and MCPtools/callare thin adapters over this stream.action<I, O, P>({ manifest, validateInput?, execute })—executeis anAsyncGenerator<P, O>so progress events and final result share one control flow.ActionErrorCode=UNKNOWN_ACTION | UNKNOWN_VERSION | INVALID_INPUT | UNAUTHORIZED | DEPRECATED | DUPLICATE_INVOCATION | EXECUTION_FAILED | CANCELED, each with aretryableflag.*wildcard; transport layer maps session → caps.action@version#idempotencyKey; replays emitDUPLICATE_INVOCATION.get(name)picks the highest,get(name, version)is explicit.deprecatedSinceon the manifest short-circuits invoke.AbortSignal; the invoke loop checks before each yield and returnsCANCELED.Sample actions take an injected
ShellExecso they're pure and testable — the host wires in core'sshelladapter (or a stub).Changes
packages/core/src/control/types.ts—ActionDefinition,ActionManifest,ActionContext,InvokeRequest/Event,ActionRegistryaction.ts— identity builder (matches thetool()/mcp()pattern)registry.ts—createRegistry()with list/get/invoke + idempotency maperrors.ts—ActionError+isActionErroractions/{cli-update,project-add-from-origin,agent-install}.ts— three reference actionsactions/types.ts—ShellExecDI interfacepackages/core/src/index.ts— re-exports the control module from the top-level barrelNext steps (not in this PR)
POST /api/actions/:nameroute + WS handler forwarding theInvokeEventstream.action:invokethat proxies to daemon (or runs its own registry for local-only actions).tools/list←registry.list(),tools/call←registry.invoke().Test plan
npm run verify— type-check + lint + format + 145 tests + build, all greencli:updateend-to-end from desktop against a local daemon (follow-up)