devlanes 0.1.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 +4 -2
- package/bin/{devlanes.js → devlanes} +3 -1
- package/install.js +75 -0
- package/package.json +10 -6
- package/schema.json +1033 -879
- package/user-schema.json +555 -373
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
|
-
"retention": "
|
|
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
|
-
"default": "
|
|
116
|
-
"description": "
|
|
119
|
+
"default": "604800000ms",
|
|
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
|
-
"
|
|
119
|
-
"
|
|
120
|
-
]
|
|
122
|
+
"7d",
|
|
123
|
+
"30d"
|
|
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,33 +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
|
-
"retention": "
|
|
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
|
-
"default": "
|
|
317
|
-
"description": "
|
|
330
|
+
"default": "604800000ms",
|
|
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": [
|
|
333
|
+
"7d",
|
|
319
334
|
"30d"
|
|
320
|
-
]
|
|
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."
|
|
321
337
|
}
|
|
322
338
|
},
|
|
323
339
|
"type": "object"
|
|
@@ -328,24 +344,27 @@
|
|
|
328
344
|
"75%",
|
|
329
345
|
"12.5%"
|
|
330
346
|
],
|
|
347
|
+
"markdownDescription": "A percentage with a `%` suffix, such as `75%` or `12.5%`.",
|
|
331
348
|
"pattern": "^\\s*([0-9]+\\.?[0-9]*|\\.[0-9]+)\\s*%\\s*$",
|
|
332
349
|
"type": "string"
|
|
333
350
|
},
|
|
334
351
|
"PortsConfig": {
|
|
335
352
|
"additionalProperties": false,
|
|
336
|
-
"description": "Machine-wide
|
|
353
|
+
"description": "Machine-wide pool every lane's block of ports comes from.",
|
|
337
354
|
"examples": [
|
|
338
355
|
{
|
|
339
356
|
"range": "20000-32767"
|
|
340
357
|
}
|
|
341
358
|
],
|
|
359
|
+
"markdownDescription": "Machine-wide pool every lane's block of ports comes from.",
|
|
342
360
|
"properties": {
|
|
343
361
|
"range": {
|
|
344
362
|
"default": "20000-32767",
|
|
345
|
-
"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.",
|
|
346
364
|
"examples": [
|
|
347
365
|
"20000-32767"
|
|
348
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.",
|
|
349
368
|
"pattern": "^[0-9]+-[0-9]+$",
|
|
350
369
|
"type": "string"
|
|
351
370
|
}
|
|
@@ -354,7 +373,7 @@
|
|
|
354
373
|
},
|
|
355
374
|
"ProxyConfig": {
|
|
356
375
|
"additionalProperties": false,
|
|
357
|
-
"description": "Ports and network
|
|
376
|
+
"description": "Ports and network exposure of the daemon's proxy, which routes each lane hostname to its service.",
|
|
358
377
|
"examples": [
|
|
359
378
|
{
|
|
360
379
|
"http_port": 80,
|
|
@@ -362,89 +381,79 @@
|
|
|
362
381
|
"lan": false
|
|
363
382
|
}
|
|
364
383
|
],
|
|
384
|
+
"markdownDescription": "Ports and network exposure of the daemon's proxy, which routes each lane hostname to its service.",
|
|
365
385
|
"properties": {
|
|
366
386
|
"http_port": {
|
|
367
387
|
"default": 80,
|
|
368
|
-
"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.",
|
|
369
389
|
"examples": [
|
|
370
390
|
80,
|
|
371
391
|
8080
|
|
372
392
|
],
|
|
373
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.",
|
|
374
395
|
"maximum": 65535,
|
|
375
396
|
"minimum": 0,
|
|
376
397
|
"type": "integer"
|
|
377
398
|
},
|
|
378
399
|
"https_port": {
|
|
379
400
|
"default": 443,
|
|
380
|
-
"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.",
|
|
381
402
|
"examples": [
|
|
382
403
|
443,
|
|
383
404
|
8443
|
|
384
405
|
],
|
|
385
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.",
|
|
386
408
|
"maximum": 65535,
|
|
387
409
|
"minimum": 0,
|
|
388
410
|
"type": "integer"
|
|
389
411
|
},
|
|
390
412
|
"lan": {
|
|
391
413
|
"default": false,
|
|
392
|
-
"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.",
|
|
393
415
|
"examples": [
|
|
394
416
|
false,
|
|
395
417
|
true
|
|
396
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.",
|
|
397
420
|
"type": "boolean"
|
|
398
421
|
}
|
|
399
422
|
},
|
|
400
423
|
"type": "object"
|
|
401
424
|
},
|
|
402
425
|
"Resolver": {
|
|
403
|
-
"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
|
+
],
|
|
404
439
|
"examples": [
|
|
405
440
|
"localhost",
|
|
406
441
|
"hosts_file",
|
|
407
442
|
"resolver",
|
|
408
443
|
"public"
|
|
409
444
|
],
|
|
410
|
-
"
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
},
|
|
419
|
-
{
|
|
420
|
-
"const": "hosts_file",
|
|
421
|
-
"description": "Resolve exact project names through system hosts-file entries.",
|
|
422
|
-
"examples": [
|
|
423
|
-
"hosts_file"
|
|
424
|
-
],
|
|
425
|
-
"type": "string"
|
|
426
|
-
},
|
|
427
|
-
{
|
|
428
|
-
"const": "resolver",
|
|
429
|
-
"description": "Use the daemon's DNS resolver for the configured custom top-level domain.",
|
|
430
|
-
"examples": [
|
|
431
|
-
"resolver"
|
|
432
|
-
],
|
|
433
|
-
"type": "string"
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
"const": "public",
|
|
437
|
-
"description": "Reserved public DNS and DNS-01 strategy; not supported yet.",
|
|
438
|
-
"examples": [
|
|
439
|
-
"public"
|
|
440
|
-
],
|
|
441
|
-
"type": "string"
|
|
442
|
-
}
|
|
443
|
-
]
|
|
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"
|
|
444
453
|
},
|
|
445
454
|
"StartupConfig": {
|
|
446
455
|
"additionalProperties": false,
|
|
447
|
-
"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.",
|
|
448
457
|
"examples": [
|
|
449
458
|
{
|
|
450
459
|
"max": 4,
|
|
@@ -454,19 +463,22 @@
|
|
|
454
463
|
"initial": 2,
|
|
455
464
|
"max": 8,
|
|
456
465
|
"mode": "adaptive",
|
|
466
|
+
"reserve_memory": "2GiB",
|
|
457
467
|
"settle_cpu": "10%",
|
|
458
468
|
"slot_timeout": "20s",
|
|
459
469
|
"target_cpu": "75%"
|
|
460
470
|
}
|
|
461
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.",
|
|
462
473
|
"properties": {
|
|
463
474
|
"initial": {
|
|
464
475
|
"default": null,
|
|
465
|
-
"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`.",
|
|
466
477
|
"examples": [
|
|
467
478
|
2
|
|
468
479
|
],
|
|
469
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`.",
|
|
470
482
|
"minimum": 1,
|
|
471
483
|
"type": [
|
|
472
484
|
"integer",
|
|
@@ -475,11 +487,12 @@
|
|
|
475
487
|
},
|
|
476
488
|
"max": {
|
|
477
489
|
"default": null,
|
|
478
|
-
"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.",
|
|
479
491
|
"examples": [
|
|
480
492
|
8
|
|
481
493
|
],
|
|
482
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.",
|
|
483
496
|
"minimum": 1,
|
|
484
497
|
"type": [
|
|
485
498
|
"integer",
|
|
@@ -488,95 +501,112 @@
|
|
|
488
501
|
},
|
|
489
502
|
"mode": {
|
|
490
503
|
"$ref": "#/$defs/StartupMode",
|
|
491
|
-
"default": "
|
|
492
|
-
"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`).",
|
|
493
506
|
"examples": [
|
|
494
507
|
"adaptive",
|
|
495
508
|
"fixed",
|
|
496
509
|
"all"
|
|
497
|
-
]
|
|
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."
|
|
498
532
|
},
|
|
499
533
|
"settle_cpu": {
|
|
500
534
|
"$ref": "#/$defs/Percent",
|
|
501
535
|
"default": "10%",
|
|
502
|
-
"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%`.",
|
|
503
537
|
"examples": [
|
|
504
538
|
"10%",
|
|
505
539
|
"12.5%"
|
|
506
|
-
]
|
|
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%`."
|
|
507
542
|
},
|
|
508
543
|
"slot_timeout": {
|
|
509
544
|
"$ref": "#/$defs/ConfigDuration",
|
|
510
545
|
"default": "20000ms",
|
|
511
|
-
"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.",
|
|
512
547
|
"examples": [
|
|
513
548
|
"15s",
|
|
514
549
|
"10m"
|
|
515
|
-
]
|
|
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."
|
|
516
552
|
},
|
|
517
553
|
"target_cpu": {
|
|
518
554
|
"$ref": "#/$defs/Percent",
|
|
519
555
|
"default": "75%",
|
|
520
|
-
"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.",
|
|
521
557
|
"examples": [
|
|
522
558
|
"75%",
|
|
523
559
|
"80%"
|
|
524
|
-
]
|
|
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."
|
|
525
562
|
}
|
|
526
563
|
},
|
|
527
564
|
"type": "object"
|
|
528
565
|
},
|
|
529
566
|
"StartupMode": {
|
|
530
|
-
"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
|
+
],
|
|
531
578
|
"examples": [
|
|
532
579
|
"adaptive",
|
|
533
580
|
"fixed",
|
|
534
581
|
"all"
|
|
535
582
|
],
|
|
536
|
-
"
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
"type": "string"
|
|
544
|
-
},
|
|
545
|
-
{
|
|
546
|
-
"const": "fixed",
|
|
547
|
-
"description": "Always `max` starts at a time.",
|
|
548
|
-
"examples": [
|
|
549
|
-
"fixed"
|
|
550
|
-
],
|
|
551
|
-
"type": "string"
|
|
552
|
-
},
|
|
553
|
-
{
|
|
554
|
-
"const": "all",
|
|
555
|
-
"description": "No pacing: every service starts at once.",
|
|
556
|
-
"examples": [
|
|
557
|
-
"all"
|
|
558
|
-
],
|
|
559
|
-
"type": "string"
|
|
560
|
-
}
|
|
561
|
-
]
|
|
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"
|
|
562
590
|
},
|
|
563
591
|
"StateConfig": {
|
|
564
592
|
"additionalProperties": false,
|
|
565
|
-
"description": "
|
|
593
|
+
"description": "Size budget for the daemon's SQLite database, enforced by its hourly cleanup.",
|
|
566
594
|
"examples": [
|
|
567
595
|
{
|
|
568
596
|
"max_size": "512MiB"
|
|
569
597
|
}
|
|
570
598
|
],
|
|
599
|
+
"markdownDescription": "Size budget for the daemon's SQLite database, enforced by its hourly cleanup.",
|
|
571
600
|
"properties": {
|
|
572
601
|
"max_size": {
|
|
573
602
|
"$ref": "#/$defs/ByteSize",
|
|
574
603
|
"default": "536870912B",
|
|
575
|
-
"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.",
|
|
576
605
|
"examples": [
|
|
577
606
|
"512MiB",
|
|
578
607
|
"1GiB"
|
|
579
|
-
]
|
|
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."
|
|
580
610
|
}
|
|
581
611
|
},
|
|
582
612
|
"type": "object"
|
|
@@ -584,182 +614,159 @@
|
|
|
584
614
|
"Templated_string": {
|
|
585
615
|
"anyOf": [
|
|
586
616
|
{
|
|
587
|
-
"description": "Literal value used without expression evaluation.",
|
|
588
617
|
"type": "string"
|
|
589
618
|
},
|
|
590
619
|
{
|
|
591
|
-
"description": "Text containing `${{ ... }}`, evaluated for each lane; write `${{ '${{' }}` for a literal `${{`.",
|
|
592
|
-
"examples": [
|
|
593
|
-
"${{ lane.index }}"
|
|
594
|
-
],
|
|
595
620
|
"pattern": "\\$\\{\\{",
|
|
596
621
|
"type": "string"
|
|
597
622
|
}
|
|
598
623
|
],
|
|
599
|
-
"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 `${{`.",
|
|
600
625
|
"examples": [
|
|
601
626
|
"${{ lane.index }}"
|
|
602
|
-
]
|
|
603
|
-
},
|
|
604
|
-
"Terminal": {
|
|
605
|
-
"description": "Terminal application used by open-in-terminal actions.",
|
|
606
|
-
"examples": [
|
|
607
|
-
"iterm2",
|
|
608
|
-
"ghostty",
|
|
609
|
-
"wezterm",
|
|
610
|
-
"kitty",
|
|
611
|
-
"terminal"
|
|
612
627
|
],
|
|
613
|
-
"
|
|
614
|
-
{
|
|
615
|
-
"const": "iterm2",
|
|
616
|
-
"description": "Open a session in iTerm2 on macOS.",
|
|
617
|
-
"examples": [
|
|
618
|
-
"iterm2"
|
|
619
|
-
],
|
|
620
|
-
"type": "string"
|
|
621
|
-
},
|
|
622
|
-
{
|
|
623
|
-
"const": "ghostty",
|
|
624
|
-
"description": "Open a session in Ghostty.",
|
|
625
|
-
"examples": [
|
|
626
|
-
"ghostty"
|
|
627
|
-
],
|
|
628
|
-
"type": "string"
|
|
629
|
-
},
|
|
630
|
-
{
|
|
631
|
-
"const": "wezterm",
|
|
632
|
-
"description": "Open a session in WezTerm.",
|
|
633
|
-
"examples": [
|
|
634
|
-
"wezterm"
|
|
635
|
-
],
|
|
636
|
-
"type": "string"
|
|
637
|
-
},
|
|
638
|
-
{
|
|
639
|
-
"const": "kitty",
|
|
640
|
-
"description": "Open a session in kitty.",
|
|
641
|
-
"examples": [
|
|
642
|
-
"kitty"
|
|
643
|
-
],
|
|
644
|
-
"type": "string"
|
|
645
|
-
},
|
|
646
|
-
{
|
|
647
|
-
"const": "terminal",
|
|
648
|
-
"description": "Open a session in macOS Terminal.app.",
|
|
649
|
-
"examples": [
|
|
650
|
-
"terminal"
|
|
651
|
-
],
|
|
652
|
-
"type": "string"
|
|
653
|
-
}
|
|
654
|
-
]
|
|
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 `${{`."
|
|
655
629
|
},
|
|
656
630
|
"TerminalConfig": {
|
|
657
631
|
"anyOf": [
|
|
658
632
|
{
|
|
659
|
-
"
|
|
660
|
-
"description": "Terminal app used by open-in-terminal actions; progress stays on auto.",
|
|
661
|
-
"examples": [
|
|
662
|
-
"ghostty"
|
|
663
|
-
]
|
|
633
|
+
"type": "string"
|
|
664
634
|
},
|
|
665
635
|
{
|
|
666
636
|
"$ref": "#/$defs/TerminalSettings",
|
|
667
|
-
"description": "
|
|
668
|
-
"examples": [
|
|
669
|
-
|
|
670
|
-
"app": "wezterm",
|
|
671
|
-
"progress": "never"
|
|
672
|
-
}
|
|
673
|
-
]
|
|
637
|
+
"description": "",
|
|
638
|
+
"examples": [],
|
|
639
|
+
"markdownDescription": ""
|
|
674
640
|
}
|
|
675
641
|
],
|
|
676
|
-
"description": "
|
|
642
|
+
"description": "Terminal integration of the CLI, or a terminal app name from older versions, which is ignored.",
|
|
677
643
|
"examples": [
|
|
678
|
-
"ghostty",
|
|
679
644
|
{
|
|
680
|
-
"app": "ghostty",
|
|
681
645
|
"progress": "auto"
|
|
682
646
|
}
|
|
683
|
-
]
|
|
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"
|
|
684
674
|
},
|
|
685
675
|
"TerminalProgress": {
|
|
686
|
-
"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
|
+
],
|
|
687
687
|
"examples": [
|
|
688
688
|
"auto",
|
|
689
689
|
"always",
|
|
690
690
|
"never"
|
|
691
691
|
],
|
|
692
|
-
"
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
"type": "string"
|
|
700
|
-
},
|
|
701
|
-
{
|
|
702
|
-
"const": "always",
|
|
703
|
-
"description": "In any terminal, also kitty 0.47 or later and inside tmux (needs `allow-passthrough on`).",
|
|
704
|
-
"examples": [
|
|
705
|
-
"always"
|
|
706
|
-
],
|
|
707
|
-
"type": "string"
|
|
708
|
-
},
|
|
709
|
-
{
|
|
710
|
-
"const": "never",
|
|
711
|
-
"description": "Never.",
|
|
712
|
-
"examples": [
|
|
713
|
-
"never"
|
|
714
|
-
],
|
|
715
|
-
"type": "string"
|
|
716
|
-
}
|
|
717
|
-
]
|
|
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"
|
|
718
699
|
},
|
|
719
700
|
"TerminalSettings": {
|
|
720
701
|
"additionalProperties": false,
|
|
721
|
-
"description": "
|
|
702
|
+
"description": "How devlanes uses the terminal: its progress bar, tab title, links, notifications and marks.",
|
|
722
703
|
"examples": [
|
|
723
704
|
{
|
|
724
|
-
"app": "ghostty",
|
|
725
705
|
"progress": "auto"
|
|
726
706
|
},
|
|
727
707
|
{
|
|
728
|
-
"progress": "never"
|
|
708
|
+
"progress": "never",
|
|
709
|
+
"title": "never"
|
|
729
710
|
}
|
|
730
711
|
],
|
|
712
|
+
"markdownDescription": "How devlanes uses the terminal: its progress bar, tab title, links, notifications and marks.",
|
|
731
713
|
"properties": {
|
|
732
|
-
"
|
|
733
|
-
"
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}
|
|
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"
|
|
740
721
|
],
|
|
741
|
-
"
|
|
742
|
-
|
|
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.",
|
|
743
728
|
"examples": [
|
|
744
|
-
"
|
|
745
|
-
"
|
|
746
|
-
]
|
|
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."
|
|
747
743
|
},
|
|
748
744
|
"progress": {
|
|
749
745
|
"$ref": "#/$defs/TerminalProgress",
|
|
750
746
|
"default": "auto",
|
|
751
|
-
"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.",
|
|
752
748
|
"examples": [
|
|
753
749
|
"auto",
|
|
754
750
|
"never"
|
|
755
|
-
]
|
|
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."
|
|
756
763
|
}
|
|
757
764
|
},
|
|
758
765
|
"type": "object"
|
|
759
766
|
},
|
|
760
767
|
"TlsConfig": {
|
|
761
768
|
"additionalProperties": false,
|
|
762
|
-
"description": "Certificate authority
|
|
769
|
+
"description": "Certificate authority behind the proxy's HTTPS certificates, and the stores `devlanes certs trust` installs it into.",
|
|
763
770
|
"examples": [
|
|
764
771
|
{
|
|
765
772
|
"ca": "devlanes",
|
|
@@ -769,19 +776,21 @@
|
|
|
769
776
|
]
|
|
770
777
|
}
|
|
771
778
|
],
|
|
779
|
+
"markdownDescription": "Certificate authority behind the proxy's HTTPS certificates, and the stores `devlanes certs trust` installs it into.",
|
|
772
780
|
"properties": {
|
|
773
781
|
"ca": {
|
|
774
782
|
"$ref": "#/$defs/CaKind",
|
|
775
783
|
"default": "devlanes",
|
|
776
|
-
"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.",
|
|
777
785
|
"examples": [
|
|
778
786
|
"devlanes",
|
|
779
787
|
"mkcert"
|
|
780
|
-
]
|
|
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."
|
|
781
790
|
},
|
|
782
791
|
"trust": {
|
|
783
792
|
"default": [],
|
|
784
|
-
"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.",
|
|
785
794
|
"examples": [
|
|
786
795
|
[
|
|
787
796
|
"system",
|
|
@@ -793,22 +802,38 @@
|
|
|
793
802
|
],
|
|
794
803
|
"items": {
|
|
795
804
|
"$ref": "#/$defs/TrustTarget",
|
|
796
|
-
"description": "
|
|
805
|
+
"description": "Certificate store that `devlanes certs trust` installs the CA into.",
|
|
797
806
|
"examples": [
|
|
798
807
|
"system",
|
|
799
808
|
"firefox",
|
|
800
809
|
"chrome",
|
|
801
810
|
"ios-simulator",
|
|
802
811
|
"android-emulator"
|
|
803
|
-
]
|
|
812
|
+
],
|
|
813
|
+
"markdownDescription": "Certificate store that `devlanes certs trust` installs the CA into."
|
|
804
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.",
|
|
805
816
|
"type": "array"
|
|
806
817
|
}
|
|
807
818
|
},
|
|
808
819
|
"type": "object"
|
|
809
820
|
},
|
|
810
821
|
"TrustTarget": {
|
|
811
|
-
"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
|
+
],
|
|
812
837
|
"examples": [
|
|
813
838
|
"system",
|
|
814
839
|
"firefox",
|
|
@@ -816,96 +841,213 @@
|
|
|
816
841
|
"ios-simulator",
|
|
817
842
|
"android-emulator"
|
|
818
843
|
],
|
|
819
|
-
"
|
|
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"
|
|
853
|
+
},
|
|
854
|
+
"TuiConfig": {
|
|
855
|
+
"additionalProperties": false,
|
|
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.",
|
|
857
|
+
"examples": [
|
|
820
858
|
{
|
|
821
|
-
"
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
"type": "string"
|
|
859
|
+
"open_on_start": false
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"glyphs": "ascii",
|
|
863
|
+
"theme": "light"
|
|
827
864
|
},
|
|
828
865
|
{
|
|
829
|
-
"
|
|
830
|
-
|
|
866
|
+
"on_quit": "keep"
|
|
867
|
+
}
|
|
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.",
|
|
870
|
+
"properties": {
|
|
871
|
+
"glyphs": {
|
|
872
|
+
"$ref": "#/$defs/TuiGlyphs",
|
|
873
|
+
"default": "auto",
|
|
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.",
|
|
831
875
|
"examples": [
|
|
832
|
-
"
|
|
876
|
+
"auto",
|
|
877
|
+
"unicode",
|
|
878
|
+
"ascii"
|
|
833
879
|
],
|
|
834
|
-
"
|
|
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."
|
|
835
881
|
},
|
|
836
|
-
{
|
|
837
|
-
"
|
|
838
|
-
"
|
|
882
|
+
"on_quit": {
|
|
883
|
+
"$ref": "#/$defs/TuiOnQuit",
|
|
884
|
+
"default": "ask",
|
|
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.",
|
|
839
886
|
"examples": [
|
|
840
|
-
"
|
|
887
|
+
"ask",
|
|
888
|
+
"keep",
|
|
889
|
+
"stop"
|
|
841
890
|
],
|
|
842
|
-
"
|
|
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."
|
|
843
892
|
},
|
|
844
|
-
{
|
|
845
|
-
"
|
|
846
|
-
"description": "
|
|
893
|
+
"open_on_start": {
|
|
894
|
+
"default": true,
|
|
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.",
|
|
847
896
|
"examples": [
|
|
848
|
-
|
|
897
|
+
true,
|
|
898
|
+
false
|
|
849
899
|
],
|
|
850
|
-
"
|
|
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.",
|
|
901
|
+
"type": "boolean"
|
|
851
902
|
},
|
|
852
|
-
{
|
|
853
|
-
"
|
|
854
|
-
"
|
|
903
|
+
"theme": {
|
|
904
|
+
"$ref": "#/$defs/TuiTheme",
|
|
905
|
+
"default": "auto",
|
|
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.",
|
|
855
907
|
"examples": [
|
|
856
|
-
"
|
|
908
|
+
"auto",
|
|
909
|
+
"dark",
|
|
910
|
+
"light",
|
|
911
|
+
"ansi"
|
|
857
912
|
],
|
|
858
|
-
"
|
|
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."
|
|
859
914
|
}
|
|
860
|
-
|
|
915
|
+
},
|
|
916
|
+
"type": "object"
|
|
861
917
|
},
|
|
862
|
-
"
|
|
918
|
+
"TuiGlyphs": {
|
|
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
|
+
],
|
|
930
|
+
"examples": [
|
|
931
|
+
"auto",
|
|
932
|
+
"unicode",
|
|
933
|
+
"ascii"
|
|
934
|
+
],
|
|
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"
|
|
942
|
+
},
|
|
943
|
+
"TuiOnQuit": {
|
|
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
|
+
],
|
|
955
|
+
"examples": [
|
|
956
|
+
"ask",
|
|
957
|
+
"keep",
|
|
958
|
+
"stop"
|
|
959
|
+
],
|
|
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"
|
|
967
|
+
},
|
|
968
|
+
"TuiTheme": {
|
|
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
|
+
],
|
|
982
|
+
"examples": [
|
|
983
|
+
"auto",
|
|
984
|
+
"dark",
|
|
985
|
+
"light",
|
|
986
|
+
"ansi"
|
|
987
|
+
],
|
|
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"
|
|
996
|
+
},
|
|
997
|
+
"UpdatesConfig": {
|
|
863
998
|
"additionalProperties": false,
|
|
864
|
-
"description": "
|
|
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.",
|
|
865
1000
|
"examples": [
|
|
866
1001
|
{
|
|
867
|
-
"
|
|
1002
|
+
"check": false
|
|
868
1003
|
}
|
|
869
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.",
|
|
870
1006
|
"properties": {
|
|
871
|
-
"
|
|
1007
|
+
"check": {
|
|
872
1008
|
"default": true,
|
|
873
|
-
"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.",
|
|
874
1010
|
"examples": [
|
|
875
1011
|
true,
|
|
876
1012
|
false
|
|
877
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.",
|
|
878
1015
|
"type": "boolean"
|
|
879
1016
|
}
|
|
880
1017
|
},
|
|
881
1018
|
"type": "object"
|
|
882
1019
|
},
|
|
883
|
-
"
|
|
1020
|
+
"UserLanesConfig": {
|
|
884
1021
|
"additionalProperties": false,
|
|
885
|
-
"description": "
|
|
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.",
|
|
886
1023
|
"examples": [
|
|
887
1024
|
{
|
|
888
|
-
"
|
|
1025
|
+
"data_dir": "~/.devlanes/data"
|
|
889
1026
|
}
|
|
890
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.",
|
|
891
1029
|
"properties": {
|
|
892
|
-
"
|
|
893
|
-
"default":
|
|
894
|
-
"description": "
|
|
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.",
|
|
895
1033
|
"examples": [
|
|
896
|
-
|
|
897
|
-
|
|
1034
|
+
"~/.devlanes/data",
|
|
1035
|
+
"/Volumes/fast/devlanes"
|
|
898
1036
|
],
|
|
899
|
-
"
|
|
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
|
+
]
|
|
900
1042
|
}
|
|
901
1043
|
},
|
|
902
1044
|
"type": "object"
|
|
903
1045
|
}
|
|
904
1046
|
},
|
|
905
|
-
"$id": "https://devlanes.run/
|
|
1047
|
+
"$id": "https://devlanes.run/v1/user-schema.json",
|
|
906
1048
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
907
1049
|
"additionalProperties": false,
|
|
908
|
-
"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",
|
|
909
1051
|
"examples": [
|
|
910
1052
|
{
|
|
911
1053
|
"hostnames": {
|
|
@@ -914,23 +1056,27 @@
|
|
|
914
1056
|
"ports": {
|
|
915
1057
|
"range": "20000-32767"
|
|
916
1058
|
},
|
|
917
|
-
"terminal":
|
|
1059
|
+
"terminal": {
|
|
1060
|
+
"progress": "auto"
|
|
1061
|
+
}
|
|
918
1062
|
}
|
|
919
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",
|
|
920
1065
|
"properties": {
|
|
921
1066
|
"history": {
|
|
922
1067
|
"$ref": "#/$defs/HistoryConfig",
|
|
923
1068
|
"default": {
|
|
924
1069
|
"remote_hosts_retention": "7776000000ms",
|
|
925
|
-
"retention": "
|
|
1070
|
+
"retention": "604800000ms"
|
|
926
1071
|
},
|
|
927
|
-
"description": "
|
|
1072
|
+
"description": "How long the database keeps records of finished service and task runs, and of remote boxes that no longer connect.",
|
|
928
1073
|
"examples": [
|
|
929
1074
|
{
|
|
930
1075
|
"remote_hosts_retention": "90d",
|
|
931
|
-
"retention": "
|
|
1076
|
+
"retention": "7d"
|
|
932
1077
|
}
|
|
933
|
-
]
|
|
1078
|
+
],
|
|
1079
|
+
"markdownDescription": "How long the database keeps records of finished service and task runs, and of remote boxes that no longer connect."
|
|
934
1080
|
},
|
|
935
1081
|
"hostnames": {
|
|
936
1082
|
"$ref": "#/$defs/HostnamesConfig",
|
|
@@ -941,7 +1087,7 @@
|
|
|
941
1087
|
"resolver": "localhost",
|
|
942
1088
|
"tld": null
|
|
943
1089
|
},
|
|
944
|
-
"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`.",
|
|
945
1091
|
"examples": [
|
|
946
1092
|
{
|
|
947
1093
|
"hosts_file": "auto",
|
|
@@ -951,7 +1097,21 @@
|
|
|
951
1097
|
"resolver": "resolver",
|
|
952
1098
|
"tld": "test"
|
|
953
1099
|
}
|
|
954
|
-
]
|
|
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."
|
|
955
1115
|
},
|
|
956
1116
|
"logs": {
|
|
957
1117
|
"$ref": "#/$defs/LogsConfig",
|
|
@@ -961,7 +1121,7 @@
|
|
|
961
1121
|
"max_size": "5368709120B"
|
|
962
1122
|
}
|
|
963
1123
|
},
|
|
964
|
-
"description": "
|
|
1124
|
+
"description": "How much service output devlanes keeps under `~/.devlanes/logs`, by age and total size.",
|
|
965
1125
|
"examples": [
|
|
966
1126
|
{
|
|
967
1127
|
"retention": {
|
|
@@ -969,31 +1129,34 @@
|
|
|
969
1129
|
"max_size": "5GiB"
|
|
970
1130
|
}
|
|
971
1131
|
}
|
|
972
|
-
]
|
|
1132
|
+
],
|
|
1133
|
+
"markdownDescription": "How much service output devlanes keeps under `~/.devlanes/logs`, by age and total size."
|
|
973
1134
|
},
|
|
974
1135
|
"metrics": {
|
|
975
1136
|
"$ref": "#/$defs/MetricsConfig",
|
|
976
1137
|
"default": {
|
|
977
|
-
"retention": "
|
|
1138
|
+
"retention": "604800000ms"
|
|
978
1139
|
},
|
|
979
|
-
"description": "
|
|
1140
|
+
"description": "How long CPU and memory history stays in the daemon's database.",
|
|
980
1141
|
"examples": [
|
|
981
1142
|
{
|
|
982
|
-
"retention": "
|
|
1143
|
+
"retention": "7d"
|
|
983
1144
|
}
|
|
984
|
-
]
|
|
1145
|
+
],
|
|
1146
|
+
"markdownDescription": "How long CPU and memory history stays in the daemon's database."
|
|
985
1147
|
},
|
|
986
1148
|
"ports": {
|
|
987
1149
|
"$ref": "#/$defs/PortsConfig",
|
|
988
1150
|
"default": {
|
|
989
1151
|
"range": "20000-32767"
|
|
990
1152
|
},
|
|
991
|
-
"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`.",
|
|
992
1154
|
"examples": [
|
|
993
1155
|
{
|
|
994
1156
|
"range": "20000-32767"
|
|
995
1157
|
}
|
|
996
|
-
]
|
|
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`."
|
|
997
1160
|
},
|
|
998
1161
|
"proxy": {
|
|
999
1162
|
"$ref": "#/$defs/ProxyConfig",
|
|
@@ -1002,26 +1165,28 @@
|
|
|
1002
1165
|
"https_port": 443,
|
|
1003
1166
|
"lan": false
|
|
1004
1167
|
},
|
|
1005
|
-
"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.",
|
|
1006
1169
|
"examples": [
|
|
1007
1170
|
{
|
|
1008
1171
|
"http_port": 80,
|
|
1009
1172
|
"https_port": 443,
|
|
1010
1173
|
"lan": false
|
|
1011
1174
|
}
|
|
1012
|
-
]
|
|
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."
|
|
1013
1177
|
},
|
|
1014
1178
|
"startup": {
|
|
1015
1179
|
"$ref": "#/$defs/StartupConfig",
|
|
1016
1180
|
"default": {
|
|
1017
1181
|
"initial": null,
|
|
1018
1182
|
"max": null,
|
|
1019
|
-
"mode": "
|
|
1183
|
+
"mode": "adaptive",
|
|
1184
|
+
"reserve_memory": null,
|
|
1020
1185
|
"settle_cpu": "10%",
|
|
1021
1186
|
"slot_timeout": "20000ms",
|
|
1022
1187
|
"target_cpu": "75%"
|
|
1023
1188
|
},
|
|
1024
|
-
"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.",
|
|
1025
1190
|
"examples": [
|
|
1026
1191
|
{
|
|
1027
1192
|
"max": 4,
|
|
@@ -1031,42 +1196,47 @@
|
|
|
1031
1196
|
"initial": 2,
|
|
1032
1197
|
"max": 8,
|
|
1033
1198
|
"mode": "adaptive",
|
|
1199
|
+
"reserve_memory": "2GiB",
|
|
1034
1200
|
"settle_cpu": "10%",
|
|
1035
1201
|
"slot_timeout": "20s",
|
|
1036
1202
|
"target_cpu": "75%"
|
|
1037
1203
|
}
|
|
1038
|
-
]
|
|
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."
|
|
1039
1206
|
},
|
|
1040
1207
|
"state": {
|
|
1041
1208
|
"$ref": "#/$defs/StateConfig",
|
|
1042
1209
|
"default": {
|
|
1043
1210
|
"max_size": "536870912B"
|
|
1044
1211
|
},
|
|
1045
|
-
"description": "
|
|
1212
|
+
"description": "Size budget for the daemon's database; past it, the oldest metrics and history are deleted before their retention ends.",
|
|
1046
1213
|
"examples": [
|
|
1047
1214
|
{
|
|
1048
1215
|
"max_size": "512MiB"
|
|
1049
1216
|
}
|
|
1050
|
-
]
|
|
1217
|
+
],
|
|
1218
|
+
"markdownDescription": "Size budget for the daemon's database; past it, the oldest metrics and history are deleted before their retention ends."
|
|
1051
1219
|
},
|
|
1052
1220
|
"terminal": {
|
|
1053
1221
|
"anyOf": [
|
|
1054
1222
|
{
|
|
1055
|
-
"$ref": "#/$defs/TerminalConfig"
|
|
1223
|
+
"$ref": "#/$defs/TerminalConfig",
|
|
1224
|
+
"description": "",
|
|
1225
|
+
"examples": [],
|
|
1226
|
+
"markdownDescription": ""
|
|
1056
1227
|
},
|
|
1057
1228
|
{
|
|
1058
1229
|
"type": "null"
|
|
1059
1230
|
}
|
|
1060
1231
|
],
|
|
1061
1232
|
"default": null,
|
|
1062
|
-
"description": "Terminal
|
|
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.",
|
|
1063
1234
|
"examples": [
|
|
1064
|
-
"ghostty",
|
|
1065
1235
|
{
|
|
1066
|
-
"app": "ghostty",
|
|
1067
1236
|
"progress": "auto"
|
|
1068
1237
|
}
|
|
1069
|
-
]
|
|
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."
|
|
1070
1240
|
},
|
|
1071
1241
|
"tls": {
|
|
1072
1242
|
"$ref": "#/$defs/TlsConfig",
|
|
@@ -1074,7 +1244,7 @@
|
|
|
1074
1244
|
"ca": "devlanes",
|
|
1075
1245
|
"trust": []
|
|
1076
1246
|
},
|
|
1077
|
-
"description": "
|
|
1247
|
+
"description": "Which certificate authority signs the proxy's HTTPS certificates (`ca`), and which stores `devlanes certs trust` installs it into (`trust`).",
|
|
1078
1248
|
"examples": [
|
|
1079
1249
|
{
|
|
1080
1250
|
"ca": "devlanes",
|
|
@@ -1083,33 +1253,45 @@
|
|
|
1083
1253
|
"firefox"
|
|
1084
1254
|
]
|
|
1085
1255
|
}
|
|
1086
|
-
]
|
|
1256
|
+
],
|
|
1257
|
+
"markdownDescription": "Which certificate authority signs the proxy's HTTPS certificates (`ca`), and which stores `devlanes certs trust` installs it into (`trust`)."
|
|
1087
1258
|
},
|
|
1088
1259
|
"tui": {
|
|
1089
1260
|
"$ref": "#/$defs/TuiConfig",
|
|
1090
1261
|
"default": {
|
|
1091
|
-
"
|
|
1262
|
+
"glyphs": "auto",
|
|
1263
|
+
"on_quit": "ask",
|
|
1264
|
+
"open_on_start": true,
|
|
1265
|
+
"theme": "auto"
|
|
1092
1266
|
},
|
|
1093
|
-
"description": "
|
|
1267
|
+
"description": "Whether start commands open the terminal UI, how it looks, and what quitting it does with running lanes.",
|
|
1094
1268
|
"examples": [
|
|
1095
1269
|
{
|
|
1096
1270
|
"open_on_start": false
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
"glyphs": "ascii",
|
|
1274
|
+
"theme": "light"
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
"on_quit": "keep"
|
|
1097
1278
|
}
|
|
1098
|
-
]
|
|
1279
|
+
],
|
|
1280
|
+
"markdownDescription": "Whether start commands open the terminal UI, how it looks, and what quitting it does with running lanes."
|
|
1099
1281
|
},
|
|
1100
1282
|
"updates": {
|
|
1101
1283
|
"$ref": "#/$defs/UpdatesConfig",
|
|
1102
1284
|
"default": {
|
|
1103
1285
|
"check": true
|
|
1104
1286
|
},
|
|
1105
|
-
"description": "
|
|
1287
|
+
"description": "Daily check for a newer devlanes release; nothing is downloaded or installed.",
|
|
1106
1288
|
"examples": [
|
|
1107
1289
|
{
|
|
1108
1290
|
"check": false
|
|
1109
1291
|
}
|
|
1110
|
-
]
|
|
1292
|
+
],
|
|
1293
|
+
"markdownDescription": "Daily check for a newer devlanes release; nothing is downloaded or installed."
|
|
1111
1294
|
}
|
|
1112
1295
|
},
|
|
1113
|
-
"title": "devlanes user config",
|
|
1114
1296
|
"type": "object"
|
|
1115
1297
|
}
|