Problem
poe-agent-tools is a canary for the real OpenAPI spec and toolcraft-openapi behavior. After updating to toolcraft-openapi@0.0.62 and regenerating, the generator emitted all expected command groups in src/generated/index.ts, including generatedCommands:
export const generatedCommands = [
agent,
apiBots,
botActions,
botAssets,
botCostTelemetry,
botWorkflowControls,
bots,
costUnitPrices,
handles,
llms,
modelPricing,
officialBots,
users,
] as const;
But the package-level client still has to manually import and wire commands:
import { botActions, bots, users } from "./generated/index.js";
import { agentWhoamiCommand } from "./generated/agent/whoami.js";
export const client = defineClient({
name: "poe-agent-tools",
baseUrl,
auth,
commands: [agentWhoamiCommand, botActions, bots, users],
});
That hand-maintained list caused most generated actions to be omitted from the installed CLI/MCP surface. poe-agent-tools --help currently exposes only:
whoami
bot-actions
bots
users
while generated groups also include agent, api-bots, bot-assets, bot-cost-telemetry, bot-workflow-controls, cost-unit-prices, handles, llms, model-pricing, and official-bots.
Required behavior
toolcraft-openapi should generate the package-level OpenAPI client wrapper, not just the leaf commands and groups.
The default generated command structure must reflect the OpenAPI-derived generated output exactly. Downstream packages should not need to flatten, reshape, rename, filter, or manually rewire generated commands to get a complete client. If the generator emits an agent group containing whoami, the default generated client surface should expose agent whoami, not a locally flattened root whoami command.
Downstream code should not import individual generated operations, enumerate generated groups, or pass a generated command array manually for the default full client. The consumer should provide only host-specific configuration:
import { defineGeneratedClient } from "./generated/client.js";
import { envBearerTokenAuth } from "./auth.js";
const BASE_URL = "https://www.i.quora.com/api/internal_agent";
export const client = defineGeneratedClient({
name: "poe-agent-tools",
baseUrl: BASE_URL,
auth: envBearerTokenAuth("POE_API_KEY"),
});
The generated wrapper owns the complete generated command surface:
// generated/client.ts
import { defineClient } from "toolcraft-openapi";
import { generatedCommands } from "./index.js";
export function defineGeneratedClient(options: GeneratedClientOptions) {
return defineClient({
...options,
commands: generatedCommands,
});
}
Exact naming can change, but the contract should be:
- one generated client factory is the primary public entrypoint for consumers;
- it includes every generated operation exactly once;
- it preserves the OpenAPI-derived generated grouping exactly;
- it is shared by CLI, MCP, and SDK/client usage;
- app code supplies only deployment/configuration concerns such as
name, baseUrl, auth, optional docsUrl, and optional fetch;
- lower-level exports remain available for consumers that intentionally want a custom command surface.
Advanced customization escape hatch
The generator should still emit lower-level files/exports for advanced consumers. If a consumer really wants to curate the CLI shape, flatten a group, hide commands, rename groups, or expose only a subset, that should be possible by explicitly importing generated groups or leaf commands and calling defineClient directly.
Example advanced/manual wiring:
import { defineClient } from "toolcraft-openapi";
import { botActions, bots } from "./generated/index.js";
import { agentWhoamiCommand } from "./generated/agent/whoami.js";
export const client = defineClient({
name: "custom-cli",
baseUrl,
auth,
commands: [agentWhoamiCommand, botActions, bots],
});
That escape hatch is useful, but it should be opt-in. The default generated integration path should be complete and spec-shaped by construction.
Generated CLI/MCP shape
Generated CLI and MCP entrypoints should consume the same generated client/root surface, so all surfaces agree by construction.
Example:
import { runCLI } from "toolcraft/cli";
import { client } from "./client.js";
await runCLI(client.root, { services: client.services });
or, if the generated output owns the runnable entrypoint directly:
import { runGeneratedCLI } from "./generated/cli.js";
import { envBearerTokenAuth } from "./auth.js";
await runGeneratedCLI({
name: "poe-agent-tools",
baseUrl: "https://www.i.quora.com/api/internal_agent",
auth: envBearerTokenAuth("POE_API_KEY"),
});
The key invariant is that CLI, MCP, and SDK clients cannot drift because they all use the same generated root/client definition by default.
Acceptance criteria
toolcraft-openapi-generate emits a generated client factory, e.g. defineGeneratedClient, that owns the complete command/root surface.
- The generated client factory includes every generated operation exactly once.
- The generated client factory preserves the OpenAPI-derived generated grouping exactly; no local flattening or reshaping in downstream packages is needed for the default full client.
- Generated CLI and MCP entrypoints use the same generated client/root surface as SDK/client consumers.
- Downstream packages do not need to import individual operation files or manually enumerate generated groups for the default full client.
- Lower-level generated exports remain available for explicit advanced customization, and docs distinguish this from the default integration path.
- Docs/readme/template should point consumers at the generated client factory as the default integration path.
- Add a regression test in
packages/toolcraft-openapi using a fixture spec with multiple groups; assert the generated client/root includes every operation and preserves the generated grouping.
- Add a regression/compile test showing an advanced consumer can still import a generated group or leaf command and call
defineClient manually.
- Update
poe-agent-tools to consume the generated client factory with no local compatibility shim and verify poe-agent-tools --help lists all generated groups/actions after regeneration.
Why this belongs upstream
Per poe-agent-tools/AGENTS.md, this repo should not patch generated files, normalize generator behavior locally, or add compatibility shims that hide upstream failures. Missing command wiring is a toolcraft-openapi ergonomics/contract issue: the generator already knows the full operation graph and should emit the complete high-level client integration point.
Problem
poe-agent-toolsis a canary for the real OpenAPI spec andtoolcraft-openapibehavior. After updating totoolcraft-openapi@0.0.62and regenerating, the generator emitted all expected command groups insrc/generated/index.ts, includinggeneratedCommands:But the package-level client still has to manually import and wire commands:
That hand-maintained list caused most generated actions to be omitted from the installed CLI/MCP surface.
poe-agent-tools --helpcurrently exposes only:while generated groups also include
agent,api-bots,bot-assets,bot-cost-telemetry,bot-workflow-controls,cost-unit-prices,handles,llms,model-pricing, andofficial-bots.Required behavior
toolcraft-openapishould generate the package-level OpenAPI client wrapper, not just the leaf commands and groups.The default generated command structure must reflect the OpenAPI-derived generated output exactly. Downstream packages should not need to flatten, reshape, rename, filter, or manually rewire generated commands to get a complete client. If the generator emits an
agentgroup containingwhoami, the default generated client surface should exposeagent whoami, not a locally flattened rootwhoamicommand.Downstream code should not import individual generated operations, enumerate generated groups, or pass a generated command array manually for the default full client. The consumer should provide only host-specific configuration:
The generated wrapper owns the complete generated command surface:
Exact naming can change, but the contract should be:
name,baseUrl,auth, optionaldocsUrl, and optionalfetch;Advanced customization escape hatch
The generator should still emit lower-level files/exports for advanced consumers. If a consumer really wants to curate the CLI shape, flatten a group, hide commands, rename groups, or expose only a subset, that should be possible by explicitly importing generated groups or leaf commands and calling
defineClientdirectly.Example advanced/manual wiring:
That escape hatch is useful, but it should be opt-in. The default generated integration path should be complete and spec-shaped by construction.
Generated CLI/MCP shape
Generated CLI and MCP entrypoints should consume the same generated client/root surface, so all surfaces agree by construction.
Example:
or, if the generated output owns the runnable entrypoint directly:
The key invariant is that CLI, MCP, and SDK clients cannot drift because they all use the same generated root/client definition by default.
Acceptance criteria
toolcraft-openapi-generateemits a generated client factory, e.g.defineGeneratedClient, that owns the complete command/root surface.packages/toolcraft-openapiusing a fixture spec with multiple groups; assert the generated client/root includes every operation and preserves the generated grouping.defineClientmanually.poe-agent-toolsto consume the generated client factory with no local compatibility shim and verifypoe-agent-tools --helplists all generated groups/actions after regeneration.Why this belongs upstream
Per
poe-agent-tools/AGENTS.md, this repo should not patch generated files, normalize generator behavior locally, or add compatibility shims that hide upstream failures. Missing command wiring is atoolcraft-openapiergonomics/contract issue: the generator already knows the full operation graph and should emit the complete high-level client integration point.