feat(codegen): add unified multi-target CLI architecture#729
Open
pyramation wants to merge 9 commits intomainfrom
Open
feat(codegen): add unified multi-target CLI architecture#729pyramation wants to merge 9 commits intomainfrom
pyramation wants to merge 9 commits intomainfrom
Conversation
- Add cli config option (CliConfig | boolean) to GraphQLSDKConfigTarget - Add komoji dependency for toKebabCase casing - Create CLI generator orchestrator (cli/index.ts) - Create arg-mapper: converts CleanTypeRef to inquirerer Question[] - Create infra-generator: context + auth commands via Babel AST - Create executor-generator: ORM client init with appstash credentials - Create table-command-generator: per-table CRUD using ORM methods - Create custom-command-generator: per-operation using ORM methods - Create command-map-generator: command registry (Record<string, Function>) - Wire CLI generation into generate.ts alongside ORM/React Query - Update root barrel to include CLI exports Architecture: CLI -> ORM -> GraphQL (not CLI -> raw GraphQL) CLI commands: prompt for args -> call ORM method -> print JSON result Uses appstash@0.4.0 config-store for context/credential management
- Add cli-generator.test.ts with 13 tests covering all generated files - Snapshot executor, context, auth, table commands, custom commands, command map - Verify ORM method calls in table and custom commands - Verify appstash config-store usage in executor - Fix: runOrm now includes runCli so ORM is auto-enabled when CLI is enabled
- Add docs-generator.ts that produces README.md (overview, setup, commands) and COMMANDS.md (man-page style reference with synopsis, options, examples) - Wire into CLI orchestrator so docs are always generated alongside commands - Update snapshot tests: 15 tests, 10 snapshots covering all generated files
…CP, Skills)
- Add DocsConfig interface: { readme, agents, mcp, skills } with boolean flags
- Defaults: readme + agents on, mcp + skills opt-in. docs: true enables all.
- generateAgentsDocs(): structured AGENTS.md for LLM consumption with TOOL
sections, INPUT/OUTPUT schemas, WORKFLOWS, and ERROR HANDLING
- generateMcpConfig(): mcp.json with typed inputSchema per command (JSON Schema)
- generateSkills(): per-command .md skill files for agent systems
- Wire into cli/index.ts orchestrator with config-driven conditional generation
- 22 tests, 17 snapshots covering all formats and config combinations
…rget support - Move docs config to top-level GraphQLSDKConfigTarget (removed from CliConfig) - Create shared docs-utils.ts with common utilities - Add ORM docs generator (README, AGENTS.md, MCP tools, skills) - Add React Query hooks docs generator (README, AGENTS.md, MCP tools, skills) - Add per-target README and combined MCP config generators - Add root-root README for multi-target configs - Add generateMulti() to core for multi-target orchestration - Update CLI entry point to use core generateMulti() - Wire all docs generation into generate.ts - 32 tests, 31 snapshots covering all doc formats
- Add InfraNames config to CliConfig for collision detection - Add multi-target executor generator with baked endpoints and target routing - Add target-prefixed table/custom command generators - Add multi-target command map generator with target:command namespacing - Add multi-target context command with per-target endpoint prompts - Add generateAuthCommandWithName for custom auth command naming - Add resolveInfraNames() for automatic collision detection (auth->credentials, context->env) - Add generateMultiTargetCli() orchestrator - Wire into generateMulti() with unifiedCli option - Add --save-token flag on auth target custom operations - Add snapshot tests for multi-target CLI (8 new snapshots) - Add unit tests for resolveInfraNames collision detection
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
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.
feat(codegen): add unified multi-target CLI architecture
Summary
Adds a unified multi-target CLI generator that produces a single CLI for projects with multiple GraphQL API endpoints (e.g.,
auth.localhost,members.localhost,app.localhost). Instead of generating separate CLIs per target, this generates one CLI with target-namespaced commands (auth:user list,members:member create,app:car get).Key pieces:
resolveBuiltinNames()— collision detection that auto-renames builtin commands when they clash with target names (e.g.,auth→credentials,context→env), with user-configurable overrides viabuiltinNamesconfigtarget:commandnamespacing for all schema-derived commands; builtin commands (context,auth/credentials) remain top-levelcontext createprompts for per-target endpoints with defaults baked from config--save-tokenflag — auth target mutations can auto-save tokens to credentials storegenerateMulti()wiring — newunifiedClioption that skips per-target CLI generation, collects pipeline data, and generates a single unified CLIThis PR also includes the prior work from PRs #725 (CLI codegen) and #728 (docs generation) which this branch builds on.
Updates since last revision
Renamed
infraNames→builtinNamesacross the entire codebase (BuiltinNamesinterface,resolveBuiltinNames()function,CliConfig.builtinNamesproperty, all generators, all tests). This is a purely mechanical rename for API clarity — "builtin" better communicates that these are the built-in commands that ship with every generated CLI, as opposed to the schema-derived ones.Added multi-target documentation generators that produce docs reflecting the unified CLI's target-namespaced command structure:
generateMultiTargetReadme()— README.md showingtarget:commandsyntax, per-target endpoint setup viacontext create, and collision-renamed builtin commandsgenerateMultiTargetAgentsDocs()— AGENTS.md structured for LLM consumption with per-target tool definitions and multi-target workflowsgetMultiTargetCliMcpTools()— MCP tool definitions for all targets with target-prefixed tool namesgenerateMultiTargetSkills()— per-target skill files with target-prefixed file namesThese are wired into
generateMulti()ingenerate.ts— whenuseUnifiedCliis enabled anddocsConfigis present, docs are written alongside the generated CLI code. 5 new snapshot tests added (284 tests total, 118 snapshots).Review & Testing Checklist for Human
tscthe output. Check imports resolve correctly (especially../../executorpaths fromcommands/auth/user.ts).builtinNames: { auth: 'credentials' }but also has a target namedcredentials? The current code doesn't detect secondary collisions. Also verify the default renaming works (auth→credentials,context→env).skipCli/runOrmlogic change: Ingenerate.ts, the condition forrunOrmchanged fromrunReactQuery || runCli || ...torunReactQuery || !!config.cli || .... This means ORM is now generated even whenskipCli: trueis passed (which is correct for multi-target, but verify it doesn't break single-target behavior).store.getTargetEndpoint(targetName)which was added in dev-utils PR Move req object and ApiModule to server/src/types #64. Verify that PR is merged and published (appstash@0.5.0 or similar) before merging this.isAuthTargetdetection: The code hardcodesisAuthTarget = name === 'auth'ingenerateMulti(). This means only targets literally namedauthget--save-tokenon mutations. Consider if this should be configurable or detected differently.docsConfigfrom the first target (configs[names[0]]?.docs), assuming all targets share the same docs config. Test with a real multi-target project to ensure docs correctly show target-namespaced commands, collision-renamed builtin commands, and per-target endpoint setup instructions.Notes
getTargetEndpoint()/setTargetEndpoint()APIresolveBuiltinNames(), 5 new snapshot tests for multi-target docs. All 284 tests pass (118 snapshots).unifiedClioption ingenerateMulti().