[DO NOT MERGE]feat(compiler): prefer client.tsp over main.tsp when no entrypoint configured#10960
[DO NOT MERGE]feat(compiler): prefer client.tsp over main.tsp when no entrypoint configured#10960m-nash wants to merge 1 commit into
Conversation
…nfigured When resolving the default entrypoint and no entrypoint is explicitly set (via tspconfig.yaml entrypoint or package.json tspMain), prefer client.tsp over main.tsp when a sibling client.tsp exists. This matches the convention already used by tsp-client and allows augment decorators in client.tsp (e.g. @@clientName) to participate in compilation and linting without requiring imports: - ./client.tsp in tspconfig.yaml. client.tsp is expected to import './main.tsp' per existing convention, which keeps the dependency direction client -> service intact. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
commit: |
|
All changed packages have been documented.
Show changes
|
There was a problem hiding this comment.
Pull request overview
This PR updates TypeSpec compiler entrypoint resolution so that, when no entrypoint is explicitly configured, client.tsp is preferred over main.tsp if both exist—aligning core compiler + language server behavior with the existing tsp-client convention.
Changes:
- Updated the language server entrypoint resolver to default to
["client.tsp", "main.tsp"], and to default toclient.tspwithinkind: projectboundaries when present. - Updated the CLI/compiler entrypoint resolver to use a shared default resolver that prefers
client.tspwhen present. - Added server-side unit tests covering the new default behavior, and added a Chronus entry documenting the change.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/compiler/test/server/entrypoint-resolver.test.ts | Adds tests ensuring client.tsp is preferred over main.tsp in default resolution cases. |
| packages/compiler/src/server/entrypoint-resolver.ts | Changes default fallback entrypoints to check client.tsp before main.tsp, including for kind: project configs. |
| packages/compiler/src/core/entrypoint-resolution.ts | Adjusts compiler/CLI directory entrypoint resolution to prefer client.tsp when present. |
| .chronus/changes/prefer-client-tsp-entrypoint-2026-6-10-15-15-0.md | Adds a changelog entry for the new default entrypoint behavior. |
| async function resolveDefaultEntrypoint(host: CompilerHost, dir: string): Promise<string> { | ||
| const clientTspPath = resolvePath(dir, "client.tsp"); | ||
| const stat = await doIO(host.stat, clientTspPath, () => {}, { allowFileNotFound: true }); | ||
| return stat?.isFile() ? "client.tsp" : "main.tsp"; |
| const entrypoint = | ||
| config.entrypoint ?? ((await existingFile(dir, "client.tsp")) ? "client.tsp" : "main.tsp"); | ||
| const candidate = await existingFile(dir, entrypoint); |
| - "@typespec/compiler" | ||
| --- | ||
|
|
||
| Default entrypoint resolution now prefers `client.tsp` over `main.tsp` when a project's `tspconfig.yaml` does not explicitly set `entrypoint` and a sibling `client.tsp` exists. This matches the convention used by `tsp-client` and allows augment decorators in `client.tsp` (e.g. `@@clientName`) to participate in compilation and linting without needing to add `imports: - ./client.tsp` to `tspconfig.yaml`. |
|
You can try these changes here
|
Summary
When resolving the default entrypoint and no entrypoint is explicitly set (via tspconfig.yaml
entrypointor package.jsontspMain), preferclient.tspovermain.tspwhen a siblingclient.tspexists.This matches the convention already used by
tsp-clientand allows augment decorators inclient.tsp(e.g.@@clientName) to participate in compilation and linting without requiringimports: - ./client.tspin tspconfig.yaml.Motivation
Linter rules that emit codefixes targeting
client.tsp(e.g. Azure/typespec-azure#4541) currently have two options to ensure the augmented decorators participate in the compile/lint pass:tspconfig.yamlto addimports: - ./client.tsp.Both are awkward.
tsp-clientalready solves this by treatingclient.tspas the entrypoint when present. This change brings the same convention to the core compiler/language server so that:client.tspJust Work without YAML editing.client.tsp imports main.tsp(client depends on service, not the other way around).Behavior
Resolution order is unchanged except for the implicit default:
tspconfig.yamlexplicitly setsentrypoint, that wins.package.jsonsetstspMain, that wins.client.tspif it exists in the project root, elsemain.tsp.Both the CLI entrypoint resolver (
core/entrypoint-resolution.ts) and the language-server entrypoint resolver (server/entrypoint-resolver.ts) are updated.Caveat
For augments in
client.tspto reference types defined inmain.tsp,client.tspmustimport './main.tsp'. This matches the existing tsp-client convention and is already the standard pattern.Tests
test/server/entrypoint-resolver.test.ts.client.tspovermain.tspwhen both exist, and compilation succeeds whenclient.tspimportsmain.tsp.