[TypeScript client] feat: RPC & in-memory transports#153
Draft
0xpolarzero wants to merge 27 commits into
Draft
Conversation
97a9ab0 to
e2182b7
Compare
e2182b7 to
c0ddef3
Compare
c0ddef3 to
e1db698
Compare
e1db698 to
2f25ed9
Compare
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.
Warning
This PR is stacked on top of #154 (
fix: reuse CLI skill projection). Becausewevm/incurdoes not have that base branch and this PR targetsmain, the diff includes the commits from that prerequisite branch as well.This PR adds the runtime and transport foundation that lets TypeScript code call an incur CLI through the same structured command protocol, whether the CLI is served over HTTP or used in process.
Check the PR on my fork for reviewing from a stacked diff.
API
The same request shape works against a served CLI:
HTTP clients can also call the RPC endpoint directly:
Streaming commands return NDJSON over HTTP and an async record iterator in transports:
Discovery uses the same transport contract for help, schemas, OpenAPI, skills, LLM manifests, and MCP tools:
Memory transports also expose local-only setup helpers:
Changes
incur/clientexport withClientError,Request,Discover,Local,Transport,HttpTransport, andMemoryTransport.argsandoptions.cli.fetch()./_incur/rpc.chunk, terminaldone, terminalerror, metadata, retryability, and cancellation.ClientErrorso transport and discovery failures carrycode,status,data,fieldErrors, and metadata when available.Notes
transport.request({ command, args, options }); a later PR builds the public generated/client-facing API on top.COMMAND_GROUP, and raw fetch gateways returnFETCH_GATEWAY.MemoryTransport.create(cli, { env })uses explicit env and does not load config defaults.HttpTransportsends OpenAPI discovery to/openapi.jsonor/openapi.yaml; other discovery resources use/_incur/*.Notable side effects
Typegen.fromCli()only walked the subcommand map, so a root CLI created withCli.create('name', { run })could be missing from generated command declarations.?: T | undefined) and escapes generated command/property keys when they are not valid bare TypeScript identifiers.outputschemas andstream: truemarkers for async generator commands.Cli.command('api', { fetch, openapi })now generates OpenAPI-backed command groups synchronously, so mounted OpenAPI operations are available before serving.Openapi.Commands<name, spec>.Openapi.generateCommands()now includes JSON response schemas as commandoutputschemas when available.get users posts.Command.execute()now supportsparseMode: 'structured'for RPC requests whereargsandoptionsare already separated.