devlanes 0.2.0 → 0.3.0
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/README.md +3 -1
- package/bin/{devlanes.js → devlanes} +3 -1
- package/install.js +75 -0
- package/package.json +10 -6
- package/schema.json +1025 -882
- package/user-schema.json +483 -389
package/user-schema.json
CHANGED
|
@@ -6,49 +6,48 @@
|
|
|
6
6
|
"examples": [
|
|
7
7
|
"5GiB"
|
|
8
8
|
],
|
|
9
|
+
"markdownDescription": "A byte count with decimal or binary size units.",
|
|
9
10
|
"pattern": "^[0-9]+(B|KB|MB|GB|KiB|MiB|GiB)$",
|
|
10
11
|
"type": "string"
|
|
11
12
|
},
|
|
12
13
|
"CaKind": {
|
|
13
|
-
"description": "Certificate authority
|
|
14
|
+
"description": "Certificate authority that signs HTTPS certificates for lane hostnames.",
|
|
15
|
+
"enum": [
|
|
16
|
+
"devlanes",
|
|
17
|
+
"mkcert"
|
|
18
|
+
],
|
|
19
|
+
"enumDescriptions": [
|
|
20
|
+
"devlanes creates its own CA in `~/.devlanes/ca` on first use, limited to names under `localhost`, `test`, `internal`, `home.arpa` and `hostnames.tld`, so it cannot sign for real sites. Trust it once with `devlanes certs trust`.",
|
|
21
|
+
"Load mkcert's existing root CA (from `mkcert -CAROOT`) instead, so browsers that already trust it need nothing new. HTTPS stays off when `mkcert` is not on `PATH`; the mkcert CA has no name limits, and `certs untrust` leaves it trusted."
|
|
22
|
+
],
|
|
14
23
|
"examples": [
|
|
15
24
|
"devlanes",
|
|
16
25
|
"mkcert"
|
|
17
26
|
],
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
],
|
|
25
|
-
"type": "string"
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"const": "mkcert",
|
|
29
|
-
"description": "Reuse the CA in mkcert's CAROOT directory.",
|
|
30
|
-
"examples": [
|
|
31
|
-
"mkcert"
|
|
32
|
-
],
|
|
33
|
-
"type": "string"
|
|
34
|
-
}
|
|
35
|
-
]
|
|
27
|
+
"markdownDescription": "Certificate authority that signs HTTPS certificates for lane hostnames.",
|
|
28
|
+
"markdownEnumDescriptions": [
|
|
29
|
+
"devlanes creates its own CA in `~/.devlanes/ca` on first use, limited to names under `localhost`, `test`, `internal`, `home.arpa` and `hostnames.tld`, so it cannot sign for real sites. Trust it once with `devlanes certs trust`.",
|
|
30
|
+
"Load mkcert's existing root CA (from `mkcert -CAROOT`) instead, so browsers that already trust it need nothing new. HTTPS stays off when `mkcert` is not on `PATH`; the mkcert CA has no name limits, and `certs untrust` leaves it trusted."
|
|
31
|
+
],
|
|
32
|
+
"type": "string"
|
|
36
33
|
},
|
|
37
34
|
"CloudflareDns": {
|
|
38
35
|
"additionalProperties": false,
|
|
39
|
-
"description": "Cloudflare DNS credentials for the
|
|
36
|
+
"description": "Reserved Cloudflare DNS credentials for the planned `public` resolver; not supported yet.",
|
|
40
37
|
"examples": [
|
|
41
38
|
{
|
|
42
39
|
"token": "${{ env.CF_API_TOKEN }}"
|
|
43
40
|
}
|
|
44
41
|
],
|
|
42
|
+
"markdownDescription": "Reserved Cloudflare DNS credentials for the planned `public` resolver; not supported yet.",
|
|
45
43
|
"properties": {
|
|
46
44
|
"token": {
|
|
47
45
|
"$ref": "#/$defs/Templated_string",
|
|
48
|
-
"description": "API token
|
|
46
|
+
"description": "Reserved: Cloudflare API token allowed to edit the domain's DNS records. Write an environment expression such as `${{ env.CF_API_TOKEN }}`, not the token itself.",
|
|
49
47
|
"examples": [
|
|
50
48
|
"${{ env.CF_API_TOKEN }}"
|
|
51
|
-
]
|
|
49
|
+
],
|
|
50
|
+
"markdownDescription": "Reserved: Cloudflare API token allowed to edit the domain's DNS records. Write an environment expression such as `${{ env.CF_API_TOKEN }}`, not the token itself."
|
|
52
51
|
}
|
|
53
52
|
},
|
|
54
53
|
"required": [
|
|
@@ -57,17 +56,18 @@
|
|
|
57
56
|
"type": "object"
|
|
58
57
|
},
|
|
59
58
|
"ConfigDuration": {
|
|
60
|
-
"description": "A duration
|
|
59
|
+
"description": "A duration: a whole number followed by `ms`, `s`, `m`, `h` or `d`, such as `500ms`, `15s` or `10m`. Units cannot be combined.",
|
|
61
60
|
"examples": [
|
|
62
61
|
"15s",
|
|
63
62
|
"10m"
|
|
64
63
|
],
|
|
64
|
+
"markdownDescription": "A duration: a whole number followed by `ms`, `s`, `m`, `h` or `d`, such as `500ms`, `15s` or `10m`. Units cannot be combined.",
|
|
65
65
|
"pattern": "^[0-9]+(ms|s|m|h|d)$",
|
|
66
66
|
"type": "string"
|
|
67
67
|
},
|
|
68
68
|
"DnsProvider": {
|
|
69
69
|
"additionalProperties": false,
|
|
70
|
-
"description": "Reserved DNS-01 provider
|
|
70
|
+
"description": "Reserved DNS-01 provider settings for the planned `public` resolver; not supported yet.",
|
|
71
71
|
"examples": [
|
|
72
72
|
{
|
|
73
73
|
"cloudflare": {
|
|
@@ -75,15 +75,17 @@
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
],
|
|
78
|
+
"markdownDescription": "Reserved DNS-01 provider settings for the planned `public` resolver; not supported yet.",
|
|
78
79
|
"properties": {
|
|
79
80
|
"cloudflare": {
|
|
80
81
|
"$ref": "#/$defs/CloudflareDns",
|
|
81
|
-
"description": "Cloudflare
|
|
82
|
+
"description": "Reserved: Cloudflare credentials for DNS-01 certificates; not supported yet.",
|
|
82
83
|
"examples": [
|
|
83
84
|
{
|
|
84
85
|
"token": "${{ env.CF_API_TOKEN }}"
|
|
85
86
|
}
|
|
86
|
-
]
|
|
87
|
+
],
|
|
88
|
+
"markdownDescription": "Reserved: Cloudflare credentials for DNS-01 certificates; not supported yet."
|
|
87
89
|
}
|
|
88
90
|
},
|
|
89
91
|
"required": [
|
|
@@ -93,38 +95,41 @@
|
|
|
93
95
|
},
|
|
94
96
|
"HistoryConfig": {
|
|
95
97
|
"additionalProperties": false,
|
|
96
|
-
"description": "
|
|
98
|
+
"description": "How long the daemon's database keeps records of finished runs and of remote boxes. An hourly cleanup deletes what is older.",
|
|
97
99
|
"examples": [
|
|
98
100
|
{
|
|
99
101
|
"remote_hosts_retention": "90d",
|
|
100
102
|
"retention": "7d"
|
|
101
103
|
}
|
|
102
104
|
],
|
|
105
|
+
"markdownDescription": "How long the daemon's database keeps records of finished runs and of remote boxes. An hourly cleanup deletes what is older.",
|
|
103
106
|
"properties": {
|
|
104
107
|
"remote_hosts_retention": {
|
|
105
108
|
"$ref": "#/$defs/ConfigDuration",
|
|
106
109
|
"default": "7776000000ms",
|
|
107
|
-
"description": "
|
|
110
|
+
"description": "How long a remote box stays listed by `devlanes remote ls` after its last successful connection; defaults to `90d` and must be longer than `0s`. A record without a connection time is never deleted by age, and `state.max_size` can delete records sooner.",
|
|
108
111
|
"examples": [
|
|
109
112
|
"90d",
|
|
110
113
|
"180d"
|
|
111
|
-
]
|
|
114
|
+
],
|
|
115
|
+
"markdownDescription": "How long a remote box stays listed by `devlanes remote ls` after its last successful connection; defaults to `90d` and must be longer than `0s`. A record without a connection time is never deleted by age, and `state.max_size` can delete records sooner."
|
|
112
116
|
},
|
|
113
117
|
"retention": {
|
|
114
118
|
"$ref": "#/$defs/ConfigDuration",
|
|
115
119
|
"default": "604800000ms",
|
|
116
|
-
"description": "
|
|
120
|
+
"description": "How long records of finished service and task runs (start and end times, exit status) are kept after the run ends; defaults to `7d` and must be longer than `0s`. A run that still has log index entries or a metrics summary in the database stays until those expire, and `state.max_size` can delete runs sooner.",
|
|
117
121
|
"examples": [
|
|
118
122
|
"7d",
|
|
119
123
|
"30d"
|
|
120
|
-
]
|
|
124
|
+
],
|
|
125
|
+
"markdownDescription": "How long records of finished service and task runs (start and end times, exit status) are kept after the run ends; defaults to `7d` and must be longer than `0s`. A run that still has log index entries or a metrics summary in the database stays until those expire, and `state.max_size` can delete runs sooner."
|
|
121
126
|
}
|
|
122
127
|
},
|
|
123
128
|
"type": "object"
|
|
124
129
|
},
|
|
125
130
|
"HostnamesConfig": {
|
|
126
131
|
"additionalProperties": false,
|
|
127
|
-
"description": "
|
|
132
|
+
"description": "How lane hostnames resolve to this machine, and whether they are also written to `/etc/hosts` for programs that cannot resolve them otherwise.",
|
|
128
133
|
"examples": [
|
|
129
134
|
{
|
|
130
135
|
"hosts_file": "auto",
|
|
@@ -135,13 +140,15 @@
|
|
|
135
140
|
"tld": "test"
|
|
136
141
|
}
|
|
137
142
|
],
|
|
143
|
+
"markdownDescription": "How lane hostnames resolve to this machine, and whether they are also written to `/etc/hosts` for programs that cannot resolve them otherwise.",
|
|
138
144
|
"properties": {
|
|
139
145
|
"base_domain": {
|
|
140
146
|
"default": null,
|
|
141
|
-
"description": "Reserved public
|
|
147
|
+
"description": "Reserved for the planned `public` resolver; any value is rejected for now.",
|
|
142
148
|
"examples": [
|
|
143
149
|
"dev.example.invalid"
|
|
144
150
|
],
|
|
151
|
+
"markdownDescription": "Reserved for the planned `public` resolver; any value is rejected for now.",
|
|
145
152
|
"type": [
|
|
146
153
|
"string",
|
|
147
154
|
"null"
|
|
@@ -150,56 +157,66 @@
|
|
|
150
157
|
"dns_provider": {
|
|
151
158
|
"anyOf": [
|
|
152
159
|
{
|
|
153
|
-
"$ref": "#/$defs/DnsProvider"
|
|
160
|
+
"$ref": "#/$defs/DnsProvider",
|
|
161
|
+
"description": "",
|
|
162
|
+
"examples": [],
|
|
163
|
+
"markdownDescription": ""
|
|
154
164
|
},
|
|
155
165
|
{
|
|
156
166
|
"type": "null"
|
|
157
167
|
}
|
|
158
168
|
],
|
|
159
169
|
"default": null,
|
|
160
|
-
"description": "Reserved DNS-01
|
|
170
|
+
"description": "Reserved for the planned `public` resolver's DNS-01 certificates; any value is rejected for now.",
|
|
161
171
|
"examples": [
|
|
162
172
|
{
|
|
163
173
|
"cloudflare": {
|
|
164
174
|
"token": "${{ env.CF_API_TOKEN }}"
|
|
165
175
|
}
|
|
166
176
|
}
|
|
167
|
-
]
|
|
177
|
+
],
|
|
178
|
+
"markdownDescription": "Reserved for the planned `public` resolver's DNS-01 certificates; any value is rejected for now."
|
|
168
179
|
},
|
|
169
180
|
"hosts_file": {
|
|
170
181
|
"anyOf": [
|
|
171
182
|
{
|
|
172
|
-
"$ref": "#/$defs/HostsFile"
|
|
183
|
+
"$ref": "#/$defs/HostsFile",
|
|
184
|
+
"description": "",
|
|
185
|
+
"examples": [],
|
|
186
|
+
"markdownDescription": ""
|
|
173
187
|
},
|
|
174
188
|
{
|
|
175
189
|
"type": "null"
|
|
176
190
|
}
|
|
177
191
|
],
|
|
178
192
|
"default": null,
|
|
179
|
-
"description": "Whether
|
|
193
|
+
"description": "Whether lane hostnames are also written to `/etc/hosts`, for programs that do not resolve `*.localhost` themselves (workerd, musl or pure-Go binaries); defaults to `auto`, which writes them only when a probe at daemon start shows the system resolver fails `*.localhost`. `never` here wins over every project; otherwise a project's `lanes.hosts_file` replaces this value for that project. Writing needs the helper `devlanes certs trust --hosts` installs, only exact names are written (no wildcards), and `resolver: hosts_file` ignores this key.",
|
|
180
194
|
"examples": [
|
|
181
195
|
"auto",
|
|
182
196
|
"never",
|
|
183
197
|
"always"
|
|
184
|
-
]
|
|
198
|
+
],
|
|
199
|
+
"markdownDescription": "Whether lane hostnames are also written to `/etc/hosts`, for programs that do not resolve `*.localhost` themselves (workerd, musl or pure-Go binaries); defaults to `auto`, which writes them only when a probe at daemon start shows the system resolver fails `*.localhost`. `never` here wins over every project; otherwise a project's `lanes.hosts_file` replaces this value for that project. Writing needs the helper `devlanes certs trust --hosts` installs, only exact names are written (no wildcards), and `resolver: hosts_file` ignores this key."
|
|
185
200
|
},
|
|
186
201
|
"resolver": {
|
|
187
202
|
"$ref": "#/$defs/Resolver",
|
|
188
203
|
"default": "localhost",
|
|
189
|
-
"description": "
|
|
204
|
+
"description": "Which domain lanes get and what makes their hostnames resolve; defaults to `localhost`. `resolver` also needs `tld` and a one-time `devlanes certs trust --resolver`; `public` is not supported yet.",
|
|
190
205
|
"examples": [
|
|
191
206
|
"localhost",
|
|
192
207
|
"hosts_file",
|
|
193
208
|
"resolver",
|
|
194
209
|
"public"
|
|
195
|
-
]
|
|
210
|
+
],
|
|
211
|
+
"markdownDescription": "Which domain lanes get and what makes their hostnames resolve; defaults to `localhost`. `resolver` also needs `tld` and a one-time `devlanes certs trust --resolver`; `public` is not supported yet."
|
|
196
212
|
},
|
|
197
213
|
"tld": {
|
|
198
214
|
"default": null,
|
|
199
|
-
"description": "
|
|
215
|
+
"description": "Top-level domain for the `resolver` strategy, such as `test`; required there. It must be `test`, `internal`, `home.arpa` or a domain under one of them (or under `localhost`), made of valid DNS labels, because any other name could belong to a real site; the file is rejected otherwise, whatever the strategy. A new devlanes CA may sign names under the `tld` set when it is created, whatever the strategy, so switching to another `tld` later needs a new CA.",
|
|
200
216
|
"examples": [
|
|
201
217
|
"test"
|
|
202
218
|
],
|
|
219
|
+
"markdownDescription": "Top-level domain for the `resolver` strategy, such as `test`; required there. It must be `test`, `internal`, `home.arpa` or a domain under one of them (or under `localhost`), made of valid DNS labels, because any other name could belong to a real site; the file is rejected otherwise, whatever the strategy. A new devlanes CA may sign names under the `tld` set when it is created, whatever the strategy, so switching to another `tld` later needs a new CA.",
|
|
203
220
|
"type": [
|
|
204
221
|
"string",
|
|
205
222
|
"null"
|
|
@@ -209,73 +226,67 @@
|
|
|
209
226
|
"type": "object"
|
|
210
227
|
},
|
|
211
228
|
"HostsFile": {
|
|
212
|
-
"description": "Whether
|
|
229
|
+
"description": "Whether routed hostnames are also written to `/etc/hosts`.",
|
|
230
|
+
"enum": [
|
|
231
|
+
"auto",
|
|
232
|
+
"never",
|
|
233
|
+
"always"
|
|
234
|
+
],
|
|
235
|
+
"enumDescriptions": [
|
|
236
|
+
"Write the exact hostnames only when the daemon's startup check finds that the system resolver does not answer `*.localhost` with a loopback address.",
|
|
237
|
+
"Never write hostnames to `/etc/hosts`. Set in the user config, it applies to every project whatever the project sets.",
|
|
238
|
+
"Always write the exact hostnames, even when the system resolver handles `*.localhost`, for programs that send `*.localhost` to DNS themselves."
|
|
239
|
+
],
|
|
213
240
|
"examples": [
|
|
214
241
|
"auto",
|
|
215
242
|
"never",
|
|
216
243
|
"always"
|
|
217
244
|
],
|
|
218
|
-
"
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
"type": "string"
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
"const": "never",
|
|
229
|
-
"description": "Do not write hosts entries.",
|
|
230
|
-
"examples": [
|
|
231
|
-
"never"
|
|
232
|
-
],
|
|
233
|
-
"type": "string"
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
"const": "always",
|
|
237
|
-
"description": "Always write exact hostnames, including for runtimes without localhost subdomain support.",
|
|
238
|
-
"examples": [
|
|
239
|
-
"always"
|
|
240
|
-
],
|
|
241
|
-
"type": "string"
|
|
242
|
-
}
|
|
243
|
-
]
|
|
245
|
+
"markdownDescription": "Whether routed hostnames are also written to `/etc/hosts`.",
|
|
246
|
+
"markdownEnumDescriptions": [
|
|
247
|
+
"Write the exact hostnames only when the daemon's startup check finds that the system resolver does not answer `*.localhost` with a loopback address.",
|
|
248
|
+
"Never write hostnames to `/etc/hosts`. Set in the user config, it applies to every project whatever the project sets.",
|
|
249
|
+
"Always write the exact hostnames, even when the system resolver handles `*.localhost`, for programs that send `*.localhost` to DNS themselves."
|
|
250
|
+
],
|
|
251
|
+
"type": "string"
|
|
244
252
|
},
|
|
245
253
|
"LogRetention": {
|
|
246
254
|
"additionalProperties": false,
|
|
247
|
-
"description": "
|
|
255
|
+
"description": "Limits for stored service output; reaching either one deletes the oldest output first.",
|
|
248
256
|
"examples": [
|
|
249
257
|
{
|
|
250
258
|
"days": 7,
|
|
251
259
|
"max_size": "5GiB"
|
|
252
260
|
}
|
|
253
261
|
],
|
|
262
|
+
"markdownDescription": "Limits for stored service output; reaching either one deletes the oldest output first.",
|
|
254
263
|
"properties": {
|
|
255
264
|
"days": {
|
|
256
265
|
"default": 7,
|
|
257
|
-
"description": "
|
|
266
|
+
"description": "Delete output older than this many days, along with its index entries in the database; defaults to 7 and must be at least 1. The newest log file of each stopped service is kept.",
|
|
258
267
|
"examples": [
|
|
259
268
|
7
|
|
260
269
|
],
|
|
261
270
|
"format": "uint32",
|
|
262
|
-
"
|
|
271
|
+
"markdownDescription": "Delete output older than this many days, along with its index entries in the database; defaults to 7 and must be at least 1. The newest log file of each stopped service is kept.",
|
|
272
|
+
"minimum": 1,
|
|
263
273
|
"type": "integer"
|
|
264
274
|
},
|
|
265
275
|
"max_size": {
|
|
266
276
|
"$ref": "#/$defs/ByteSize",
|
|
267
277
|
"default": "5368709120B",
|
|
268
|
-
"description": "
|
|
278
|
+
"description": "Total size of stored output across all projects and lanes; defaults to `5GiB` and must be above zero. Over it, the oldest output goes first wherever it is, but each stopped service's newest file and up to 1 MiB of a running service's current file are kept.",
|
|
269
279
|
"examples": [
|
|
270
280
|
"5GiB"
|
|
271
|
-
]
|
|
281
|
+
],
|
|
282
|
+
"markdownDescription": "Total size of stored output across all projects and lanes; defaults to `5GiB` and must be above zero. Over it, the oldest output goes first wherever it is, but each stopped service's newest file and up to 1 MiB of a running service's current file are kept."
|
|
272
283
|
}
|
|
273
284
|
},
|
|
274
285
|
"type": "object"
|
|
275
286
|
},
|
|
276
287
|
"LogsConfig": {
|
|
277
288
|
"additionalProperties": false,
|
|
278
|
-
"description": "Retention
|
|
289
|
+
"description": "Retention of the service output stored under `~/.devlanes/logs`.",
|
|
279
290
|
"examples": [
|
|
280
291
|
{
|
|
281
292
|
"retention": {
|
|
@@ -284,6 +295,7 @@
|
|
|
284
295
|
}
|
|
285
296
|
}
|
|
286
297
|
],
|
|
298
|
+
"markdownDescription": "Retention of the service output stored under `~/.devlanes/logs`.",
|
|
287
299
|
"properties": {
|
|
288
300
|
"retention": {
|
|
289
301
|
"$ref": "#/$defs/LogRetention",
|
|
@@ -291,34 +303,37 @@
|
|
|
291
303
|
"days": 7,
|
|
292
304
|
"max_size": "5368709120B"
|
|
293
305
|
},
|
|
294
|
-
"description": "Age and total-size
|
|
306
|
+
"description": "Age and total-size limits for stored service output; a cleanup every 10 minutes deletes the oldest output past either one. Defaults to 7 days and `5GiB`.",
|
|
295
307
|
"examples": [
|
|
296
308
|
{
|
|
297
309
|
"days": 7,
|
|
298
310
|
"max_size": "5GiB"
|
|
299
311
|
}
|
|
300
|
-
]
|
|
312
|
+
],
|
|
313
|
+
"markdownDescription": "Age and total-size limits for stored service output; a cleanup every 10 minutes deletes the oldest output past either one. Defaults to 7 days and `5GiB`."
|
|
301
314
|
}
|
|
302
315
|
},
|
|
303
316
|
"type": "object"
|
|
304
317
|
},
|
|
305
318
|
"MetricsConfig": {
|
|
306
319
|
"additionalProperties": false,
|
|
307
|
-
"description": "Retention
|
|
320
|
+
"description": "Retention of the CPU and memory history in the daemon's database.",
|
|
308
321
|
"examples": [
|
|
309
322
|
{
|
|
310
323
|
"retention": "7d"
|
|
311
324
|
}
|
|
312
325
|
],
|
|
326
|
+
"markdownDescription": "Retention of the CPU and memory history in the daemon's database.",
|
|
313
327
|
"properties": {
|
|
314
328
|
"retention": {
|
|
315
329
|
"$ref": "#/$defs/ConfigDuration",
|
|
316
330
|
"default": "604800000ms",
|
|
317
|
-
"description": "
|
|
331
|
+
"description": "How long per-minute CPU and memory samples, per-run summaries and startup memory peaks are kept; defaults to `7d` and must be longer than `0s`. Shorter keeps less history for graphs and for the memory a start is expected to need; `state.max_size` can delete samples sooner.",
|
|
318
332
|
"examples": [
|
|
319
333
|
"7d",
|
|
320
334
|
"30d"
|
|
321
|
-
]
|
|
335
|
+
],
|
|
336
|
+
"markdownDescription": "How long per-minute CPU and memory samples, per-run summaries and startup memory peaks are kept; defaults to `7d` and must be longer than `0s`. Shorter keeps less history for graphs and for the memory a start is expected to need; `state.max_size` can delete samples sooner."
|
|
322
337
|
}
|
|
323
338
|
},
|
|
324
339
|
"type": "object"
|
|
@@ -329,24 +344,27 @@
|
|
|
329
344
|
"75%",
|
|
330
345
|
"12.5%"
|
|
331
346
|
],
|
|
347
|
+
"markdownDescription": "A percentage with a `%` suffix, such as `75%` or `12.5%`.",
|
|
332
348
|
"pattern": "^\\s*([0-9]+\\.?[0-9]*|\\.[0-9]+)\\s*%\\s*$",
|
|
333
349
|
"type": "string"
|
|
334
350
|
},
|
|
335
351
|
"PortsConfig": {
|
|
336
352
|
"additionalProperties": false,
|
|
337
|
-
"description": "Machine-wide
|
|
353
|
+
"description": "Machine-wide pool every lane's block of ports comes from.",
|
|
338
354
|
"examples": [
|
|
339
355
|
{
|
|
340
356
|
"range": "20000-32767"
|
|
341
357
|
}
|
|
342
358
|
],
|
|
359
|
+
"markdownDescription": "Machine-wide pool every lane's block of ports comes from.",
|
|
343
360
|
"properties": {
|
|
344
361
|
"range": {
|
|
345
362
|
"default": "20000-32767",
|
|
346
|
-
"description": "
|
|
363
|
+
"description": "Ports devlanes may hand out, written `start-end` (both included, start above 0); defaults to `20000-32767`, below Linux's usual ephemeral range so the OS does not pick them for outgoing connections. Each lane of each project gets its own block of consecutive ports from it, so a smaller range fits fewer lanes.",
|
|
347
364
|
"examples": [
|
|
348
365
|
"20000-32767"
|
|
349
366
|
],
|
|
367
|
+
"markdownDescription": "Ports devlanes may hand out, written `start-end` (both included, start above 0); defaults to `20000-32767`, below Linux's usual ephemeral range so the OS does not pick them for outgoing connections. Each lane of each project gets its own block of consecutive ports from it, so a smaller range fits fewer lanes.",
|
|
350
368
|
"pattern": "^[0-9]+-[0-9]+$",
|
|
351
369
|
"type": "string"
|
|
352
370
|
}
|
|
@@ -355,7 +373,7 @@
|
|
|
355
373
|
},
|
|
356
374
|
"ProxyConfig": {
|
|
357
375
|
"additionalProperties": false,
|
|
358
|
-
"description": "Ports and network
|
|
376
|
+
"description": "Ports and network exposure of the daemon's proxy, which routes each lane hostname to its service.",
|
|
359
377
|
"examples": [
|
|
360
378
|
{
|
|
361
379
|
"http_port": 80,
|
|
@@ -363,89 +381,79 @@
|
|
|
363
381
|
"lan": false
|
|
364
382
|
}
|
|
365
383
|
],
|
|
384
|
+
"markdownDescription": "Ports and network exposure of the daemon's proxy, which routes each lane hostname to its service.",
|
|
366
385
|
"properties": {
|
|
367
386
|
"http_port": {
|
|
368
387
|
"default": 80,
|
|
369
|
-
"description": "
|
|
388
|
+
"description": "Port for plain HTTP; defaults to 80, falling back to 8080 like `https_port`, and must differ from it. While HTTPS runs it redirects known hostnames to HTTPS; without a CA it serves them over plain HTTP.",
|
|
370
389
|
"examples": [
|
|
371
390
|
80,
|
|
372
391
|
8080
|
|
373
392
|
],
|
|
374
393
|
"format": "uint16",
|
|
394
|
+
"markdownDescription": "Port for plain HTTP; defaults to 80, falling back to 8080 like `https_port`, and must differ from it. While HTTPS runs it redirects known hostnames to HTTPS; without a CA it serves them over plain HTTP.",
|
|
375
395
|
"maximum": 65535,
|
|
376
396
|
"minimum": 0,
|
|
377
397
|
"type": "integer"
|
|
378
398
|
},
|
|
379
399
|
"https_port": {
|
|
380
400
|
"default": 443,
|
|
381
|
-
"description": "HTTPS
|
|
401
|
+
"description": "Port the HTTPS proxy listens on; defaults to 443. When the port is taken or not allowed (low ports on Linux need extra permission), the daemon falls back to 8443 and service URLs carry the port.",
|
|
382
402
|
"examples": [
|
|
383
403
|
443,
|
|
384
404
|
8443
|
|
385
405
|
],
|
|
386
406
|
"format": "uint16",
|
|
407
|
+
"markdownDescription": "Port the HTTPS proxy listens on; defaults to 443. When the port is taken or not allowed (low ports on Linux need extra permission), the daemon falls back to 8443 and service URLs carry the port.",
|
|
387
408
|
"maximum": 65535,
|
|
388
409
|
"minimum": 0,
|
|
389
410
|
"type": "integer"
|
|
390
411
|
},
|
|
391
412
|
"lan": {
|
|
392
413
|
"default": false,
|
|
393
|
-
"description": "Accept connections from other
|
|
414
|
+
"description": "Accept connections from other devices on the network; defaults to false, which refuses every peer that is not this machine. Those devices must still resolve the hostnames to this machine and trust the CA.",
|
|
394
415
|
"examples": [
|
|
395
416
|
false,
|
|
396
417
|
true
|
|
397
418
|
],
|
|
419
|
+
"markdownDescription": "Accept connections from other devices on the network; defaults to false, which refuses every peer that is not this machine. Those devices must still resolve the hostnames to this machine and trust the CA.",
|
|
398
420
|
"type": "boolean"
|
|
399
421
|
}
|
|
400
422
|
},
|
|
401
423
|
"type": "object"
|
|
402
424
|
},
|
|
403
425
|
"Resolver": {
|
|
404
|
-
"description": "Strategy
|
|
426
|
+
"description": "Strategy that makes lane hostnames resolve to this machine.",
|
|
427
|
+
"enum": [
|
|
428
|
+
"localhost",
|
|
429
|
+
"hosts_file",
|
|
430
|
+
"resolver",
|
|
431
|
+
"public"
|
|
432
|
+
],
|
|
433
|
+
"enumDescriptions": [
|
|
434
|
+
"Lane domains end in `.localhost` (`acme.localhost`, `acme-2.localhost`), which browsers and many system resolvers send to loopback by themselves. `hosts_file` covers programs that do not.",
|
|
435
|
+
"Keep `.localhost` names and always write exact hostnames to `/etc/hosts`, as `hosts_file: always` does, whatever `hosts_file` says; a project's `lanes.hosts_file` still takes precedence. Needs the helper from `devlanes certs trust --hosts`.",
|
|
436
|
+
"Lane domains become `<project>.<tld>` and `<project>-<N>.<tld>`, answered by a DNS server the daemon runs on `127.0.0.1:15353`, so wildcard hostnames resolve too for programs that use the system resolver. Needs `tld` and a one-time `devlanes certs trust --resolver`; projects that set `lanes.vars.domain` or `lanes.matrix` keep their own domains.",
|
|
437
|
+
"Reserved for public DNS names with DNS-01 certificates; not supported yet, so the config is rejected."
|
|
438
|
+
],
|
|
405
439
|
"examples": [
|
|
406
440
|
"localhost",
|
|
407
441
|
"hosts_file",
|
|
408
442
|
"resolver",
|
|
409
443
|
"public"
|
|
410
444
|
],
|
|
411
|
-
"
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
},
|
|
420
|
-
{
|
|
421
|
-
"const": "hosts_file",
|
|
422
|
-
"description": "Resolve exact project names through system hosts-file entries.",
|
|
423
|
-
"examples": [
|
|
424
|
-
"hosts_file"
|
|
425
|
-
],
|
|
426
|
-
"type": "string"
|
|
427
|
-
},
|
|
428
|
-
{
|
|
429
|
-
"const": "resolver",
|
|
430
|
-
"description": "Use the daemon's DNS resolver for the configured custom top-level domain.",
|
|
431
|
-
"examples": [
|
|
432
|
-
"resolver"
|
|
433
|
-
],
|
|
434
|
-
"type": "string"
|
|
435
|
-
},
|
|
436
|
-
{
|
|
437
|
-
"const": "public",
|
|
438
|
-
"description": "Reserved public DNS and DNS-01 strategy; not supported yet.",
|
|
439
|
-
"examples": [
|
|
440
|
-
"public"
|
|
441
|
-
],
|
|
442
|
-
"type": "string"
|
|
443
|
-
}
|
|
444
|
-
]
|
|
445
|
+
"markdownDescription": "Strategy that makes lane hostnames resolve to this machine.",
|
|
446
|
+
"markdownEnumDescriptions": [
|
|
447
|
+
"Lane domains end in `.localhost` (`acme.localhost`, `acme-2.localhost`), which browsers and many system resolvers send to loopback by themselves. `hosts_file` covers programs that do not.",
|
|
448
|
+
"Keep `.localhost` names and always write exact hostnames to `/etc/hosts`, as `hosts_file: always` does, whatever `hosts_file` says; a project's `lanes.hosts_file` still takes precedence. Needs the helper from `devlanes certs trust --hosts`.",
|
|
449
|
+
"Lane domains become `<project>.<tld>` and `<project>-<N>.<tld>`, answered by a DNS server the daemon runs on `127.0.0.1:15353`, so wildcard hostnames resolve too for programs that use the system resolver. Needs `tld` and a one-time `devlanes certs trust --resolver`; projects that set `lanes.vars.domain` or `lanes.matrix` keep their own domains.",
|
|
450
|
+
"Reserved for public DNS names with DNS-01 certificates; not supported yet, so the config is rejected."
|
|
451
|
+
],
|
|
452
|
+
"type": "string"
|
|
445
453
|
},
|
|
446
454
|
"StartupConfig": {
|
|
447
455
|
"additionalProperties": false,
|
|
448
|
-
"description": "
|
|
456
|
+
"description": "Pacing of service starts, shared by every lane and project on this machine. Starts queue first come, first served; only spawning waits, running processes are never limited.",
|
|
449
457
|
"examples": [
|
|
450
458
|
{
|
|
451
459
|
"max": 4,
|
|
@@ -455,19 +463,22 @@
|
|
|
455
463
|
"initial": 2,
|
|
456
464
|
"max": 8,
|
|
457
465
|
"mode": "adaptive",
|
|
466
|
+
"reserve_memory": "2GiB",
|
|
458
467
|
"settle_cpu": "10%",
|
|
459
468
|
"slot_timeout": "20s",
|
|
460
469
|
"target_cpu": "75%"
|
|
461
470
|
}
|
|
462
471
|
],
|
|
472
|
+
"markdownDescription": "Pacing of service starts, shared by every lane and project on this machine. Starts queue first come, first served; only spawning waits, running processes are never limited.",
|
|
463
473
|
"properties": {
|
|
464
474
|
"initial": {
|
|
465
475
|
"default": null,
|
|
466
|
-
"description": "Adaptive starting window;
|
|
476
|
+
"description": "Adaptive starting window; defaults to `max`, so starts run at full speed until the machine is under pressure. Set it lower to ramp up from a few slots instead; never above `max`.",
|
|
467
477
|
"examples": [
|
|
468
478
|
2
|
|
469
479
|
],
|
|
470
480
|
"format": "uint32",
|
|
481
|
+
"markdownDescription": "Adaptive starting window; defaults to `max`, so starts run at full speed until the machine is under pressure. Set it lower to ramp up from a few slots instead; never above `max`.",
|
|
471
482
|
"minimum": 1,
|
|
472
483
|
"type": [
|
|
473
484
|
"integer",
|
|
@@ -476,11 +487,12 @@
|
|
|
476
487
|
},
|
|
477
488
|
"max": {
|
|
478
489
|
"default": null,
|
|
479
|
-
"description": "
|
|
490
|
+
"description": "Most services starting at once: the constant window in `fixed` mode and the ceiling in `adaptive` mode. Defaults to the number of CPU cores; `all` ignores it.",
|
|
480
491
|
"examples": [
|
|
481
492
|
8
|
|
482
493
|
],
|
|
483
494
|
"format": "uint32",
|
|
495
|
+
"markdownDescription": "Most services starting at once: the constant window in `fixed` mode and the ceiling in `adaptive` mode. Defaults to the number of CPU cores; `all` ignores it.",
|
|
484
496
|
"minimum": 1,
|
|
485
497
|
"type": [
|
|
486
498
|
"integer",
|
|
@@ -489,95 +501,112 @@
|
|
|
489
501
|
},
|
|
490
502
|
"mode": {
|
|
491
503
|
"$ref": "#/$defs/StartupMode",
|
|
492
|
-
"default": "
|
|
493
|
-
"description": "`adaptive`, `fixed` or `all`; default `
|
|
504
|
+
"default": "adaptive",
|
|
505
|
+
"description": "`adaptive`, `fixed` or `all`; default `adaptive`. A starting service holds its slot until its ready check (`tcp`, `http`, `log` or `cmd`) passes, it fails, or `slot_timeout` passes; one without a check (`ready: started`) holds it until it settles (`settle_cpu`).",
|
|
494
506
|
"examples": [
|
|
495
507
|
"adaptive",
|
|
496
508
|
"fixed",
|
|
497
509
|
"all"
|
|
498
|
-
]
|
|
510
|
+
],
|
|
511
|
+
"markdownDescription": "`adaptive`, `fixed` or `all`; default `adaptive`. A starting service holds its slot until its ready check (`tcp`, `http`, `log` or `cmd`) passes, it fails, or `slot_timeout` passes; one without a check (`ready: started`) holds it until it settles (`settle_cpu`)."
|
|
512
|
+
},
|
|
513
|
+
"reserve_memory": {
|
|
514
|
+
"anyOf": [
|
|
515
|
+
{
|
|
516
|
+
"$ref": "#/$defs/ByteSize",
|
|
517
|
+
"description": "",
|
|
518
|
+
"examples": [],
|
|
519
|
+
"markdownDescription": ""
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
"type": "null"
|
|
523
|
+
}
|
|
524
|
+
],
|
|
525
|
+
"default": null,
|
|
526
|
+
"description": "Free memory every new start must leave, on top of the memory the services already starting are expected to still need (each one's past startup peak, or 512 MiB without history). Defaults to 10% of RAM, at most `2GiB`; `0B` turns it off. A start with nothing else starting never waits for it. `all` ignores it.",
|
|
527
|
+
"examples": [
|
|
528
|
+
"2GiB",
|
|
529
|
+
"0B"
|
|
530
|
+
],
|
|
531
|
+
"markdownDescription": "Free memory every new start must leave, on top of the memory the services already starting are expected to still need (each one's past startup peak, or 512 MiB without history). Defaults to 10% of RAM, at most `2GiB`; `0B` turns it off. A start with nothing else starting never waits for it. `all` ignores it."
|
|
499
532
|
},
|
|
500
533
|
"settle_cpu": {
|
|
501
534
|
"$ref": "#/$defs/Percent",
|
|
502
535
|
"default": "10%",
|
|
503
|
-
"description": "
|
|
536
|
+
"description": "Only for services without a ready check (`ready: started`, the default for a service without `hosts`): such a service gives its slot back once its process tree uses less than this share of one core for 2 s, meaning it has finished starting up. Services with a `tcp`, `http`, `log` or `cmd` check keep their slot until the check passes instead. Defaults to `10%`.",
|
|
504
537
|
"examples": [
|
|
505
538
|
"10%",
|
|
506
539
|
"12.5%"
|
|
507
|
-
]
|
|
540
|
+
],
|
|
541
|
+
"markdownDescription": "Only for services without a ready check (`ready: started`, the default for a service without `hosts`): such a service gives its slot back once its process tree uses less than this share of one core for 2 s, meaning it has finished starting up. Services with a `tcp`, `http`, `log` or `cmd` check keep their slot until the check passes instead. Defaults to `10%`."
|
|
508
542
|
},
|
|
509
543
|
"slot_timeout": {
|
|
510
544
|
"$ref": "#/$defs/ConfigDuration",
|
|
511
545
|
"default": "20000ms",
|
|
512
|
-
"description": "
|
|
546
|
+
"description": "Longest a starting service holds its slot; after it, the next queued service may start even if this one is not ready, so services waiting on each other cannot block the queue. Defaults to `20s` and must be above zero; the service itself keeps starting.",
|
|
513
547
|
"examples": [
|
|
514
548
|
"15s",
|
|
515
549
|
"10m"
|
|
516
|
-
]
|
|
550
|
+
],
|
|
551
|
+
"markdownDescription": "Longest a starting service holds its slot; after it, the next queued service may start even if this one is not ready, so services waiting on each other cannot block the queue. Defaults to `20s` and must be above zero; the service itself keeps starting."
|
|
517
552
|
},
|
|
518
553
|
"target_cpu": {
|
|
519
554
|
"$ref": "#/$defs/Percent",
|
|
520
555
|
"default": "75%",
|
|
521
|
-
"description": "
|
|
556
|
+
"description": "System CPU use below which `adaptive` mode adds slots; defaults to `75%`, and must be above 0% and at most 100%. Lower it to keep the machine responsive during large starts; other modes ignore it.",
|
|
522
557
|
"examples": [
|
|
523
558
|
"75%",
|
|
524
559
|
"80%"
|
|
525
|
-
]
|
|
560
|
+
],
|
|
561
|
+
"markdownDescription": "System CPU use below which `adaptive` mode adds slots; defaults to `75%`, and must be above 0% and at most 100%. Lower it to keep the machine responsive during large starts; other modes ignore it."
|
|
526
562
|
}
|
|
527
563
|
},
|
|
528
564
|
"type": "object"
|
|
529
565
|
},
|
|
530
566
|
"StartupMode": {
|
|
531
|
-
"description": "How the start
|
|
567
|
+
"description": "How the number of services allowed to start at once is chosen.",
|
|
568
|
+
"enum": [
|
|
569
|
+
"adaptive",
|
|
570
|
+
"fixed",
|
|
571
|
+
"all"
|
|
572
|
+
],
|
|
573
|
+
"enumDescriptions": [
|
|
574
|
+
"Begin each burst of starts at `initial` (by default `max`, full speed). Halve the slots after 3 s above 90% CPU or when the system reports memory pressure, start nothing while that pressure is critical, and add a slot every 2 s while system CPU stays below `target_cpu`, up to `max`.",
|
|
575
|
+
"Allow `max` starts at a time, never more or fewer. A start also waits while free memory cannot fit what it needs.",
|
|
576
|
+
"Start every service immediately, with no limit and no memory check."
|
|
577
|
+
],
|
|
532
578
|
"examples": [
|
|
533
579
|
"adaptive",
|
|
534
580
|
"fixed",
|
|
535
581
|
"all"
|
|
536
582
|
],
|
|
537
|
-
"
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
"type": "string"
|
|
545
|
-
},
|
|
546
|
-
{
|
|
547
|
-
"const": "fixed",
|
|
548
|
-
"description": "Always `max` starts at a time.",
|
|
549
|
-
"examples": [
|
|
550
|
-
"fixed"
|
|
551
|
-
],
|
|
552
|
-
"type": "string"
|
|
553
|
-
},
|
|
554
|
-
{
|
|
555
|
-
"const": "all",
|
|
556
|
-
"description": "No pacing: every service starts at once.",
|
|
557
|
-
"examples": [
|
|
558
|
-
"all"
|
|
559
|
-
],
|
|
560
|
-
"type": "string"
|
|
561
|
-
}
|
|
562
|
-
]
|
|
583
|
+
"markdownDescription": "How the number of services allowed to start at once is chosen.",
|
|
584
|
+
"markdownEnumDescriptions": [
|
|
585
|
+
"Begin each burst of starts at `initial` (by default `max`, full speed). Halve the slots after 3 s above 90% CPU or when the system reports memory pressure, start nothing while that pressure is critical, and add a slot every 2 s while system CPU stays below `target_cpu`, up to `max`.",
|
|
586
|
+
"Allow `max` starts at a time, never more or fewer. A start also waits while free memory cannot fit what it needs.",
|
|
587
|
+
"Start every service immediately, with no limit and no memory check."
|
|
588
|
+
],
|
|
589
|
+
"type": "string"
|
|
563
590
|
},
|
|
564
591
|
"StateConfig": {
|
|
565
592
|
"additionalProperties": false,
|
|
566
|
-
"description": "
|
|
593
|
+
"description": "Size budget for the daemon's SQLite database, enforced by its hourly cleanup.",
|
|
567
594
|
"examples": [
|
|
568
595
|
{
|
|
569
596
|
"max_size": "512MiB"
|
|
570
597
|
}
|
|
571
598
|
],
|
|
599
|
+
"markdownDescription": "Size budget for the daemon's SQLite database, enforced by its hourly cleanup.",
|
|
572
600
|
"properties": {
|
|
573
601
|
"max_size": {
|
|
574
602
|
"$ref": "#/$defs/ByteSize",
|
|
575
603
|
"default": "536870912B",
|
|
576
|
-
"description": "
|
|
604
|
+
"description": "Size the database (`state.db` with its WAL and shared-memory files) should stay under; defaults to `512MiB` and must be above zero. When it is larger, the cleanup deletes the oldest metric samples first, then the oldest history (finished runs, log index entries, remote boxes), even before their retention ends. Lanes, ports and running units are never deleted, so the file can stay above the budget.",
|
|
577
605
|
"examples": [
|
|
578
606
|
"512MiB",
|
|
579
607
|
"1GiB"
|
|
580
|
-
]
|
|
608
|
+
],
|
|
609
|
+
"markdownDescription": "Size the database (`state.db` with its WAL and shared-memory files) should stay under; defaults to `512MiB` and must be above zero. When it is larger, the cleanup deletes the oldest metric samples first, then the oldest history (finished runs, log index entries, remote boxes), even before their retention ends. Lanes, ports and running units are never deleted, so the file can stay above the budget."
|
|
581
610
|
}
|
|
582
611
|
},
|
|
583
612
|
"type": "object"
|
|
@@ -585,110 +614,159 @@
|
|
|
585
614
|
"Templated_string": {
|
|
586
615
|
"anyOf": [
|
|
587
616
|
{
|
|
588
|
-
"description": "Literal value used without expression evaluation.",
|
|
589
617
|
"type": "string"
|
|
590
618
|
},
|
|
591
619
|
{
|
|
592
|
-
"description": "Text containing `${{ ... }}`, evaluated for each lane; write `${{ '${{' }}` for a literal `${{`.",
|
|
593
|
-
"examples": [
|
|
594
|
-
"${{ lane.index }}"
|
|
595
|
-
],
|
|
596
620
|
"pattern": "\\$\\{\\{",
|
|
597
621
|
"type": "string"
|
|
598
622
|
}
|
|
599
623
|
],
|
|
600
|
-
"description": "A
|
|
624
|
+
"description": "A plain value or text with `${{ ... }}` expressions, evaluated for each lane with names such as `lane`, `self`, `services`, `infra` and `env`. A value that is one whole expression keeps its type, which must fit the setting. Write `${{ '${{' }}` for a literal `${{`.",
|
|
601
625
|
"examples": [
|
|
602
626
|
"${{ lane.index }}"
|
|
603
|
-
]
|
|
627
|
+
],
|
|
628
|
+
"markdownDescription": "A plain value or text with `${{ ... }}` expressions, evaluated for each lane with names such as `lane`, `self`, `services`, `infra` and `env`. A value that is one whole expression keeps its type, which must fit the setting. Write `${{ '${{' }}` for a literal `${{`."
|
|
604
629
|
},
|
|
605
630
|
"TerminalConfig": {
|
|
606
631
|
"anyOf": [
|
|
607
632
|
{
|
|
608
|
-
"description": "A terminal app name from when devlanes opened units in a new terminal\nwindow; that feature is gone, so the name is ignored with a warning.",
|
|
609
|
-
"examples": [
|
|
610
|
-
"ghostty"
|
|
611
|
-
],
|
|
612
633
|
"type": "string"
|
|
613
634
|
},
|
|
614
635
|
{
|
|
615
636
|
"$ref": "#/$defs/TerminalSettings",
|
|
616
|
-
"description": "
|
|
617
|
-
"examples": [
|
|
618
|
-
|
|
619
|
-
"progress": "never"
|
|
620
|
-
}
|
|
621
|
-
]
|
|
637
|
+
"description": "",
|
|
638
|
+
"examples": [],
|
|
639
|
+
"markdownDescription": ""
|
|
622
640
|
}
|
|
623
641
|
],
|
|
624
|
-
"description": "
|
|
642
|
+
"description": "Terminal integration of the CLI, or a terminal app name from older versions, which is ignored.",
|
|
625
643
|
"examples": [
|
|
626
644
|
{
|
|
627
645
|
"progress": "auto"
|
|
628
646
|
}
|
|
629
|
-
]
|
|
647
|
+
],
|
|
648
|
+
"markdownDescription": "Terminal integration of the CLI, or a terminal app name from older versions, which is ignored."
|
|
649
|
+
},
|
|
650
|
+
"TerminalFeature": {
|
|
651
|
+
"description": "When devlanes uses a terminal feature (title, links, notifications, marks).",
|
|
652
|
+
"enum": [
|
|
653
|
+
"auto",
|
|
654
|
+
"always",
|
|
655
|
+
"never"
|
|
656
|
+
],
|
|
657
|
+
"enumDescriptions": [
|
|
658
|
+
"Only in terminals known to support it, on human output to a terminal; never inside tmux, screen, CI or a dumb terminal.",
|
|
659
|
+
"In every terminal, tmux included; a terminal without support may ignore it, or keep a title devlanes cannot put back.",
|
|
660
|
+
"Never use it."
|
|
661
|
+
],
|
|
662
|
+
"examples": [
|
|
663
|
+
"auto",
|
|
664
|
+
"always",
|
|
665
|
+
"never"
|
|
666
|
+
],
|
|
667
|
+
"markdownDescription": "When devlanes uses a terminal feature (title, links, notifications, marks).",
|
|
668
|
+
"markdownEnumDescriptions": [
|
|
669
|
+
"Only in terminals known to support it, on human output to a terminal; never inside tmux, screen, CI or a dumb terminal.",
|
|
670
|
+
"In every terminal, tmux included; a terminal without support may ignore it, or keep a title devlanes cannot put back.",
|
|
671
|
+
"Never use it."
|
|
672
|
+
],
|
|
673
|
+
"type": "string"
|
|
630
674
|
},
|
|
631
675
|
"TerminalProgress": {
|
|
632
|
-
"description": "When start progress goes to the terminal tab's progress bar.
|
|
676
|
+
"description": "When start progress goes to the terminal tab's progress bar.",
|
|
677
|
+
"enum": [
|
|
678
|
+
"auto",
|
|
679
|
+
"always",
|
|
680
|
+
"never"
|
|
681
|
+
],
|
|
682
|
+
"enumDescriptions": [
|
|
683
|
+
"Only in terminals known to draw it (Ghostty, WezTerm, iTerm2 3.6.6+, Windows Terminal, ConEmu, Ptyxis 48+, Konsole 26.04+); never inside tmux, screen, CI or a dumb terminal.",
|
|
684
|
+
"In every terminal, for ones `auto` does not recognize such as kitty; a terminal without support may ignore it or show it as text or a notification. Inside tmux it is passed through, which needs `allow-passthrough on`.",
|
|
685
|
+
"Never draw the progress bar."
|
|
686
|
+
],
|
|
633
687
|
"examples": [
|
|
634
688
|
"auto",
|
|
635
689
|
"always",
|
|
636
690
|
"never"
|
|
637
691
|
],
|
|
638
|
-
"
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
"type": "string"
|
|
646
|
-
},
|
|
647
|
-
{
|
|
648
|
-
"const": "always",
|
|
649
|
-
"description": "In any terminal, also kitty 0.47 or later and inside tmux (needs `allow-passthrough on`).",
|
|
650
|
-
"examples": [
|
|
651
|
-
"always"
|
|
652
|
-
],
|
|
653
|
-
"type": "string"
|
|
654
|
-
},
|
|
655
|
-
{
|
|
656
|
-
"const": "never",
|
|
657
|
-
"description": "Never.",
|
|
658
|
-
"examples": [
|
|
659
|
-
"never"
|
|
660
|
-
],
|
|
661
|
-
"type": "string"
|
|
662
|
-
}
|
|
663
|
-
]
|
|
692
|
+
"markdownDescription": "When start progress goes to the terminal tab's progress bar.",
|
|
693
|
+
"markdownEnumDescriptions": [
|
|
694
|
+
"Only in terminals known to draw it (Ghostty, WezTerm, iTerm2 3.6.6+, Windows Terminal, ConEmu, Ptyxis 48+, Konsole 26.04+); never inside tmux, screen, CI or a dumb terminal.",
|
|
695
|
+
"In every terminal, for ones `auto` does not recognize such as kitty; a terminal without support may ignore it or show it as text or a notification. Inside tmux it is passed through, which needs `allow-passthrough on`.",
|
|
696
|
+
"Never draw the progress bar."
|
|
697
|
+
],
|
|
698
|
+
"type": "string"
|
|
664
699
|
},
|
|
665
700
|
"TerminalSettings": {
|
|
666
701
|
"additionalProperties": false,
|
|
667
|
-
"description": "How devlanes uses the terminal
|
|
702
|
+
"description": "How devlanes uses the terminal: its progress bar, tab title, links, notifications and marks.",
|
|
668
703
|
"examples": [
|
|
669
704
|
{
|
|
670
705
|
"progress": "auto"
|
|
671
706
|
},
|
|
672
707
|
{
|
|
673
|
-
"progress": "never"
|
|
708
|
+
"progress": "never",
|
|
709
|
+
"title": "never"
|
|
674
710
|
}
|
|
675
711
|
],
|
|
712
|
+
"markdownDescription": "How devlanes uses the terminal: its progress bar, tab title, links, notifications and marks.",
|
|
676
713
|
"properties": {
|
|
714
|
+
"links": {
|
|
715
|
+
"$ref": "#/$defs/TerminalFeature",
|
|
716
|
+
"default": "auto",
|
|
717
|
+
"description": "Whether service URLs, config error locations and log or bundle paths are clickable links (the OSC 8 sequence); defaults to `auto`, which writes them in iTerm2, kitty, WezTerm, Ghostty, Windows Terminal, VTE terminals, Konsole, Alacritty and foot. Elsewhere the same text prints without a link. `DEVLANES_TERM_LINKS=0` or `1` overrides this setting.",
|
|
718
|
+
"examples": [
|
|
719
|
+
"auto",
|
|
720
|
+
"never"
|
|
721
|
+
],
|
|
722
|
+
"markdownDescription": "Whether service URLs, config error locations and log or bundle paths are clickable links (the OSC 8 sequence); defaults to `auto`, which writes them in iTerm2, kitty, WezTerm, Ghostty, Windows Terminal, VTE terminals, Konsole, Alacritty and foot. Elsewhere the same text prints without a link. `DEVLANES_TERM_LINKS=0` or `1` overrides this setting."
|
|
723
|
+
},
|
|
724
|
+
"marks": {
|
|
725
|
+
"$ref": "#/$defs/TerminalFeature",
|
|
726
|
+
"default": "auto",
|
|
727
|
+
"description": "Whether long command output (logs of several services, failed starts) marks where each section starts, so the terminal's jump-to-mark or jump-to-prompt keys move between them; defaults to `auto`: marks in iTerm2, and prompt marks (OSC 133) in WezTerm, Ghostty, kitty, foot and Windows Terminal. `DEVLANES_TERM_MARKS=0` or `1` overrides this setting.",
|
|
728
|
+
"examples": [
|
|
729
|
+
"auto",
|
|
730
|
+
"never"
|
|
731
|
+
],
|
|
732
|
+
"markdownDescription": "Whether long command output (logs of several services, failed starts) marks where each section starts, so the terminal's jump-to-mark or jump-to-prompt keys move between them; defaults to `auto`: marks in iTerm2, and prompt marks (OSC 133) in WezTerm, Ghostty, kitty, foot and Windows Terminal. `DEVLANES_TERM_MARKS=0` or `1` overrides this setting."
|
|
733
|
+
},
|
|
734
|
+
"notifications": {
|
|
735
|
+
"$ref": "#/$defs/TerminalFeature",
|
|
736
|
+
"default": "auto",
|
|
737
|
+
"description": "Whether a start that took a while finishing or failing, and a running service crashing, show a desktop notification while the terminal is not focused; defaults to `auto`. The TUI knows focus from the terminal; a command such as `devlanes start` does not, so with `auto` it notifies only in kitty, which itself skips a focused window. Terminals without notifications get the bell. At most one notification per 10 seconds. `DEVLANES_TERM_NOTIFICATIONS=0` or `1` overrides this setting.",
|
|
738
|
+
"examples": [
|
|
739
|
+
"auto",
|
|
740
|
+
"never"
|
|
741
|
+
],
|
|
742
|
+
"markdownDescription": "Whether a start that took a while finishing or failing, and a running service crashing, show a desktop notification while the terminal is not focused; defaults to `auto`. The TUI knows focus from the terminal; a command such as `devlanes start` does not, so with `auto` it notifies only in kitty, which itself skips a focused window. Terminals without notifications get the bell. At most one notification per 10 seconds. `DEVLANES_TERM_NOTIFICATIONS=0` or `1` overrides this setting."
|
|
743
|
+
},
|
|
677
744
|
"progress": {
|
|
678
745
|
"$ref": "#/$defs/TerminalProgress",
|
|
679
746
|
"default": "auto",
|
|
680
|
-
"description": "
|
|
747
|
+
"description": "Whether starts show their progress in the terminal tab's own progress bar (the OSC 9;4 sequence); defaults to `auto`. Only human output on a terminal gets it, and `DEVLANES_TERM_PROGRESS=0` or `1` overrides this setting.",
|
|
681
748
|
"examples": [
|
|
682
749
|
"auto",
|
|
683
750
|
"never"
|
|
684
|
-
]
|
|
751
|
+
],
|
|
752
|
+
"markdownDescription": "Whether starts show their progress in the terminal tab's own progress bar (the OSC 9;4 sequence); defaults to `auto`. Only human output on a terminal gets it, and `DEVLANES_TERM_PROGRESS=0` or `1` overrides this setting."
|
|
753
|
+
},
|
|
754
|
+
"title": {
|
|
755
|
+
"$ref": "#/$defs/TerminalFeature",
|
|
756
|
+
"default": "auto",
|
|
757
|
+
"description": "Whether the terminal tab's title says what devlanes is doing (`devlanes · acme@0 · starting 3/8` in the TUI, `devlanes start acme@0 · 3/8` or `devlanes logs -f api` for long commands); defaults to `auto`. The previous title is saved on the terminal's title stack and put back on exit, so `auto` sets it only where that stack exists: xterm, iTerm2, kitty, Ghostty and VTE terminals such as GNOME Terminal. Never inside tmux or screen, which manage titles themselves. `DEVLANES_TERM_TITLE=0` or `1` overrides this setting.",
|
|
758
|
+
"examples": [
|
|
759
|
+
"auto",
|
|
760
|
+
"never"
|
|
761
|
+
],
|
|
762
|
+
"markdownDescription": "Whether the terminal tab's title says what devlanes is doing (`devlanes · acme@0 · starting 3/8` in the TUI, `devlanes start acme@0 · 3/8` or `devlanes logs -f api` for long commands); defaults to `auto`. The previous title is saved on the terminal's title stack and put back on exit, so `auto` sets it only where that stack exists: xterm, iTerm2, kitty, Ghostty and VTE terminals such as GNOME Terminal. Never inside tmux or screen, which manage titles themselves. `DEVLANES_TERM_TITLE=0` or `1` overrides this setting."
|
|
685
763
|
}
|
|
686
764
|
},
|
|
687
765
|
"type": "object"
|
|
688
766
|
},
|
|
689
767
|
"TlsConfig": {
|
|
690
768
|
"additionalProperties": false,
|
|
691
|
-
"description": "Certificate authority
|
|
769
|
+
"description": "Certificate authority behind the proxy's HTTPS certificates, and the stores `devlanes certs trust` installs it into.",
|
|
692
770
|
"examples": [
|
|
693
771
|
{
|
|
694
772
|
"ca": "devlanes",
|
|
@@ -698,19 +776,21 @@
|
|
|
698
776
|
]
|
|
699
777
|
}
|
|
700
778
|
],
|
|
779
|
+
"markdownDescription": "Certificate authority behind the proxy's HTTPS certificates, and the stores `devlanes certs trust` installs it into.",
|
|
701
780
|
"properties": {
|
|
702
781
|
"ca": {
|
|
703
782
|
"$ref": "#/$defs/CaKind",
|
|
704
783
|
"default": "devlanes",
|
|
705
|
-
"description": "
|
|
784
|
+
"description": "Which CA signs the certificate for each lane hostname; defaults to `devlanes`. Choose `mkcert` when your browsers already trust mkcert's CA.",
|
|
706
785
|
"examples": [
|
|
707
786
|
"devlanes",
|
|
708
787
|
"mkcert"
|
|
709
|
-
]
|
|
788
|
+
],
|
|
789
|
+
"markdownDescription": "Which CA signs the certificate for each lane hostname; defaults to `devlanes`. Choose `mkcert` when your browsers already trust mkcert's CA."
|
|
710
790
|
},
|
|
711
791
|
"trust": {
|
|
712
792
|
"default": [],
|
|
713
|
-
"description": "
|
|
793
|
+
"description": "Stores `devlanes certs trust` installs the CA into and `certs untrust` removes it from; an empty list means `[system]`. On Linux, browsers do not read the system store, so add `chrome` and `firefox` there; `devlanes doctor` shows each store's state.",
|
|
714
794
|
"examples": [
|
|
715
795
|
[
|
|
716
796
|
"system",
|
|
@@ -722,22 +802,38 @@
|
|
|
722
802
|
],
|
|
723
803
|
"items": {
|
|
724
804
|
"$ref": "#/$defs/TrustTarget",
|
|
725
|
-
"description": "
|
|
805
|
+
"description": "Certificate store that `devlanes certs trust` installs the CA into.",
|
|
726
806
|
"examples": [
|
|
727
807
|
"system",
|
|
728
808
|
"firefox",
|
|
729
809
|
"chrome",
|
|
730
810
|
"ios-simulator",
|
|
731
811
|
"android-emulator"
|
|
732
|
-
]
|
|
812
|
+
],
|
|
813
|
+
"markdownDescription": "Certificate store that `devlanes certs trust` installs the CA into."
|
|
733
814
|
},
|
|
815
|
+
"markdownDescription": "Stores `devlanes certs trust` installs the CA into and `certs untrust` removes it from; an empty list means `[system]`. On Linux, browsers do not read the system store, so add `chrome` and `firefox` there; `devlanes doctor` shows each store's state.",
|
|
734
816
|
"type": "array"
|
|
735
817
|
}
|
|
736
818
|
},
|
|
737
819
|
"type": "object"
|
|
738
820
|
},
|
|
739
821
|
"TrustTarget": {
|
|
740
|
-
"description": "
|
|
822
|
+
"description": "Certificate store that `devlanes certs trust` installs the CA into.",
|
|
823
|
+
"enum": [
|
|
824
|
+
"system",
|
|
825
|
+
"firefox",
|
|
826
|
+
"chrome",
|
|
827
|
+
"ios-simulator",
|
|
828
|
+
"android-emulator"
|
|
829
|
+
],
|
|
830
|
+
"enumDescriptions": [
|
|
831
|
+
"The OS store: the login keychain on macOS, read by Safari, Chrome, Edge and `/usr/bin/curl`; on Linux, the distribution's CA anchors, updated through sudo.",
|
|
832
|
+
"Every Firefox profile's certificate database, through `certutil` from the NSS tools (`brew install nss`, or `libnss3-tools` / `nss-tools` on Linux).",
|
|
833
|
+
"The store Chrome and Chromium read: `~/.pki/nssdb` through `certutil` on Linux, the same login keychain as `system` on macOS.",
|
|
834
|
+
"Reserved for the iOS simulator; not supported yet, so it is dropped with a warning.",
|
|
835
|
+
"Reserved for the Android emulator; not supported yet, so it is dropped with a warning."
|
|
836
|
+
],
|
|
741
837
|
"examples": [
|
|
742
838
|
"system",
|
|
743
839
|
"firefox",
|
|
@@ -745,52 +841,19 @@
|
|
|
745
841
|
"ios-simulator",
|
|
746
842
|
"android-emulator"
|
|
747
843
|
],
|
|
748
|
-
"
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
{
|
|
758
|
-
"const": "firefox",
|
|
759
|
-
"description": "Trust the local CA in Firefox's certificate database.",
|
|
760
|
-
"examples": [
|
|
761
|
-
"firefox"
|
|
762
|
-
],
|
|
763
|
-
"type": "string"
|
|
764
|
-
},
|
|
765
|
-
{
|
|
766
|
-
"const": "chrome",
|
|
767
|
-
"description": "Trust the local CA in Chrome's certificate database where required.",
|
|
768
|
-
"examples": [
|
|
769
|
-
"chrome"
|
|
770
|
-
],
|
|
771
|
-
"type": "string"
|
|
772
|
-
},
|
|
773
|
-
{
|
|
774
|
-
"const": "ios-simulator",
|
|
775
|
-
"description": "Reserved iOS simulator trust target; not supported yet, so it is ignored with a warning.",
|
|
776
|
-
"examples": [
|
|
777
|
-
"ios-simulator"
|
|
778
|
-
],
|
|
779
|
-
"type": "string"
|
|
780
|
-
},
|
|
781
|
-
{
|
|
782
|
-
"const": "android-emulator",
|
|
783
|
-
"description": "Reserved Android emulator trust target; not supported yet, so it is ignored with a warning.",
|
|
784
|
-
"examples": [
|
|
785
|
-
"android-emulator"
|
|
786
|
-
],
|
|
787
|
-
"type": "string"
|
|
788
|
-
}
|
|
789
|
-
]
|
|
844
|
+
"markdownDescription": "Certificate store that `devlanes certs trust` installs the CA into.",
|
|
845
|
+
"markdownEnumDescriptions": [
|
|
846
|
+
"The OS store: the login keychain on macOS, read by Safari, Chrome, Edge and `/usr/bin/curl`; on Linux, the distribution's CA anchors, updated through sudo.",
|
|
847
|
+
"Every Firefox profile's certificate database, through `certutil` from the NSS tools (`brew install nss`, or `libnss3-tools` / `nss-tools` on Linux).",
|
|
848
|
+
"The store Chrome and Chromium read: `~/.pki/nssdb` through `certutil` on Linux, the same login keychain as `system` on macOS.",
|
|
849
|
+
"Reserved for the iOS simulator; not supported yet, so it is dropped with a warning.",
|
|
850
|
+
"Reserved for the Android emulator; not supported yet, so it is dropped with a warning."
|
|
851
|
+
],
|
|
852
|
+
"type": "string"
|
|
790
853
|
},
|
|
791
854
|
"TuiConfig": {
|
|
792
855
|
"additionalProperties": false,
|
|
793
|
-
"description": "Terminal UI
|
|
856
|
+
"description": "Terminal UI settings: when it opens, its colors and symbols, and what quitting does with running lanes. Changes apply to the next command.",
|
|
794
857
|
"examples": [
|
|
795
858
|
{
|
|
796
859
|
"open_on_start": false
|
|
@@ -803,187 +866,188 @@
|
|
|
803
866
|
"on_quit": "keep"
|
|
804
867
|
}
|
|
805
868
|
],
|
|
869
|
+
"markdownDescription": "Terminal UI settings: when it opens, its colors and symbols, and what quitting does with running lanes. Changes apply to the next command.",
|
|
806
870
|
"properties": {
|
|
807
871
|
"glyphs": {
|
|
808
872
|
"$ref": "#/$defs/TuiGlyphs",
|
|
809
873
|
"default": "auto",
|
|
810
|
-
"description": "
|
|
874
|
+
"description": "Characters the TUI draws states, markers and the spinner with; defaults to `auto`. Set `ascii` when your font shows boxes or misaligned symbols.",
|
|
811
875
|
"examples": [
|
|
812
876
|
"auto",
|
|
813
877
|
"unicode",
|
|
814
878
|
"ascii"
|
|
815
|
-
]
|
|
879
|
+
],
|
|
880
|
+
"markdownDescription": "Characters the TUI draws states, markers and the spinner with; defaults to `auto`. Set `ascii` when your font shows boxes or misaligned symbols."
|
|
816
881
|
},
|
|
817
882
|
"on_quit": {
|
|
818
883
|
"$ref": "#/$defs/TuiOnQuit",
|
|
819
884
|
"default": "ask",
|
|
820
|
-
"description": "What
|
|
885
|
+
"description": "What `q` or Ctrl+C does while lanes of the project on screen are running; defaults to `ask`. Ticking \"remember\" in the quit dialog writes the choice here.",
|
|
821
886
|
"examples": [
|
|
822
887
|
"ask",
|
|
823
888
|
"keep",
|
|
824
889
|
"stop"
|
|
825
|
-
]
|
|
890
|
+
],
|
|
891
|
+
"markdownDescription": "What `q` or Ctrl+C does while lanes of the project on screen are running; defaults to `ask`. Ticking \"remember\" in the quit dialog writes the choice here."
|
|
826
892
|
},
|
|
827
893
|
"open_on_start": {
|
|
828
894
|
"default": true,
|
|
829
|
-
"description": "
|
|
895
|
+
"description": "Open the TUI for `start`, `restart`, `lane resume` and `lane new --start` when they run at a terminal; defaults to true. Set false to have them print text instead, as `--no-ui` or `DEVLANES_NO_UI=1` do.",
|
|
830
896
|
"examples": [
|
|
831
897
|
true,
|
|
832
898
|
false
|
|
833
899
|
],
|
|
900
|
+
"markdownDescription": "Open the TUI for `start`, `restart`, `lane resume` and `lane new --start` when they run at a terminal; defaults to true. Set false to have them print text instead, as `--no-ui` or `DEVLANES_NO_UI=1` do.",
|
|
834
901
|
"type": "boolean"
|
|
835
902
|
},
|
|
836
903
|
"theme": {
|
|
837
904
|
"$ref": "#/$defs/TuiTheme",
|
|
838
905
|
"default": "auto",
|
|
839
|
-
"description": "
|
|
906
|
+
"description": "Color palette of the TUI; defaults to `auto`, which picks one from what the terminal reports. Choose `dark` or `light` when auto guesses wrong; `NO_COLOR` in the environment turns colors off whatever this says.",
|
|
840
907
|
"examples": [
|
|
841
908
|
"auto",
|
|
842
909
|
"dark",
|
|
843
910
|
"light",
|
|
844
911
|
"ansi"
|
|
845
|
-
]
|
|
912
|
+
],
|
|
913
|
+
"markdownDescription": "Color palette of the TUI; defaults to `auto`, which picks one from what the terminal reports. Choose `dark` or `light` when auto guesses wrong; `NO_COLOR` in the environment turns colors off whatever this says."
|
|
846
914
|
}
|
|
847
915
|
},
|
|
848
916
|
"type": "object"
|
|
849
917
|
},
|
|
850
918
|
"TuiGlyphs": {
|
|
851
|
-
"description": "
|
|
919
|
+
"description": "Character set the TUI draws its symbols with.",
|
|
920
|
+
"enum": [
|
|
921
|
+
"auto",
|
|
922
|
+
"unicode",
|
|
923
|
+
"ascii"
|
|
924
|
+
],
|
|
925
|
+
"enumDescriptions": [
|
|
926
|
+
"Unicode, or ASCII when the locale (the first of `LC_ALL`, `LC_CTYPE` and `LANG` that is set) is not UTF-8.",
|
|
927
|
+
"Always Unicode symbols, such as ● ✕ ▾ and a braille spinner.",
|
|
928
|
+
"Plain ASCII only, for fonts or terminals that draw Unicode symbols badly."
|
|
929
|
+
],
|
|
852
930
|
"examples": [
|
|
853
931
|
"auto",
|
|
854
932
|
"unicode",
|
|
855
933
|
"ascii"
|
|
856
934
|
],
|
|
857
|
-
"
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
"type": "string"
|
|
865
|
-
},
|
|
866
|
-
{
|
|
867
|
-
"const": "unicode",
|
|
868
|
-
"description": "Unicode symbols such as ● ✕ ▾.",
|
|
869
|
-
"examples": [
|
|
870
|
-
"unicode"
|
|
871
|
-
],
|
|
872
|
-
"type": "string"
|
|
873
|
-
},
|
|
874
|
-
{
|
|
875
|
-
"const": "ascii",
|
|
876
|
-
"description": "Plain ASCII, for fonts or terminals that draw Unicode symbols badly.",
|
|
877
|
-
"examples": [
|
|
878
|
-
"ascii"
|
|
879
|
-
],
|
|
880
|
-
"type": "string"
|
|
881
|
-
}
|
|
882
|
-
]
|
|
935
|
+
"markdownDescription": "Character set the TUI draws its symbols with.",
|
|
936
|
+
"markdownEnumDescriptions": [
|
|
937
|
+
"Unicode, or ASCII when the locale (the first of `LC_ALL`, `LC_CTYPE` and `LANG` that is set) is not UTF-8.",
|
|
938
|
+
"Always Unicode symbols, such as ● ✕ ▾ and a braille spinner.",
|
|
939
|
+
"Plain ASCII only, for fonts or terminals that draw Unicode symbols badly."
|
|
940
|
+
],
|
|
941
|
+
"type": "string"
|
|
883
942
|
},
|
|
884
943
|
"TuiOnQuit": {
|
|
885
|
-
"description": "What quitting the TUI does with running lanes.",
|
|
944
|
+
"description": "What quitting the TUI does with the running lanes of the project on screen.",
|
|
945
|
+
"enum": [
|
|
946
|
+
"ask",
|
|
947
|
+
"keep",
|
|
948
|
+
"stop"
|
|
949
|
+
],
|
|
950
|
+
"enumDescriptions": [
|
|
951
|
+
"Show a dialog each time to choose between keeping the lanes running and stopping them.",
|
|
952
|
+
"Close the TUI at once; every lane keeps running in the daemon.",
|
|
953
|
+
"Stop the running lanes of the project on screen, then close the TUI. Lanes of other projects keep running."
|
|
954
|
+
],
|
|
886
955
|
"examples": [
|
|
887
956
|
"ask",
|
|
888
957
|
"keep",
|
|
889
958
|
"stop"
|
|
890
959
|
],
|
|
891
|
-
"
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
"type": "string"
|
|
899
|
-
},
|
|
900
|
-
{
|
|
901
|
-
"const": "keep",
|
|
902
|
-
"description": "Close the TUI and leave every lane running in the daemon.",
|
|
903
|
-
"examples": [
|
|
904
|
-
"keep"
|
|
905
|
-
],
|
|
906
|
-
"type": "string"
|
|
907
|
-
},
|
|
908
|
-
{
|
|
909
|
-
"const": "stop",
|
|
910
|
-
"description": "Stop the running lanes of the project on screen, then close the TUI.",
|
|
911
|
-
"examples": [
|
|
912
|
-
"stop"
|
|
913
|
-
],
|
|
914
|
-
"type": "string"
|
|
915
|
-
}
|
|
916
|
-
]
|
|
960
|
+
"markdownDescription": "What quitting the TUI does with the running lanes of the project on screen.",
|
|
961
|
+
"markdownEnumDescriptions": [
|
|
962
|
+
"Show a dialog each time to choose between keeping the lanes running and stopping them.",
|
|
963
|
+
"Close the TUI at once; every lane keeps running in the daemon.",
|
|
964
|
+
"Stop the running lanes of the project on screen, then close the TUI. Lanes of other projects keep running."
|
|
965
|
+
],
|
|
966
|
+
"type": "string"
|
|
917
967
|
},
|
|
918
968
|
"TuiTheme": {
|
|
919
|
-
"description": "
|
|
969
|
+
"description": "Color palette of the TUI.",
|
|
970
|
+
"enum": [
|
|
971
|
+
"auto",
|
|
972
|
+
"dark",
|
|
973
|
+
"light",
|
|
974
|
+
"ansi"
|
|
975
|
+
],
|
|
976
|
+
"enumDescriptions": [
|
|
977
|
+
"Use the true-color dark or light palette when the terminal reports true color (`COLORTERM`) and its background (`COLORFGBG`); otherwise the terminal's 16 colors.",
|
|
978
|
+
"Always use the true-color palette made for a dark background.",
|
|
979
|
+
"Always use the true-color palette made for a light background.",
|
|
980
|
+
"Use only the terminal's 16 named colors, so the TUI follows the terminal's color scheme."
|
|
981
|
+
],
|
|
920
982
|
"examples": [
|
|
921
983
|
"auto",
|
|
922
984
|
"dark",
|
|
923
985
|
"light",
|
|
924
986
|
"ansi"
|
|
925
987
|
],
|
|
926
|
-
"
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
},
|
|
935
|
-
{
|
|
936
|
-
"const": "dark",
|
|
937
|
-
"description": "The true-color palette for a dark background.",
|
|
938
|
-
"examples": [
|
|
939
|
-
"dark"
|
|
940
|
-
],
|
|
941
|
-
"type": "string"
|
|
942
|
-
},
|
|
943
|
-
{
|
|
944
|
-
"const": "light",
|
|
945
|
-
"description": "The true-color palette for a light background.",
|
|
946
|
-
"examples": [
|
|
947
|
-
"light"
|
|
948
|
-
],
|
|
949
|
-
"type": "string"
|
|
950
|
-
},
|
|
951
|
-
{
|
|
952
|
-
"const": "ansi",
|
|
953
|
-
"description": "The terminal's own 16 colors, which follow its theme.",
|
|
954
|
-
"examples": [
|
|
955
|
-
"ansi"
|
|
956
|
-
],
|
|
957
|
-
"type": "string"
|
|
958
|
-
}
|
|
959
|
-
]
|
|
988
|
+
"markdownDescription": "Color palette of the TUI.",
|
|
989
|
+
"markdownEnumDescriptions": [
|
|
990
|
+
"Use the true-color dark or light palette when the terminal reports true color (`COLORTERM`) and its background (`COLORFGBG`); otherwise the terminal's 16 colors.",
|
|
991
|
+
"Always use the true-color palette made for a dark background.",
|
|
992
|
+
"Always use the true-color palette made for a light background.",
|
|
993
|
+
"Use only the terminal's 16 named colors, so the TUI follows the terminal's color scheme."
|
|
994
|
+
],
|
|
995
|
+
"type": "string"
|
|
960
996
|
},
|
|
961
997
|
"UpdatesConfig": {
|
|
962
998
|
"additionalProperties": false,
|
|
963
|
-
"description": "Release checks: the daemon reads the latest release's version once a day and
|
|
999
|
+
"description": "Release checks: the daemon reads the latest release's version once a day and commands print a one-line notice. Nothing is downloaded or installed.",
|
|
964
1000
|
"examples": [
|
|
965
1001
|
{
|
|
966
1002
|
"check": false
|
|
967
1003
|
}
|
|
968
1004
|
],
|
|
1005
|
+
"markdownDescription": "Release checks: the daemon reads the latest release's version once a day and commands print a one-line notice. Nothing is downloaded or installed.",
|
|
969
1006
|
"properties": {
|
|
970
1007
|
"check": {
|
|
971
1008
|
"default": true,
|
|
972
|
-
"description": "
|
|
1009
|
+
"description": "Have the daemon read the latest release's version from GitHub once a day; when it is newer, commands print the upgrade command on one line, at most once a day. Defaults to true; `DEVLANES_NO_UPDATE_CHECK=1` or a CI environment also turns it off.",
|
|
973
1010
|
"examples": [
|
|
974
1011
|
true,
|
|
975
1012
|
false
|
|
976
1013
|
],
|
|
1014
|
+
"markdownDescription": "Have the daemon read the latest release's version from GitHub once a day; when it is newer, commands print the upgrade command on one line, at most once a day. Defaults to true; `DEVLANES_NO_UPDATE_CHECK=1` or a CI environment also turns it off.",
|
|
977
1015
|
"type": "boolean"
|
|
978
1016
|
}
|
|
979
1017
|
},
|
|
980
1018
|
"type": "object"
|
|
1019
|
+
},
|
|
1020
|
+
"UserLanesConfig": {
|
|
1021
|
+
"additionalProperties": false,
|
|
1022
|
+
"description": "Machine settings for lanes. Each lane gets its own data folder at `<data_dir>/<project>/<lane id>`, available as `${{ lane.data_path }}` and `DEVLANES_LANE_DATA`. devlanes creates it when the lane is created and before each start, and `devlanes lane clean` deletes it.",
|
|
1023
|
+
"examples": [
|
|
1024
|
+
{
|
|
1025
|
+
"data_dir": "~/.devlanes/data"
|
|
1026
|
+
}
|
|
1027
|
+
],
|
|
1028
|
+
"markdownDescription": "Machine settings for lanes. Each lane gets its own data folder at `<data_dir>/<project>/<lane id>`, available as `${{ lane.data_path }}` and `DEVLANES_LANE_DATA`. devlanes creates it when the lane is created and before each start, and `devlanes lane clean` deletes it.",
|
|
1029
|
+
"properties": {
|
|
1030
|
+
"data_dir": {
|
|
1031
|
+
"default": null,
|
|
1032
|
+
"description": "Folder that holds every lane's data folder, one subfolder per project; defaults to `data` in the devlanes home (`~/.devlanes/data`). Must be an absolute path or start with `~/`. The daemon reads it when it starts. After a change and a daemon restart, lanes use new, empty folders under the new root; move the old folders there by hand to keep their data.",
|
|
1033
|
+
"examples": [
|
|
1034
|
+
"~/.devlanes/data",
|
|
1035
|
+
"/Volumes/fast/devlanes"
|
|
1036
|
+
],
|
|
1037
|
+
"markdownDescription": "Folder that holds every lane's data folder, one subfolder per project; defaults to `data` in the devlanes home (`~/.devlanes/data`). Must be an absolute path or start with `~/`. The daemon reads it when it starts. After a change and a daemon restart, lanes use new, empty folders under the new root; move the old folders there by hand to keep their data.",
|
|
1038
|
+
"type": [
|
|
1039
|
+
"string",
|
|
1040
|
+
"null"
|
|
1041
|
+
]
|
|
1042
|
+
}
|
|
1043
|
+
},
|
|
1044
|
+
"type": "object"
|
|
981
1045
|
}
|
|
982
1046
|
},
|
|
983
1047
|
"$id": "https://devlanes.run/v1/user-schema.json",
|
|
984
1048
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
985
1049
|
"additionalProperties": false,
|
|
986
|
-
"description": "
|
|
1050
|
+
"description": "devlanes v0.3.0 user config: per-user settings in ~/.devlanes/config.yaml. Run a dev environment per git worktree, side by side. https://devlanes.run",
|
|
987
1051
|
"examples": [
|
|
988
1052
|
{
|
|
989
1053
|
"hostnames": {
|
|
@@ -997,6 +1061,7 @@
|
|
|
997
1061
|
}
|
|
998
1062
|
}
|
|
999
1063
|
],
|
|
1064
|
+
"markdownDescription": "devlanes v0.3.0 user config: per-user settings in ~/.devlanes/config.yaml. Run a dev environment per git worktree, side by side. https://devlanes.run",
|
|
1000
1065
|
"properties": {
|
|
1001
1066
|
"history": {
|
|
1002
1067
|
"$ref": "#/$defs/HistoryConfig",
|
|
@@ -1004,13 +1069,14 @@
|
|
|
1004
1069
|
"remote_hosts_retention": "7776000000ms",
|
|
1005
1070
|
"retention": "604800000ms"
|
|
1006
1071
|
},
|
|
1007
|
-
"description": "
|
|
1072
|
+
"description": "How long the database keeps records of finished service and task runs, and of remote boxes that no longer connect.",
|
|
1008
1073
|
"examples": [
|
|
1009
1074
|
{
|
|
1010
1075
|
"remote_hosts_retention": "90d",
|
|
1011
1076
|
"retention": "7d"
|
|
1012
1077
|
}
|
|
1013
|
-
]
|
|
1078
|
+
],
|
|
1079
|
+
"markdownDescription": "How long the database keeps records of finished service and task runs, and of remote boxes that no longer connect."
|
|
1014
1080
|
},
|
|
1015
1081
|
"hostnames": {
|
|
1016
1082
|
"$ref": "#/$defs/HostnamesConfig",
|
|
@@ -1021,7 +1087,7 @@
|
|
|
1021
1087
|
"resolver": "localhost",
|
|
1022
1088
|
"tld": null
|
|
1023
1089
|
},
|
|
1024
|
-
"description": "
|
|
1090
|
+
"description": "How lane hostnames such as `api.acme-2.localhost` resolve to this machine: the strategy (`resolver`), its `tld`, and whether names also go into `/etc/hosts` (`hosts_file`). The defaults need no setup for browsers that resolve `*.localhost`.",
|
|
1025
1091
|
"examples": [
|
|
1026
1092
|
{
|
|
1027
1093
|
"hosts_file": "auto",
|
|
@@ -1031,7 +1097,21 @@
|
|
|
1031
1097
|
"resolver": "resolver",
|
|
1032
1098
|
"tld": "test"
|
|
1033
1099
|
}
|
|
1034
|
-
]
|
|
1100
|
+
],
|
|
1101
|
+
"markdownDescription": "How lane hostnames such as `api.acme-2.localhost` resolve to this machine: the strategy (`resolver`), its `tld`, and whether names also go into `/etc/hosts` (`hosts_file`). The defaults need no setup for browsers that resolve `*.localhost`."
|
|
1102
|
+
},
|
|
1103
|
+
"lanes": {
|
|
1104
|
+
"$ref": "#/$defs/UserLanesConfig",
|
|
1105
|
+
"default": {
|
|
1106
|
+
"data_dir": null
|
|
1107
|
+
},
|
|
1108
|
+
"description": "Where lane data folders (`lane.data_path`) live on this machine.",
|
|
1109
|
+
"examples": [
|
|
1110
|
+
{
|
|
1111
|
+
"data_dir": "~/.devlanes/data"
|
|
1112
|
+
}
|
|
1113
|
+
],
|
|
1114
|
+
"markdownDescription": "Where lane data folders (`lane.data_path`) live on this machine."
|
|
1035
1115
|
},
|
|
1036
1116
|
"logs": {
|
|
1037
1117
|
"$ref": "#/$defs/LogsConfig",
|
|
@@ -1041,7 +1121,7 @@
|
|
|
1041
1121
|
"max_size": "5368709120B"
|
|
1042
1122
|
}
|
|
1043
1123
|
},
|
|
1044
|
-
"description": "
|
|
1124
|
+
"description": "How much service output devlanes keeps under `~/.devlanes/logs`, by age and total size.",
|
|
1045
1125
|
"examples": [
|
|
1046
1126
|
{
|
|
1047
1127
|
"retention": {
|
|
@@ -1049,31 +1129,34 @@
|
|
|
1049
1129
|
"max_size": "5GiB"
|
|
1050
1130
|
}
|
|
1051
1131
|
}
|
|
1052
|
-
]
|
|
1132
|
+
],
|
|
1133
|
+
"markdownDescription": "How much service output devlanes keeps under `~/.devlanes/logs`, by age and total size."
|
|
1053
1134
|
},
|
|
1054
1135
|
"metrics": {
|
|
1055
1136
|
"$ref": "#/$defs/MetricsConfig",
|
|
1056
1137
|
"default": {
|
|
1057
1138
|
"retention": "604800000ms"
|
|
1058
1139
|
},
|
|
1059
|
-
"description": "
|
|
1140
|
+
"description": "How long CPU and memory history stays in the daemon's database.",
|
|
1060
1141
|
"examples": [
|
|
1061
1142
|
{
|
|
1062
1143
|
"retention": "7d"
|
|
1063
1144
|
}
|
|
1064
|
-
]
|
|
1145
|
+
],
|
|
1146
|
+
"markdownDescription": "How long CPU and memory history stays in the daemon's database."
|
|
1065
1147
|
},
|
|
1066
1148
|
"ports": {
|
|
1067
1149
|
"$ref": "#/$defs/PortsConfig",
|
|
1068
1150
|
"default": {
|
|
1069
1151
|
"range": "20000-32767"
|
|
1070
1152
|
},
|
|
1071
|
-
"description": "
|
|
1153
|
+
"description": "Port range that every lane of every project takes its block of ports from, so lanes never collide. Defaults to `20000-32767`.",
|
|
1072
1154
|
"examples": [
|
|
1073
1155
|
{
|
|
1074
1156
|
"range": "20000-32767"
|
|
1075
1157
|
}
|
|
1076
|
-
]
|
|
1158
|
+
],
|
|
1159
|
+
"markdownDescription": "Port range that every lane of every project takes its block of ports from, so lanes never collide. Defaults to `20000-32767`."
|
|
1077
1160
|
},
|
|
1078
1161
|
"proxy": {
|
|
1079
1162
|
"$ref": "#/$defs/ProxyConfig",
|
|
@@ -1082,26 +1165,28 @@
|
|
|
1082
1165
|
"https_port": 443,
|
|
1083
1166
|
"lan": false
|
|
1084
1167
|
},
|
|
1085
|
-
"description": "HTTP/HTTPS
|
|
1168
|
+
"description": "Ports of the daemon's HTTP/HTTPS proxy, which serves every `hosts` entry, and whether other devices on the network may connect to it.",
|
|
1086
1169
|
"examples": [
|
|
1087
1170
|
{
|
|
1088
1171
|
"http_port": 80,
|
|
1089
1172
|
"https_port": 443,
|
|
1090
1173
|
"lan": false
|
|
1091
1174
|
}
|
|
1092
|
-
]
|
|
1175
|
+
],
|
|
1176
|
+
"markdownDescription": "Ports of the daemon's HTTP/HTTPS proxy, which serves every `hosts` entry, and whether other devices on the network may connect to it."
|
|
1093
1177
|
},
|
|
1094
1178
|
"startup": {
|
|
1095
1179
|
"$ref": "#/$defs/StartupConfig",
|
|
1096
1180
|
"default": {
|
|
1097
1181
|
"initial": null,
|
|
1098
1182
|
"max": null,
|
|
1099
|
-
"mode": "
|
|
1183
|
+
"mode": "adaptive",
|
|
1184
|
+
"reserve_memory": null,
|
|
1100
1185
|
"settle_cpu": "10%",
|
|
1101
1186
|
"slot_timeout": "20000ms",
|
|
1102
1187
|
"target_cpu": "75%"
|
|
1103
1188
|
},
|
|
1104
|
-
"description": "How many services
|
|
1189
|
+
"description": "How many services may be starting at the same time across all lanes and projects, so a large start does not overload the machine. Defaults to one start per CPU core.",
|
|
1105
1190
|
"examples": [
|
|
1106
1191
|
{
|
|
1107
1192
|
"max": 4,
|
|
@@ -1111,40 +1196,47 @@
|
|
|
1111
1196
|
"initial": 2,
|
|
1112
1197
|
"max": 8,
|
|
1113
1198
|
"mode": "adaptive",
|
|
1199
|
+
"reserve_memory": "2GiB",
|
|
1114
1200
|
"settle_cpu": "10%",
|
|
1115
1201
|
"slot_timeout": "20s",
|
|
1116
1202
|
"target_cpu": "75%"
|
|
1117
1203
|
}
|
|
1118
|
-
]
|
|
1204
|
+
],
|
|
1205
|
+
"markdownDescription": "How many services may be starting at the same time across all lanes and projects, so a large start does not overload the machine. Defaults to one start per CPU core."
|
|
1119
1206
|
},
|
|
1120
1207
|
"state": {
|
|
1121
1208
|
"$ref": "#/$defs/StateConfig",
|
|
1122
1209
|
"default": {
|
|
1123
1210
|
"max_size": "536870912B"
|
|
1124
1211
|
},
|
|
1125
|
-
"description": "
|
|
1212
|
+
"description": "Size budget for the daemon's database; past it, the oldest metrics and history are deleted before their retention ends.",
|
|
1126
1213
|
"examples": [
|
|
1127
1214
|
{
|
|
1128
1215
|
"max_size": "512MiB"
|
|
1129
1216
|
}
|
|
1130
|
-
]
|
|
1217
|
+
],
|
|
1218
|
+
"markdownDescription": "Size budget for the daemon's database; past it, the oldest metrics and history are deleted before their retention ends."
|
|
1131
1219
|
},
|
|
1132
1220
|
"terminal": {
|
|
1133
1221
|
"anyOf": [
|
|
1134
1222
|
{
|
|
1135
|
-
"$ref": "#/$defs/TerminalConfig"
|
|
1223
|
+
"$ref": "#/$defs/TerminalConfig",
|
|
1224
|
+
"description": "",
|
|
1225
|
+
"examples": [],
|
|
1226
|
+
"markdownDescription": ""
|
|
1136
1227
|
},
|
|
1137
1228
|
{
|
|
1138
1229
|
"type": "null"
|
|
1139
1230
|
}
|
|
1140
1231
|
],
|
|
1141
1232
|
"default": null,
|
|
1142
|
-
"description": "
|
|
1233
|
+
"description": "Terminal integration of the CLI, written as a mapping with `progress` (the tab's progress bar during starts). A plain string, the terminal app name older versions used, is still accepted but ignored with a warning.",
|
|
1143
1234
|
"examples": [
|
|
1144
1235
|
{
|
|
1145
1236
|
"progress": "auto"
|
|
1146
1237
|
}
|
|
1147
|
-
]
|
|
1238
|
+
],
|
|
1239
|
+
"markdownDescription": "Terminal integration of the CLI, written as a mapping with `progress` (the tab's progress bar during starts). A plain string, the terminal app name older versions used, is still accepted but ignored with a warning."
|
|
1148
1240
|
},
|
|
1149
1241
|
"tls": {
|
|
1150
1242
|
"$ref": "#/$defs/TlsConfig",
|
|
@@ -1152,7 +1244,7 @@
|
|
|
1152
1244
|
"ca": "devlanes",
|
|
1153
1245
|
"trust": []
|
|
1154
1246
|
},
|
|
1155
|
-
"description": "
|
|
1247
|
+
"description": "Which certificate authority signs the proxy's HTTPS certificates (`ca`), and which stores `devlanes certs trust` installs it into (`trust`).",
|
|
1156
1248
|
"examples": [
|
|
1157
1249
|
{
|
|
1158
1250
|
"ca": "devlanes",
|
|
@@ -1161,7 +1253,8 @@
|
|
|
1161
1253
|
"firefox"
|
|
1162
1254
|
]
|
|
1163
1255
|
}
|
|
1164
|
-
]
|
|
1256
|
+
],
|
|
1257
|
+
"markdownDescription": "Which certificate authority signs the proxy's HTTPS certificates (`ca`), and which stores `devlanes certs trust` installs it into (`trust`)."
|
|
1165
1258
|
},
|
|
1166
1259
|
"tui": {
|
|
1167
1260
|
"$ref": "#/$defs/TuiConfig",
|
|
@@ -1171,7 +1264,7 @@
|
|
|
1171
1264
|
"open_on_start": true,
|
|
1172
1265
|
"theme": "auto"
|
|
1173
1266
|
},
|
|
1174
|
-
"description": "
|
|
1267
|
+
"description": "Whether start commands open the terminal UI, how it looks, and what quitting it does with running lanes.",
|
|
1175
1268
|
"examples": [
|
|
1176
1269
|
{
|
|
1177
1270
|
"open_on_start": false
|
|
@@ -1183,21 +1276,22 @@
|
|
|
1183
1276
|
{
|
|
1184
1277
|
"on_quit": "keep"
|
|
1185
1278
|
}
|
|
1186
|
-
]
|
|
1279
|
+
],
|
|
1280
|
+
"markdownDescription": "Whether start commands open the terminal UI, how it looks, and what quitting it does with running lanes."
|
|
1187
1281
|
},
|
|
1188
1282
|
"updates": {
|
|
1189
1283
|
"$ref": "#/$defs/UpdatesConfig",
|
|
1190
1284
|
"default": {
|
|
1191
1285
|
"check": true
|
|
1192
1286
|
},
|
|
1193
|
-
"description": "
|
|
1287
|
+
"description": "Daily check for a newer devlanes release; nothing is downloaded or installed.",
|
|
1194
1288
|
"examples": [
|
|
1195
1289
|
{
|
|
1196
1290
|
"check": false
|
|
1197
1291
|
}
|
|
1198
|
-
]
|
|
1292
|
+
],
|
|
1293
|
+
"markdownDescription": "Daily check for a newer devlanes release; nothing is downloaded or installed."
|
|
1199
1294
|
}
|
|
1200
1295
|
},
|
|
1201
|
-
"title": "devlanes user config",
|
|
1202
1296
|
"type": "object"
|
|
1203
1297
|
}
|