turbo 2.11.8 → 2.11.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/turbo CHANGED
@@ -386,7 +386,9 @@ function shouldOwnWindowsCtrlC() {
386
386
  return false;
387
387
  }
388
388
 
389
- if (usesTui(process.argv.slice(2))) {
389
+ const args = process.argv.slice(2);
390
+ // Exec's command reads the console directly, like the TUI does.
391
+ if (usesTui(args) || selectsExec(args)) {
390
392
  return false;
391
393
  }
392
394
 
@@ -410,6 +412,62 @@ function usesTui(args) {
410
412
  return false;
411
413
  }
412
414
 
415
+ // Global flags that take the next word as their value. Keep in step with the
416
+ // global options in crates/turborepo-cli/src/cli/args.rs.
417
+ const GLOBAL_VALUE_FLAGS = new Set([
418
+ "--api",
419
+ "--cwd",
420
+ "--heap",
421
+ "--login",
422
+ "--remote-cache-timeout",
423
+ "--root-turbo-json",
424
+ "--team",
425
+ "--token",
426
+ "--trace",
427
+ "--ui",
428
+ "--verbosity",
429
+ "--experimental-otel-endpoint",
430
+ "--experimental-otel-header",
431
+ "--experimental-otel-interval-ms",
432
+ "--experimental-otel-protocol",
433
+ "--experimental-otel-resource",
434
+ "--experimental-otel-timeout-ms",
435
+ ]);
436
+
437
+ // Global flags whose value is optional. Like turbo, take the next word as
438
+ // the value unless it is a flag.
439
+ const GLOBAL_OPTIONAL_VALUE_FLAGS = new Set([
440
+ "--experimental-otel-enabled",
441
+ "--experimental-otel-metrics-run-summary",
442
+ "--experimental-otel-metrics-task-details",
443
+ "--experimental-otel-use-remote-cache-token",
444
+ ]);
445
+
446
+ // The command is the first word that is not a flag or a flag's value, so a
447
+ // task or argument named `exec` does not select it.
448
+ function selectsExec(args) {
449
+ for (let i = 0; i < args.length; i++) {
450
+ const arg = args[i];
451
+ if (arg === "--") {
452
+ return false;
453
+ }
454
+ if (arg.startsWith("-")) {
455
+ const next = args[i + 1];
456
+ if (
457
+ GLOBAL_VALUE_FLAGS.has(arg) ||
458
+ (GLOBAL_OPTIONAL_VALUE_FLAGS.has(arg) &&
459
+ next !== undefined &&
460
+ !next.startsWith("-"))
461
+ ) {
462
+ i++;
463
+ }
464
+ continue;
465
+ }
466
+ return arg === "exec";
467
+ }
468
+ return false;
469
+ }
470
+
413
471
  function runTurbo() {
414
472
  if (shouldOwnWindowsCtrlC()) {
415
473
  return runTurboChild(
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  title: Multi-language support
3
- description: Combine package-manager and native language workspaces.
3
+ description: Run other language toolchains alongside JavaScript packages.
4
4
  product: turborepo
5
5
  type: guide
6
- summary: Run JavaScript packages and experimental native Go modules in one task graph.
6
+ summary: Use package scripts to build JavaScript and .NET projects in one task graph.
7
7
  prerequisites:
8
8
  - /docs/crafting-your-repository/structuring-a-repository
9
9
  - /docs/crafting-your-repository/configuring-tasks
@@ -14,35 +14,41 @@ related:
14
14
  - /docs/guides/migrating-from-nx
15
15
  ---
16
16
 
17
- Turborepo can combine package-manager workspaces with enabled native workspaces. Each workspace contributes its own package identities, dependency relationships, and tasks to the same Package Graph and Task Graph.
17
+ Turborepo can run other language toolchains through scripts in `package.json`. Add a package for each independently cacheable project and declare its dependencies so Turborepo can order tasks and invalidate cached results.
18
18
 
19
- This example combines a JavaScript application with two Go modules:
19
+ For experimental native workspace support, see the [Rust](/docs/guides/tools/rust), [Python](/docs/guides/tools/python), and [Go](/docs/guides/tools/go) guides. Those integrations discover projects and dependencies from their native workspace files.
20
+
21
+ This example combines a JavaScript package with a .NET console application and a C# library. Start with [Turborepo installed](/docs/getting-started/installation) in your repository, and install the [.NET 10 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/10.0) so `dotnet` is available on `PATH`.
20
22
 
21
23
  ```text
22
24
  .
23
25
  ├── apps/api/
24
- │ ├── go.mod
25
- │ └── main.go
26
+ │ ├── Api.csproj
27
+ │ ├── Program.cs
28
+ │ └── package.json
26
29
  ├── packages/
27
30
  │ ├── lib/
28
- │ │ ├── go.mod
29
- │ │ └── lib.go
31
+ │ │ ├── Lib.csproj
32
+ │ │ ├── Message.cs
33
+ │ │ └── package.json
30
34
  │ └── web/
31
35
  │ └── package.json
32
- ├── go.work
36
+ ├── .gitignore
37
+ ├── global.json
33
38
  ├── package.json
34
39
  └── turbo.json
35
40
  ```
36
41
 
37
- ## Add the JavaScript workspace
42
+ ## Add the package-manager workspaces
38
43
 
39
- Include `packages/web` in the package-manager workspace:
44
+ Include both the application and library directories. Their `package.json` files make the .NET projects visible to Turborepo:
40
45
 
41
46
  <PackageManagerTabs>
42
47
  <Tab value="pnpm">
43
48
 
44
49
  ```yaml title="./pnpm-workspace.yaml"
45
50
  packages:
51
+ - "apps/*"
46
52
  - "packages/*"
47
53
  ```
48
54
 
@@ -54,7 +60,8 @@ packages:
54
60
 
55
61
  ```json title="./package.json"
56
62
  {
57
- "workspaces": ["packages/*"]
63
+ "private": true,
64
+ "workspaces": ["apps/*", "packages/*"]
58
65
  }
59
66
  ```
60
67
 
@@ -66,7 +73,8 @@ packages:
66
73
 
67
74
  ```json title="./package.json"
68
75
  {
69
- "workspaces": ["packages/*"]
76
+ "private": true,
77
+ "workspaces": ["apps/*", "packages/*"]
70
78
  }
71
79
  ```
72
80
 
@@ -78,7 +86,8 @@ packages:
78
86
 
79
87
  ```json title="./package.json"
80
88
  {
81
- "workspaces": ["packages/*"]
89
+ "private": true,
90
+ "workspaces": ["apps/*", "packages/*"]
82
91
  }
83
92
  ```
84
93
 
@@ -87,7 +96,7 @@ packages:
87
96
  </Tab>
88
97
  </PackageManagerTabs>
89
98
 
90
- The JavaScript application has a normal package name and script:
99
+ The JavaScript package has a normal package name and script:
91
100
 
92
101
  ```json title="./packages/web/package.json"
93
102
  {
@@ -100,92 +109,136 @@ The JavaScript application has a normal package name and script:
100
109
  }
101
110
  ```
102
111
 
103
- ## Add the Go workspace
112
+ ## Add the .NET projects
104
113
 
105
- At the repository root, create a `go.work` that lists each Go module:
114
+ Pin the .NET SDK at the repository root so machines sharing cached builds use the same compiler. Install the version specified here:
106
115
 
107
- ```text title="./go.work"
108
- go 1.22
109
-
110
- use (
111
- ./apps/api
112
- ./packages/lib
113
- )
116
+ ```json title="./global.json"
117
+ {
118
+ "sdk": {
119
+ "version": "10.0.401",
120
+ "rollForward": "disable"
121
+ }
122
+ }
114
123
  ```
115
124
 
116
- Declare the full Go module paths in `go.mod`. Turborepo derives the package names `lib` and `api` from these paths:
125
+ `rollForward: "disable"` requires the exact SDK version. This prevents a compiler upgrade from reusing cached outputs without a corresponding change to `global.json`.
117
126
 
118
- ```text title="./packages/lib/go.mod"
119
- module example.com/acme/lib
127
+ Create the library project and its source file:
120
128
 
121
- go 1.22
129
+ ```xml title="./packages/lib/Lib.csproj"
130
+ <Project Sdk="Microsoft.NET.Sdk">
131
+ <PropertyGroup>
132
+ <TargetFramework>net10.0</TargetFramework>
133
+ <DefaultItemExcludes>$(DefaultItemExcludes);node_modules/**</DefaultItemExcludes>
134
+ </PropertyGroup>
135
+ </Project>
122
136
  ```
123
137
 
124
- ```text title="./apps/api/go.mod"
125
- module example.com/acme/api
138
+ ```csharp title="./packages/lib/Message.cs"
139
+ namespace Acme.Lib;
126
140
 
127
- go 1.22
141
+ public static class Message
142
+ {
143
+ public static string Text() => "API ready";
144
+ }
145
+ ```
146
+
147
+ The application uses a `ProjectReference` to resolve the library in .NET:
148
+
149
+ ```xml title="./apps/api/Api.csproj"
150
+ <Project Sdk="Microsoft.NET.Sdk">
151
+ <PropertyGroup>
152
+ <OutputType>Exe</OutputType>
153
+ <TargetFramework>net10.0</TargetFramework>
154
+ <DefaultItemExcludes>$(DefaultItemExcludes);node_modules/**</DefaultItemExcludes>
155
+ </PropertyGroup>
156
+ <ItemGroup>
157
+ <ProjectReference Include="../../packages/lib/Lib.csproj" />
158
+ </ItemGroup>
159
+ </Project>
160
+ ```
128
161
 
129
- require example.com/acme/lib v0.0.0
162
+ ```csharp title="./apps/api/Program.cs"
163
+ System.Console.WriteLine(Acme.Lib.Message.Text());
130
164
  ```
131
165
 
132
- For example, the API can import and call the library:
166
+ ## Connect the projects to Turborepo
167
+
168
+ Add a `package.json` beside each `.csproj` with a script that invokes the [.NET CLI](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build):
133
169
 
134
- ```go title="./packages/lib/lib.go"
135
- package lib
170
+ ```json title="./packages/lib/package.json"
171
+ {
172
+ "name": "lib",
173
+ "version": "1.0.0",
174
+ "private": true,
175
+ "scripts": {
176
+ "build": "dotnet build Lib.csproj --configuration Release"
177
+ }
178
+ }
179
+ ```
136
180
 
137
- func Message() string {
138
- return "API ready"
181
+ ```json title="./apps/api/package.json"
182
+ {
183
+ "name": "api",
184
+ "version": "1.0.0",
185
+ "private": true,
186
+ "scripts": {
187
+ "build": "dotnet build Api.csproj --configuration Release"
188
+ },
189
+ "dependencies": {
190
+ "lib": "workspace:*"
191
+ }
139
192
  }
140
193
  ```
141
194
 
142
- ```go title="./apps/api/main.go"
143
- package main
195
+ For npm, use `"lib": "*"` instead of `"workspace:*"`. Run your package manager's install command from the repository root to link the workspaces and update its lockfile.
144
196
 
145
- import (
146
- "fmt"
197
+ Keep the `package.json` dependency in sync with the `ProjectReference`. .NET uses the project reference to compile the application, while Turborepo uses the package dependency to build `lib` before `api` and invalidate `api`'s cache when the library changes. Turborepo does not read `.csproj` references or manage NuGet dependencies. Review both declarations whenever you add or remove a project reference.
147
198
 
148
- "example.com/acme/lib"
149
- )
199
+ The `DefaultItemExcludes` entries keep .NET from compiling source files reached through workspace links in `node_modules`.
150
200
 
151
- func main() {
152
- fmt.Println(lib.Message())
153
- }
154
- ```
201
+ ## Configure tasks and caching
202
+
203
+ Ignore `bin/` and `obj/` to keep generated files out of the default input hash. The `outputs` setting below still lets Turborepo cache and restore `bin/`:
155
204
 
156
- ## Enable native Go tasks
205
+ ```text title="./.gitignore"
206
+ node_modules/
207
+ .turbo/
208
+ bin/
209
+ obj/
210
+ ```
157
211
 
158
- Enable native Go workspace support in the root `turbo.json`:
212
+ Configure the build task and cache the binaries produced by each .NET project:
159
213
 
160
214
  ```json title="./turbo.json"
161
215
  {
162
216
  "$schema": "https://turborepo.dev/schema.json",
163
- "futureFlags": {
164
- "experimentalGoWorkspaces": true
165
- },
217
+ "globalDependencies": ["global.json"],
166
218
  "tasks": {
167
219
  "build": {
168
- "dependsOn": ["^build"]
220
+ "dependsOn": ["^build"],
221
+ "outputs": ["bin/**"]
169
222
  },
170
- "test": {},
171
- "lint": {}
223
+ "web#build": {
224
+ "outputs": []
225
+ }
172
226
  }
173
227
  }
174
228
  ```
175
229
 
176
- Turborepo now discovers `web` from the package-manager workspace and `api` and `lib` from `go.work`. The Go modules do not need `package.json` files. A repository that contains only enabled native workspaces can also omit the root `package.json`; this mixed repository keeps one for its JavaScript workspace.
230
+ Output paths are relative to each package. The .NET builds write to `bin/Release/net10.0`; the JavaScript script only prints a message and has no files to cache. `obj/` contains intermediate and restore state and is not cached here. A build that needs it can recreate it through `dotnet build`'s implicit restore.
177
231
 
178
- Go package names use the last module-path component and preserve a trailing major-version suffix: `example.com/api` becomes `api`, while `example.com/api/v2` becomes `api/v2`. Names must be unique across the entire Package Graph: another Go module ending in `/api`, or a JavaScript package named `api`, would collide with this API. Full paths are not aliases, and package-name overrides are not supported. See [Go package names](/docs/guides/tools/go#package-names) for collision handling.
232
+ Adding `global.json` to [`globalDependencies`](/docs/reference/configuration#globaldependencies) makes SDK version changes in that file invalidate cached tasks. Update the pinned version when upgrading the SDK; Turborepo does not detect the installed .NET SDK version automatically. If you add shared files such as `Directory.Build.props`, `Directory.Build.targets`, or `NuGet.Config`, include those in your task inputs or global dependencies too. Keep the build environment consistent between machines that share cached outputs.
179
233
 
180
- Run JavaScript scripts and built-in native Go tasks together, or select a Go package by its derived name:
234
+ Run all builds, or select the .NET application:
181
235
 
182
236
  ```bash title="Terminal"
183
237
  turbo run build
184
- turbo run test --filter=api
185
- turbo run api#test
186
- turbo run lint
238
+ turbo run build --filter=api
239
+ dotnet apps/api/bin/Release/net10.0/Api.dll
187
240
  ```
188
241
 
189
- The API's `require example.com/acme/lib` declaration resolves the dependency on the package named `lib`, so `dependsOn: ["^build"]` orders their Go builds. Keep the full module paths in `go.mod` and Go imports; those paths remain dependency-resolution metadata rather than Turborepo graph identities. The synthetic `go-workspace` package depends on every Go member but does not provide built-in `test`, `lint`, or `format` tasks. Run those tasks without a filter to execute them in each member module. See the [Go guide](/docs/guides/tools/go) for the complete native task and caching behavior.
242
+ The application prints `API ready`. A second unchanged `turbo run build` restores the cached results. Editing `packages/lib/Message.cs` causes both `lib` and its dependent `api` to rebuild, while `web` can still use its cache.
190
243
 
191
- For a language without native workspace support, add a `package.json` beside each independently cacheable project and invoke its toolchain from package scripts. Turborepo then uses the package-manager relationships rather than interpreting that language's dependency graph.
244
+ .NET still checks project references during the application's build and normally skips recompilation when they are up to date. The package dependency lets Turborepo schedule and cache each project independently; it does not replace .NET's dependency resolution.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "turbo",
3
- "version": "2.11.8",
3
+ "version": "2.11.9",
4
4
  "description": "Turborepo is the build system for coding agents.",
5
5
  "homepage": "https://turborepo.dev",
6
6
  "bugs": "https://github.com/vercel/turborepo/issues",
@@ -19,12 +19,12 @@
19
19
  ],
20
20
  "main": "./bin/turbo",
21
21
  "optionalDependencies": {
22
- "@turbo/darwin-64": "2.11.8",
23
- "@turbo/darwin-arm64": "2.11.8",
24
- "@turbo/linux-64": "2.11.8",
25
- "@turbo/linux-arm64": "2.11.8",
26
- "@turbo/windows-64": "2.11.8",
27
- "@turbo/windows-arm64": "2.11.8"
22
+ "@turbo/darwin-64": "2.11.9",
23
+ "@turbo/darwin-arm64": "2.11.9",
24
+ "@turbo/linux-64": "2.11.9",
25
+ "@turbo/linux-arm64": "2.11.9",
26
+ "@turbo/windows-64": "2.11.9",
27
+ "@turbo/windows-arm64": "2.11.9"
28
28
  },
29
29
  "scripts": {
30
30
  "postversion": "node bump-version.js"
package/schema.json CHANGED
@@ -190,6 +190,17 @@
190
190
  }
191
191
  ]
192
192
  },
193
+ "setup": {
194
+ "description": "Repository policy for `turbo setup`. Only allowed in the root turbo.json and requires `futureFlags.experimentalSetup`.",
195
+ "anyOf": [
196
+ {
197
+ "$ref": "#/definitions/SetupPolicy"
198
+ },
199
+ {
200
+ "type": "null"
201
+ }
202
+ ]
203
+ },
193
204
  "tags": {
194
205
  "description": "Arbitrary string labels for this package. In the root configuration, these labels apply to the root package.",
195
206
  "anyOf": [
@@ -223,12 +234,89 @@
223
234
  "allowComments": true,
224
235
  "allowTrailingCommas": true,
225
236
  "definitions": {
237
+ "AdditionalTool": {
238
+ "description": "A tool that `turbo setup` downloads, verifies, and installs from explicit artifacts. The full installation tree is kept; no tool-provided scripts run.",
239
+ "type": "object",
240
+ "required": ["artifacts", "version"],
241
+ "properties": {
242
+ "artifacts": {
243
+ "description": "Artifacts keyed by platform, such as `linux-x64-gnu` or `macos-arm64`. Platforms without an artifact are unsupported for this tool.",
244
+ "allOf": [
245
+ {
246
+ "$ref": "#/definitions/Map_of_AdditionalToolArtifact"
247
+ }
248
+ ]
249
+ },
250
+ "version": {
251
+ "description": "The exact version of the tool. Ranges and channels are not allowed.",
252
+ "allOf": [
253
+ {
254
+ "$ref": "#/definitions/String"
255
+ }
256
+ ]
257
+ }
258
+ }
259
+ },
260
+ "AdditionalToolArtifact": {
261
+ "description": "One platform's artifact for an additional tool.",
262
+ "type": "object",
263
+ "required": ["executables", "format", "sha256", "url"],
264
+ "properties": {
265
+ "executables": {
266
+ "description": "Executable names mapped to paths relative to `rootPrefix`, or to the archive's top level without one. A binary has exactly one entry, which names where the file is installed.",
267
+ "type": "object",
268
+ "additionalProperties": {
269
+ "$ref": "#/definitions/String"
270
+ }
271
+ },
272
+ "format": {
273
+ "description": "`binary` for a single executable file, or the archive format.",
274
+ "allOf": [
275
+ {
276
+ "$ref": "#/definitions/ArtifactFormat"
277
+ }
278
+ ]
279
+ },
280
+ "rootPrefix": {
281
+ "description": "The single top-level directory that contains every archive entry. Omit it for an archive whose entries sit at its top level. Not allowed for binaries.",
282
+ "anyOf": [
283
+ {
284
+ "$ref": "#/definitions/String"
285
+ },
286
+ {
287
+ "type": "null"
288
+ }
289
+ ]
290
+ },
291
+ "sha256": {
292
+ "description": "Lowercase hex SHA-256 digest of the downloaded bytes. A digest pins the expected bytes; it does not establish that the publisher is trustworthy.",
293
+ "allOf": [
294
+ {
295
+ "$ref": "#/definitions/String"
296
+ }
297
+ ]
298
+ },
299
+ "url": {
300
+ "description": "HTTPS download URL without credentials, a query, or a fragment.",
301
+ "allOf": [
302
+ {
303
+ "$ref": "#/definitions/String"
304
+ }
305
+ ]
306
+ }
307
+ }
308
+ },
226
309
  "Array_of_String": {
227
310
  "type": "array",
228
311
  "items": {
229
312
  "$ref": "#/definitions/String"
230
313
  }
231
314
  },
315
+ "ArtifactFormat": {
316
+ "description": "How an artifact is packaged. `binary` is a single executable file.",
317
+ "type": "string",
318
+ "enum": ["binary", "tar", "tar-gz", "zip"]
319
+ },
232
320
  "Boolean": {
233
321
  "type": "boolean"
234
322
  },
@@ -282,6 +370,11 @@
282
370
  }
283
371
  }
284
372
  },
373
+ "DependencyPolicy": {
374
+ "description": "How `turbo setup` prepares a toolchain's dependencies. `locked` installs them from the committed ecosystem lockfile without changing it. `skip` does not install them.",
375
+ "type": "string",
376
+ "enum": ["locked", "skip"]
377
+ },
285
378
  "EnvMode": {
286
379
  "description": "Turborepo's Environment Modes allow you to control which environment variables are available to a task at runtime.\n\n- `strict`: Filter environment variables to only those that are specified in the `env` and `globalEnv` keys in `turbo.json`. - `loose`: Allow all environment variables for the process to be available.\n\nDocumentation: https://turborepo.dev/docs/reference/configuration#envmode",
287
380
  "oneOf": [
@@ -510,6 +603,12 @@
510
603
  }
511
604
  }
512
605
  },
606
+ "Map_of_AdditionalToolArtifact": {
607
+ "type": "object",
608
+ "additionalProperties": {
609
+ "$ref": "#/definitions/AdditionalToolArtifact"
610
+ }
611
+ },
513
612
  "Map_of_TagRules": {
514
613
  "type": "object",
515
614
  "additionalProperties": {
@@ -804,6 +903,179 @@
804
903
  }
805
904
  }
806
905
  },
906
+ "SetupMirrors": {
907
+ "description": "Credential-free HTTPS mirrors for `turbo setup` downloads. Each value is a base URL that serves the same paths as the official source.",
908
+ "type": "object",
909
+ "properties": {
910
+ "bun": {
911
+ "description": "Replaces the `https://github.com` origin for Bun release checksums and archives, keeping their official paths.",
912
+ "anyOf": [
913
+ {
914
+ "$ref": "#/definitions/String"
915
+ },
916
+ {
917
+ "type": "null"
918
+ }
919
+ ]
920
+ },
921
+ "go": {
922
+ "description": "Replaces both the `https://go.dev` and `https://dl.google.com` origins for Go's release index and archives. The mirror serves both official paths, `/dl/?mode=json&include=all` and `/go/<archive>`, beneath its base.",
923
+ "anyOf": [
924
+ {
925
+ "$ref": "#/definitions/String"
926
+ },
927
+ {
928
+ "type": "null"
929
+ }
930
+ ]
931
+ },
932
+ "node": {
933
+ "description": "Replaces `https://nodejs.org/dist` for Node.js release metadata and archives.",
934
+ "anyOf": [
935
+ {
936
+ "$ref": "#/definitions/String"
937
+ },
938
+ {
939
+ "type": "null"
940
+ }
941
+ ]
942
+ },
943
+ "npmRegistry": {
944
+ "description": "Replaces `https://registry.npmjs.org` for npm, pnpm, and Yarn package metadata and tarballs.",
945
+ "anyOf": [
946
+ {
947
+ "$ref": "#/definitions/String"
948
+ },
949
+ {
950
+ "type": "null"
951
+ }
952
+ ]
953
+ },
954
+ "python": {
955
+ "description": "Replaces the `https://releases.astral.sh` origin for CPython build checksums and archives, keeping their official paths.",
956
+ "anyOf": [
957
+ {
958
+ "$ref": "#/definitions/String"
959
+ },
960
+ {
961
+ "type": "null"
962
+ }
963
+ ]
964
+ },
965
+ "rust": {
966
+ "description": "Replaces the `https://static.rust-lang.org` origin for rustup and Rust toolchain downloads, keeping their official paths, like `RUSTUP_DIST_SERVER`.",
967
+ "anyOf": [
968
+ {
969
+ "$ref": "#/definitions/String"
970
+ },
971
+ {
972
+ "type": "null"
973
+ }
974
+ ]
975
+ },
976
+ "uv": {
977
+ "description": "Replaces the `https://releases.astral.sh` origin for uv's version index and release archives, keeping their official paths.",
978
+ "anyOf": [
979
+ {
980
+ "$ref": "#/definitions/String"
981
+ },
982
+ {
983
+ "type": "null"
984
+ }
985
+ ]
986
+ }
987
+ }
988
+ },
989
+ "SetupPolicy": {
990
+ "description": "Repository policy for `turbo setup`. Only allowed in the root turbo.json and requires `futureFlags.experimentalSetup`.\n\nOptional: without it, `turbo setup` infers what to prepare from native declaration files, and detected tools are managed. Root `tools` and `dependencies` apply to every toolchain. A toolchain key overrides them for that toolchain.",
991
+ "type": "object",
992
+ "properties": {
993
+ "additionalTools": {
994
+ "description": "Tools that no built-in adapter manages, keyed by tool ID. Each declares an exact version and explicit per-platform artifacts. `turbo setup` locks, verifies, and installs them without running tool-provided scripts.",
995
+ "type": ["object", "null"],
996
+ "additionalProperties": {
997
+ "$ref": "#/definitions/AdditionalTool"
998
+ }
999
+ },
1000
+ "dependencies": {
1001
+ "description": "How `turbo setup` prepares dependencies for every toolchain.",
1002
+ "anyOf": [
1003
+ {
1004
+ "$ref": "#/definitions/DependencyPolicy"
1005
+ },
1006
+ {
1007
+ "type": "null"
1008
+ }
1009
+ ]
1010
+ },
1011
+ "go": {
1012
+ "description": "Setup policy for the Go toolchain. Requires `futureFlags.experimentalGoWorkspaces`.",
1013
+ "anyOf": [
1014
+ {
1015
+ "$ref": "#/definitions/ToolchainSetupPolicy"
1016
+ },
1017
+ {
1018
+ "type": "null"
1019
+ }
1020
+ ]
1021
+ },
1022
+ "javascript": {
1023
+ "description": "Setup policy for the JavaScript toolchain.",
1024
+ "anyOf": [
1025
+ {
1026
+ "$ref": "#/definitions/ToolchainSetupPolicy"
1027
+ },
1028
+ {
1029
+ "type": "null"
1030
+ }
1031
+ ]
1032
+ },
1033
+ "mirrors": {
1034
+ "description": "Credential-free HTTPS mirrors for setup downloads. `turbo.lock` keeps the official URLs, and environment variables override these values.",
1035
+ "anyOf": [
1036
+ {
1037
+ "$ref": "#/definitions/SetupMirrors"
1038
+ },
1039
+ {
1040
+ "type": "null"
1041
+ }
1042
+ ]
1043
+ },
1044
+ "python": {
1045
+ "description": "Setup policy for the Python toolchain. Requires `futureFlags.experimentalPythonWorkspaces`.",
1046
+ "anyOf": [
1047
+ {
1048
+ "$ref": "#/definitions/ToolchainSetupPolicy"
1049
+ },
1050
+ {
1051
+ "type": "null"
1052
+ }
1053
+ ]
1054
+ },
1055
+ "rust": {
1056
+ "description": "Setup policy for the Rust toolchain. Requires `futureFlags.experimentalCargoWorkspaces`.",
1057
+ "anyOf": [
1058
+ {
1059
+ "$ref": "#/definitions/ToolchainSetupPolicy"
1060
+ },
1061
+ {
1062
+ "type": "null"
1063
+ }
1064
+ ]
1065
+ },
1066
+ "tools": {
1067
+ "description": "How `turbo setup` prepares tools for every toolchain.",
1068
+ "anyOf": [
1069
+ {
1070
+ "$ref": "#/definitions/ToolPolicy"
1071
+ },
1072
+ {
1073
+ "type": "null"
1074
+ }
1075
+ ]
1076
+ }
1077
+ }
1078
+ },
807
1079
  "String": {
808
1080
  "type": "string"
809
1081
  },
@@ -882,6 +1154,39 @@
882
1154
  }
883
1155
  ]
884
1156
  },
1157
+ "ToolPolicy": {
1158
+ "description": "How `turbo setup` prepares a toolchain's tools. `managed` provisions the locked version for this repository. `verify-system` uses an installed tool after verifying that it matches the locked version. `skip` neither provisions nor verifies the tool, which also skips the toolchain's dependencies.",
1159
+ "type": "string",
1160
+ "enum": ["managed", "verify-system", "skip"]
1161
+ },
1162
+ "ToolchainSetupPolicy": {
1163
+ "description": "Setup policy for one toolchain. Omitted values use the root `setup` values, then the inferred default.",
1164
+ "type": "object",
1165
+ "properties": {
1166
+ "dependencies": {
1167
+ "description": "How `turbo setup` prepares this toolchain's dependencies.",
1168
+ "anyOf": [
1169
+ {
1170
+ "$ref": "#/definitions/DependencyPolicy"
1171
+ },
1172
+ {
1173
+ "type": "null"
1174
+ }
1175
+ ]
1176
+ },
1177
+ "tools": {
1178
+ "description": "How `turbo setup` prepares this toolchain's tools.",
1179
+ "anyOf": [
1180
+ {
1181
+ "$ref": "#/definitions/ToolPolicy"
1182
+ },
1183
+ {
1184
+ "type": "null"
1185
+ }
1186
+ ]
1187
+ }
1188
+ }
1189
+ },
885
1190
  "UI": {
886
1191
  "description": "Enable use of the UI for `turbo`.\n\nDocumentation: https://turborepo.dev/docs/reference/configuration#ui",
887
1192
  "oneOf": [