ghostdock 0.0.13 → 0.0.15
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/dist/cli-reference.md +184 -6
- package/dist/cli.md +30 -2
- package/dist/index.js +1082 -193
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -718,9 +718,33 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
718
718
|
"files"
|
|
719
719
|
],
|
|
720
720
|
additionalProperties: false
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
type: "object",
|
|
724
|
+
properties: {
|
|
725
|
+
type: {
|
|
726
|
+
type: "string",
|
|
727
|
+
const: "compose"
|
|
728
|
+
},
|
|
729
|
+
reference: {
|
|
730
|
+
type: "string",
|
|
731
|
+
minLength: 1,
|
|
732
|
+
maxLength: 512,
|
|
733
|
+
pattern: "^oci:\\/\\/(?:[a-z0-9]+(?:[.-][a-z0-9]+)*(?::\\d{1,5})?\\/)?[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*(?::[A-Za-z0-9_][A-Za-z0-9_.-]{0,127})?(?:@sha256:[a-f0-9]{64})?$"
|
|
734
|
+
},
|
|
735
|
+
override: {
|
|
736
|
+
type: "string",
|
|
737
|
+
maxLength: 262144
|
|
738
|
+
}
|
|
739
|
+
},
|
|
740
|
+
required: [
|
|
741
|
+
"type",
|
|
742
|
+
"reference"
|
|
743
|
+
],
|
|
744
|
+
additionalProperties: false
|
|
721
745
|
}
|
|
722
746
|
],
|
|
723
|
-
description: 'What the sandbox boots from. Required. "image" boots an org catalog row by id ({ id } from images_list / images_get — images_add OCI bookmarks, images_add_dockerfile, and images_add_compose rows) or any OCI ref ({ ref }); "dockerfile" builds inline Dockerfile text only (ghostdock.* LABEL lines parsed for manifest; this tool has no build directory, so COPY/ADD of local files fails — use the CLI `ghostdock sandboxes build --kind dockerfile` with a directory or ZIP); "compose" boots Docker-in-Docker from the given inline files (must include docker-compose.yml/yaml or compose.yml/yaml; ghostdock.* service labels parsed for manifest). A Compose project that needs extra files is not accepted here — use `ghostdock sandboxes build --kind compose`. Image, dockerfile, and compose sources never appear in snapshots_list. Published static sites use sites_publish (CDN), not a snapshot.'
|
|
747
|
+
description: 'What the sandbox boots from. Required. "image" boots an org catalog row by id ({ id } from images_list / images_get — images_add OCI bookmarks, images_add_dockerfile, and images_add_compose rows) or any OCI ref ({ ref }); "dockerfile" builds inline Dockerfile text only (ghostdock.* LABEL lines parsed for manifest; this tool has no build directory, so COPY/ADD of local files fails — use the CLI `ghostdock sandboxes build --kind dockerfile` with a directory or ZIP); "compose" boots Docker-in-Docker from the given inline files (must include docker-compose.yml/yaml or compose.yml/yaml; ghostdock.* service labels parsed for manifest). A Compose project that needs extra files is not accepted here — use `ghostdock sandboxes build --kind compose`. "compose" also takes a published Compose project instead of files ({ reference: "oci://…", override? }): it runs through include:, the override merged into it. Image, dockerfile, and compose sources never appear in snapshots_list. Published static sites use sites_publish (CDN), not a snapshot.'
|
|
724
748
|
},
|
|
725
749
|
resources: {
|
|
726
750
|
type: "object",
|
|
@@ -4454,11 +4478,16 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4454
4478
|
"images",
|
|
4455
4479
|
"add-compose"
|
|
4456
4480
|
],
|
|
4457
|
-
description: "Add Compose
|
|
4481
|
+
description: "Add a Compose project to the organization’s image catalog. Give its files, or a reference: a Compose project published as an OCI artifact (oci://…), used through include: with an optional override. ghostdock.* service labels (of the files, or of the override) become its manifest. Fails if the name is taken.",
|
|
4458
4482
|
inputSchema: {
|
|
4459
4483
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4460
4484
|
type: "object",
|
|
4461
4485
|
properties: {
|
|
4486
|
+
organization: {
|
|
4487
|
+
type: "string",
|
|
4488
|
+
minLength: 1,
|
|
4489
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
4490
|
+
},
|
|
4462
4491
|
name: {
|
|
4463
4492
|
type: "string",
|
|
4464
4493
|
minLength: 1,
|
|
@@ -4466,6 +4495,7 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4466
4495
|
description: "Image name, unique in the organization."
|
|
4467
4496
|
},
|
|
4468
4497
|
files: {
|
|
4498
|
+
description: "Compose files by file name. Must include docker-compose.yml/yaml or compose.yml/yaml.",
|
|
4469
4499
|
type: "object",
|
|
4470
4500
|
propertyNames: {
|
|
4471
4501
|
type: "string"
|
|
@@ -4474,19 +4504,24 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4474
4504
|
type: "string",
|
|
4475
4505
|
minLength: 1,
|
|
4476
4506
|
maxLength: 512000
|
|
4477
|
-
}
|
|
4478
|
-
description: "Compose files by file name. Must include docker-compose.yml/yaml or compose.yml/yaml."
|
|
4507
|
+
}
|
|
4479
4508
|
},
|
|
4480
|
-
|
|
4509
|
+
reference: {
|
|
4510
|
+
description: "A published Compose project instead of files, e.g. oci://docker.io/ghostdockhq/vm-compose:ubuntu-26.04.",
|
|
4481
4511
|
type: "string",
|
|
4482
4512
|
minLength: 1,
|
|
4483
|
-
|
|
4513
|
+
maxLength: 512,
|
|
4514
|
+
pattern: "^oci:\\/\\/(?:[a-z0-9]+(?:[.-][a-z0-9]+)*(?::\\d{1,5})?\\/)?[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*(?::[A-Za-z0-9_][A-Za-z0-9_.-]{0,127})?(?:@sha256:[a-f0-9]{64})?$"
|
|
4515
|
+
},
|
|
4516
|
+
override: {
|
|
4517
|
+
description: "With reference: a Compose file merged into it (services, environment, labels).",
|
|
4518
|
+
type: "string",
|
|
4519
|
+
maxLength: 262144
|
|
4484
4520
|
}
|
|
4485
4521
|
},
|
|
4486
4522
|
required: [
|
|
4487
|
-
"
|
|
4488
|
-
"
|
|
4489
|
-
"organization"
|
|
4523
|
+
"organization",
|
|
4524
|
+
"name"
|
|
4490
4525
|
],
|
|
4491
4526
|
additionalProperties: false
|
|
4492
4527
|
},
|
|
@@ -4509,7 +4544,7 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4509
4544
|
cliArgs: [
|
|
4510
4545
|
"imageId"
|
|
4511
4546
|
],
|
|
4512
|
-
description: "Replace a catalog Compose image’s files and/or name. Re-parses its labels.",
|
|
4547
|
+
description: "Replace a catalog Compose image’s files, reference, override and/or name. Re-parses its labels.",
|
|
4513
4548
|
inputSchema: {
|
|
4514
4549
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
4515
4550
|
type: "object",
|
|
@@ -4536,6 +4571,25 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4536
4571
|
maxLength: 512000
|
|
4537
4572
|
}
|
|
4538
4573
|
},
|
|
4574
|
+
reference: {
|
|
4575
|
+
description: "A new reference (oci://…): the image becomes a Compose reference.",
|
|
4576
|
+
type: "string",
|
|
4577
|
+
minLength: 1,
|
|
4578
|
+
maxLength: 512,
|
|
4579
|
+
pattern: "^oci:\\/\\/(?:[a-z0-9]+(?:[.-][a-z0-9]+)*(?::\\d{1,5})?\\/)?[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*(?:\\/[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*)*(?::[A-Za-z0-9_][A-Za-z0-9_.-]{0,127})?(?:@sha256:[a-f0-9]{64})?$"
|
|
4580
|
+
},
|
|
4581
|
+
override: {
|
|
4582
|
+
description: "A reference’s new override; null removes it.",
|
|
4583
|
+
anyOf: [
|
|
4584
|
+
{
|
|
4585
|
+
type: "string",
|
|
4586
|
+
maxLength: 262144
|
|
4587
|
+
},
|
|
4588
|
+
{
|
|
4589
|
+
type: "null"
|
|
4590
|
+
}
|
|
4591
|
+
]
|
|
4592
|
+
},
|
|
4539
4593
|
name: {
|
|
4540
4594
|
description: "New image name. Omit to keep it.",
|
|
4541
4595
|
type: "string",
|
|
@@ -4625,6 +4679,13 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4625
4679
|
minLength: 1,
|
|
4626
4680
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
4627
4681
|
},
|
|
4682
|
+
container: {
|
|
4683
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
4684
|
+
type: "string",
|
|
4685
|
+
minLength: 1,
|
|
4686
|
+
maxLength: 255,
|
|
4687
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
4688
|
+
},
|
|
4628
4689
|
files: {
|
|
4629
4690
|
description: "Small inline files: { path, content } for utf8 text, or { path, contentBase64 } for binary.",
|
|
4630
4691
|
type: "array",
|
|
@@ -4701,6 +4762,13 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4701
4762
|
minLength: 1,
|
|
4702
4763
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
4703
4764
|
},
|
|
4765
|
+
container: {
|
|
4766
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
4767
|
+
type: "string",
|
|
4768
|
+
minLength: 1,
|
|
4769
|
+
maxLength: 255,
|
|
4770
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
4771
|
+
},
|
|
4704
4772
|
path: {
|
|
4705
4773
|
description: "Directory to list. Absolute or relative to /. Defaults to /workspace.",
|
|
4706
4774
|
type: "string",
|
|
@@ -4780,6 +4848,13 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
4780
4848
|
minLength: 1,
|
|
4781
4849
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
4782
4850
|
},
|
|
4851
|
+
container: {
|
|
4852
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
4853
|
+
type: "string",
|
|
4854
|
+
minLength: 1,
|
|
4855
|
+
maxLength: 255,
|
|
4856
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
4857
|
+
},
|
|
4783
4858
|
path: {
|
|
4784
4859
|
type: "string",
|
|
4785
4860
|
minLength: 1,
|
|
@@ -5922,6 +5997,13 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
5922
5997
|
type: "string",
|
|
5923
5998
|
minLength: 1,
|
|
5924
5999
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6000
|
+
},
|
|
6001
|
+
container: {
|
|
6002
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6003
|
+
type: "string",
|
|
6004
|
+
minLength: 1,
|
|
6005
|
+
maxLength: 255,
|
|
6006
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
5925
6007
|
}
|
|
5926
6008
|
},
|
|
5927
6009
|
required: [
|
|
@@ -5982,17 +6064,17 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
5982
6064
|
}
|
|
5983
6065
|
},
|
|
5984
6066
|
{
|
|
5985
|
-
id: "
|
|
5986
|
-
name: "
|
|
6067
|
+
id: "sandboxes_containers_list",
|
|
6068
|
+
name: "sandboxes_containers_list",
|
|
5987
6069
|
cli: [
|
|
5988
6070
|
"sandboxes",
|
|
5989
|
-
"
|
|
5990
|
-
"
|
|
6071
|
+
"containers",
|
|
6072
|
+
"list"
|
|
5991
6073
|
],
|
|
5992
6074
|
cliArgs: [
|
|
5993
6075
|
"sandboxId"
|
|
5994
6076
|
],
|
|
5995
|
-
description: "
|
|
6077
|
+
description: "List the containers of a sandbox, running or not. Each with state, health, restart policy, ports, Compose project and service, deletion protection, ghostdock.* labels, and which one is the default. A stopped sandbox lists none (it is not started for this).",
|
|
5996
6078
|
inputSchema: {
|
|
5997
6079
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
5998
6080
|
type: "object",
|
|
@@ -6006,31 +6088,11 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6006
6088
|
type: "string",
|
|
6007
6089
|
minLength: 1,
|
|
6008
6090
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6009
|
-
},
|
|
6010
|
-
command: {
|
|
6011
|
-
type: "string",
|
|
6012
|
-
minLength: 1,
|
|
6013
|
-
description: "Shell command to run. Never include secret values: commands are logged."
|
|
6014
|
-
},
|
|
6015
|
-
sessionId: {
|
|
6016
|
-
description: "Session from sandboxes_shells_create, to keep cwd and environment from earlier commands. Omit for a one-off session.",
|
|
6017
|
-
type: "string",
|
|
6018
|
-
minLength: 1
|
|
6019
|
-
},
|
|
6020
|
-
cwd: {
|
|
6021
|
-
description: "Directory to run the command in.",
|
|
6022
|
-
type: "string",
|
|
6023
|
-
minLength: 1
|
|
6024
|
-
},
|
|
6025
|
-
waitSeconds: {
|
|
6026
|
-
description: "Seconds to wait before returning handles to poll: 1 to 120, default 120.",
|
|
6027
|
-
type: "number"
|
|
6028
6091
|
}
|
|
6029
6092
|
},
|
|
6030
6093
|
required: [
|
|
6031
6094
|
"organization",
|
|
6032
|
-
"sandboxId"
|
|
6033
|
-
"command"
|
|
6095
|
+
"sandboxId"
|
|
6034
6096
|
],
|
|
6035
6097
|
additionalProperties: false
|
|
6036
6098
|
},
|
|
@@ -6044,17 +6106,16 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6044
6106
|
}
|
|
6045
6107
|
},
|
|
6046
6108
|
{
|
|
6047
|
-
id: "
|
|
6048
|
-
name: "
|
|
6109
|
+
id: "sandboxes_default_container",
|
|
6110
|
+
name: "sandboxes_default_container",
|
|
6049
6111
|
cli: [
|
|
6050
6112
|
"sandboxes",
|
|
6051
|
-
"
|
|
6052
|
-
"get"
|
|
6113
|
+
"default-container"
|
|
6053
6114
|
],
|
|
6054
6115
|
cliArgs: [
|
|
6055
|
-
"
|
|
6116
|
+
"sandboxId"
|
|
6056
6117
|
],
|
|
6057
|
-
description: "
|
|
6118
|
+
description: "Show, set or clear the sandbox’s default container. SSH, the terminal, files, commands and MCP land there when no container is named. Without container or clear it only shows the setting.",
|
|
6058
6119
|
inputSchema: {
|
|
6059
6120
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6060
6121
|
type: "object",
|
|
@@ -6069,22 +6130,21 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6069
6130
|
minLength: 1,
|
|
6070
6131
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6071
6132
|
},
|
|
6072
|
-
|
|
6133
|
+
container: {
|
|
6134
|
+
description: "Container to make the default, by name. The running sandbox must have it.",
|
|
6073
6135
|
type: "string",
|
|
6074
6136
|
minLength: 1,
|
|
6075
|
-
|
|
6137
|
+
maxLength: 255,
|
|
6138
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6076
6139
|
},
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
description: "Command id returned by sandboxes_commands_run."
|
|
6140
|
+
clear: {
|
|
6141
|
+
description: "Clear the default.",
|
|
6142
|
+
type: "boolean"
|
|
6081
6143
|
}
|
|
6082
6144
|
},
|
|
6083
6145
|
required: [
|
|
6084
6146
|
"organization",
|
|
6085
|
-
"sandboxId"
|
|
6086
|
-
"sessionId",
|
|
6087
|
-
"commandId"
|
|
6147
|
+
"sandboxId"
|
|
6088
6148
|
],
|
|
6089
6149
|
additionalProperties: false
|
|
6090
6150
|
},
|
|
@@ -6098,17 +6158,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6098
6158
|
}
|
|
6099
6159
|
},
|
|
6100
6160
|
{
|
|
6101
|
-
id: "
|
|
6102
|
-
name: "
|
|
6161
|
+
id: "sandboxes_containers_protection",
|
|
6162
|
+
name: "sandboxes_containers_protection",
|
|
6103
6163
|
cli: [
|
|
6104
6164
|
"sandboxes",
|
|
6105
|
-
"
|
|
6106
|
-
"
|
|
6165
|
+
"containers",
|
|
6166
|
+
"protection"
|
|
6107
6167
|
],
|
|
6108
6168
|
cliArgs: [
|
|
6109
|
-
"
|
|
6169
|
+
"sandboxId",
|
|
6170
|
+
"container"
|
|
6110
6171
|
],
|
|
6111
|
-
description: "
|
|
6172
|
+
description: "Switch a container’s deletion protection on or off. A protected container cannot be removed or recreated (docker rm, compose down) until its protection is off. Starts the sandbox when needed.",
|
|
6112
6173
|
inputSchema: {
|
|
6113
6174
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6114
6175
|
type: "object",
|
|
@@ -6123,28 +6184,23 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6123
6184
|
minLength: 1,
|
|
6124
6185
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6125
6186
|
},
|
|
6126
|
-
|
|
6127
|
-
type: "string",
|
|
6128
|
-
minLength: 1,
|
|
6129
|
-
description: "Session id returned by sandboxes_commands_run together with the commandId."
|
|
6130
|
-
},
|
|
6131
|
-
commandId: {
|
|
6187
|
+
container: {
|
|
6132
6188
|
type: "string",
|
|
6133
6189
|
minLength: 1,
|
|
6134
|
-
|
|
6190
|
+
maxLength: 255,
|
|
6191
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$",
|
|
6192
|
+
description: "Container, by name."
|
|
6135
6193
|
},
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
minimum: 0,
|
|
6140
|
-
maximum: 9007199254740991
|
|
6194
|
+
protected: {
|
|
6195
|
+
type: "boolean",
|
|
6196
|
+
description: "true: protect it; false: allow removing it."
|
|
6141
6197
|
}
|
|
6142
6198
|
},
|
|
6143
6199
|
required: [
|
|
6144
6200
|
"organization",
|
|
6145
6201
|
"sandboxId",
|
|
6146
|
-
"
|
|
6147
|
-
"
|
|
6202
|
+
"container",
|
|
6203
|
+
"protected"
|
|
6148
6204
|
],
|
|
6149
6205
|
additionalProperties: false
|
|
6150
6206
|
},
|
|
@@ -6158,17 +6214,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6158
6214
|
}
|
|
6159
6215
|
},
|
|
6160
6216
|
{
|
|
6161
|
-
id: "
|
|
6162
|
-
name: "
|
|
6217
|
+
id: "sandboxes_containers_start",
|
|
6218
|
+
name: "sandboxes_containers_start",
|
|
6163
6219
|
cli: [
|
|
6164
6220
|
"sandboxes",
|
|
6165
|
-
"
|
|
6166
|
-
"
|
|
6221
|
+
"containers",
|
|
6222
|
+
"start"
|
|
6167
6223
|
],
|
|
6168
6224
|
cliArgs: [
|
|
6169
|
-
"
|
|
6225
|
+
"sandboxId",
|
|
6226
|
+
"container"
|
|
6170
6227
|
],
|
|
6171
|
-
description: "
|
|
6228
|
+
description: "Start a stopped container, as docker start does. A running container stays as it is. Starts the sandbox when needed.",
|
|
6172
6229
|
inputSchema: {
|
|
6173
6230
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6174
6231
|
type: "object",
|
|
@@ -6183,22 +6240,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6183
6240
|
minLength: 1,
|
|
6184
6241
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6185
6242
|
},
|
|
6186
|
-
|
|
6187
|
-
type: "string",
|
|
6188
|
-
minLength: 1,
|
|
6189
|
-
description: "Session id returned by sandboxes_commands_run together with the commandId."
|
|
6190
|
-
},
|
|
6191
|
-
commandId: {
|
|
6243
|
+
container: {
|
|
6192
6244
|
type: "string",
|
|
6193
6245
|
minLength: 1,
|
|
6194
|
-
|
|
6246
|
+
maxLength: 255,
|
|
6247
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$",
|
|
6248
|
+
description: "Container, by name."
|
|
6195
6249
|
}
|
|
6196
6250
|
},
|
|
6197
6251
|
required: [
|
|
6198
6252
|
"organization",
|
|
6199
6253
|
"sandboxId",
|
|
6200
|
-
"
|
|
6201
|
-
"commandId"
|
|
6254
|
+
"container"
|
|
6202
6255
|
],
|
|
6203
6256
|
additionalProperties: false
|
|
6204
6257
|
},
|
|
@@ -6212,17 +6265,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6212
6265
|
}
|
|
6213
6266
|
},
|
|
6214
6267
|
{
|
|
6215
|
-
id: "
|
|
6216
|
-
name: "
|
|
6268
|
+
id: "sandboxes_containers_stop",
|
|
6269
|
+
name: "sandboxes_containers_stop",
|
|
6217
6270
|
cli: [
|
|
6218
6271
|
"sandboxes",
|
|
6219
|
-
"
|
|
6220
|
-
"
|
|
6272
|
+
"containers",
|
|
6273
|
+
"stop"
|
|
6221
6274
|
],
|
|
6222
6275
|
cliArgs: [
|
|
6223
|
-
"sandboxId"
|
|
6276
|
+
"sandboxId",
|
|
6277
|
+
"container"
|
|
6224
6278
|
],
|
|
6225
|
-
description: "
|
|
6279
|
+
description: "Stop a container, as docker stop does. It gets its own stop signal, then a kill after its own stop timeout. It stays stopped while the sandbox sleeps and wakes, as Docker keeps a stopped container stopped, unless its restart policy is always. On a stopped sandbox it does nothing (note sandbox_stopped). The container main runs the sandbox: its stop is refused (main_is_the_sandbox), pause the sandbox instead. Deletion protection does not block it. note says when it was the default container or the last one running: then SSH, commands and files have nowhere to land until one runs.",
|
|
6226
6280
|
inputSchema: {
|
|
6227
6281
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6228
6282
|
type: "object",
|
|
@@ -6237,15 +6291,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6237
6291
|
minLength: 1,
|
|
6238
6292
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6239
6293
|
},
|
|
6240
|
-
|
|
6241
|
-
description: "Id for the new session: a slug; user-cmd, image-cmd and compose are reserved. Omit to generate one.",
|
|
6294
|
+
container: {
|
|
6242
6295
|
type: "string",
|
|
6243
|
-
minLength: 1
|
|
6296
|
+
minLength: 1,
|
|
6297
|
+
maxLength: 255,
|
|
6298
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$",
|
|
6299
|
+
description: "Container, by name."
|
|
6244
6300
|
}
|
|
6245
6301
|
},
|
|
6246
6302
|
required: [
|
|
6247
6303
|
"organization",
|
|
6248
|
-
"sandboxId"
|
|
6304
|
+
"sandboxId",
|
|
6305
|
+
"container"
|
|
6249
6306
|
],
|
|
6250
6307
|
additionalProperties: false
|
|
6251
6308
|
},
|
|
@@ -6259,17 +6316,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6259
6316
|
}
|
|
6260
6317
|
},
|
|
6261
6318
|
{
|
|
6262
|
-
id: "
|
|
6263
|
-
name: "
|
|
6319
|
+
id: "sandboxes_containers_restart",
|
|
6320
|
+
name: "sandboxes_containers_restart",
|
|
6264
6321
|
cli: [
|
|
6265
6322
|
"sandboxes",
|
|
6266
|
-
"
|
|
6267
|
-
"
|
|
6323
|
+
"containers",
|
|
6324
|
+
"restart"
|
|
6268
6325
|
],
|
|
6269
6326
|
cliArgs: [
|
|
6270
|
-
"
|
|
6327
|
+
"sandboxId",
|
|
6328
|
+
"container"
|
|
6271
6329
|
],
|
|
6272
|
-
description: "
|
|
6330
|
+
description: "Restart a container, as docker restart does (stopping as docker stop does). Starts the sandbox when needed.",
|
|
6273
6331
|
inputSchema: {
|
|
6274
6332
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6275
6333
|
type: "object",
|
|
@@ -6284,16 +6342,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6284
6342
|
minLength: 1,
|
|
6285
6343
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6286
6344
|
},
|
|
6287
|
-
|
|
6345
|
+
container: {
|
|
6288
6346
|
type: "string",
|
|
6289
6347
|
minLength: 1,
|
|
6290
|
-
|
|
6348
|
+
maxLength: 255,
|
|
6349
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$",
|
|
6350
|
+
description: "Container, by name."
|
|
6291
6351
|
}
|
|
6292
6352
|
},
|
|
6293
6353
|
required: [
|
|
6294
6354
|
"organization",
|
|
6295
6355
|
"sandboxId",
|
|
6296
|
-
"
|
|
6356
|
+
"container"
|
|
6297
6357
|
],
|
|
6298
6358
|
additionalProperties: false
|
|
6299
6359
|
},
|
|
@@ -6307,16 +6367,18 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6307
6367
|
}
|
|
6308
6368
|
},
|
|
6309
6369
|
{
|
|
6310
|
-
id: "
|
|
6311
|
-
name: "
|
|
6370
|
+
id: "sandboxes_containers_logs",
|
|
6371
|
+
name: "sandboxes_containers_logs",
|
|
6312
6372
|
cli: [
|
|
6313
6373
|
"sandboxes",
|
|
6314
|
-
"
|
|
6374
|
+
"containers",
|
|
6375
|
+
"logs"
|
|
6315
6376
|
],
|
|
6316
6377
|
cliArgs: [
|
|
6317
|
-
"sandboxId"
|
|
6378
|
+
"sandboxId",
|
|
6379
|
+
"container"
|
|
6318
6380
|
],
|
|
6319
|
-
description: "
|
|
6381
|
+
description: "Read a container’s output, as docker logs does. Oldest first, each line with its stream (stdout, stderr) and time. The last tail lines (default 200), or with after only the lines after that time: pass the last line’s time to follow. truncated says lines were left out. A stopped sandbox has none (it is not started for this).",
|
|
6320
6382
|
inputSchema: {
|
|
6321
6383
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6322
6384
|
type: "object",
|
|
@@ -6331,25 +6393,29 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6331
6393
|
minLength: 1,
|
|
6332
6394
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6333
6395
|
},
|
|
6334
|
-
|
|
6396
|
+
container: {
|
|
6335
6397
|
type: "string",
|
|
6336
6398
|
minLength: 1,
|
|
6337
|
-
|
|
6399
|
+
maxLength: 255,
|
|
6400
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$",
|
|
6401
|
+
description: "Container, by name."
|
|
6338
6402
|
},
|
|
6339
|
-
|
|
6340
|
-
description: "
|
|
6341
|
-
type: "
|
|
6342
|
-
|
|
6403
|
+
tail: {
|
|
6404
|
+
description: "The last N lines (at most 5000).",
|
|
6405
|
+
type: "integer",
|
|
6406
|
+
minimum: 1,
|
|
6407
|
+
maximum: 5000
|
|
6343
6408
|
},
|
|
6344
|
-
|
|
6345
|
-
description: "
|
|
6346
|
-
type: "
|
|
6409
|
+
after: {
|
|
6410
|
+
description: "Only lines after this time: the time of the last line already read.",
|
|
6411
|
+
type: "string",
|
|
6412
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$"
|
|
6347
6413
|
}
|
|
6348
6414
|
},
|
|
6349
6415
|
required: [
|
|
6350
6416
|
"organization",
|
|
6351
6417
|
"sandboxId",
|
|
6352
|
-
"
|
|
6418
|
+
"container"
|
|
6353
6419
|
],
|
|
6354
6420
|
additionalProperties: false
|
|
6355
6421
|
},
|
|
@@ -6363,16 +6429,17 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6363
6429
|
}
|
|
6364
6430
|
},
|
|
6365
6431
|
{
|
|
6366
|
-
id: "
|
|
6367
|
-
name: "
|
|
6432
|
+
id: "sandboxes_storage_list",
|
|
6433
|
+
name: "sandboxes_storage_list",
|
|
6368
6434
|
cli: [
|
|
6369
6435
|
"sandboxes",
|
|
6370
|
-
"
|
|
6436
|
+
"storage",
|
|
6437
|
+
"list"
|
|
6371
6438
|
],
|
|
6372
6439
|
cliArgs: [
|
|
6373
6440
|
"sandboxId"
|
|
6374
6441
|
],
|
|
6375
|
-
description: "
|
|
6442
|
+
description: "List a sandbox’s volumes and sandbox folders. The sandbox folders are where bind mounts land. Each with its size and sizeState (measured; measuring: ask again in a few seconds; tooBig: too big to measure cheaply; outside: a volume bound outside the sandbox folders, not measured nor browsable) and the containers using it, plus every container’s mounts. truncated says entries were left out. A stopped sandbox lists none (it is not started for this).",
|
|
6376
6443
|
inputSchema: {
|
|
6377
6444
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6378
6445
|
type: "object",
|
|
@@ -6386,39 +6453,6 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6386
6453
|
type: "string",
|
|
6387
6454
|
minLength: 1,
|
|
6388
6455
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6389
|
-
},
|
|
6390
|
-
displayName: {
|
|
6391
|
-
description: "New display name. Null clears it; omit to keep it.",
|
|
6392
|
-
anyOf: [
|
|
6393
|
-
{
|
|
6394
|
-
type: "string"
|
|
6395
|
-
},
|
|
6396
|
-
{
|
|
6397
|
-
type: "null"
|
|
6398
|
-
}
|
|
6399
|
-
]
|
|
6400
|
-
},
|
|
6401
|
-
autoStopIntervalMinutes: {
|
|
6402
|
-
description: "Minutes of inactivity before the platform worker idle-stops the sandbox. -1 always on. 0 is rejected. Null resets to the platform default. Provider-native timers are optional backup.",
|
|
6403
|
-
anyOf: [
|
|
6404
|
-
{
|
|
6405
|
-
type: "number"
|
|
6406
|
-
},
|
|
6407
|
-
{
|
|
6408
|
-
type: "null"
|
|
6409
|
-
}
|
|
6410
|
-
]
|
|
6411
|
-
},
|
|
6412
|
-
autoDeleteIntervalMinutes: {
|
|
6413
|
-
description: "Minutes the sandbox stays stopped before the record is deleted. 0 deletes it when it stops. -1 keeps it. Null resets to the platform default. Provider-native timers are optional backup.",
|
|
6414
|
-
anyOf: [
|
|
6415
|
-
{
|
|
6416
|
-
type: "number"
|
|
6417
|
-
},
|
|
6418
|
-
{
|
|
6419
|
-
type: "null"
|
|
6420
|
-
}
|
|
6421
|
-
]
|
|
6422
6456
|
}
|
|
6423
6457
|
},
|
|
6424
6458
|
required: [
|
|
@@ -6437,16 +6471,17 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6437
6471
|
}
|
|
6438
6472
|
},
|
|
6439
6473
|
{
|
|
6440
|
-
id: "
|
|
6441
|
-
name: "
|
|
6474
|
+
id: "sandboxes_storage_delete",
|
|
6475
|
+
name: "sandboxes_storage_delete",
|
|
6442
6476
|
cli: [
|
|
6443
6477
|
"sandboxes",
|
|
6444
|
-
"
|
|
6478
|
+
"storage",
|
|
6479
|
+
"delete"
|
|
6445
6480
|
],
|
|
6446
6481
|
cliArgs: [
|
|
6447
6482
|
"sandboxId"
|
|
6448
6483
|
],
|
|
6449
|
-
description: "
|
|
6484
|
+
description: "Delete a named volume or a top-level sandbox folder, with everything in it. Refused while a container mounts it (in any state: a stopped one counts, so stopping does not help), mounts a folder above it (a bind of /), or a volume keeps its data in the folder: remove those first.",
|
|
6450
6485
|
inputSchema: {
|
|
6451
6486
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6452
6487
|
type: "object",
|
|
@@ -6461,20 +6496,25 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6461
6496
|
minLength: 1,
|
|
6462
6497
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6463
6498
|
},
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6499
|
+
kind: {
|
|
6500
|
+
type: "string",
|
|
6501
|
+
enum: [
|
|
6502
|
+
"volume",
|
|
6503
|
+
"folder"
|
|
6504
|
+
],
|
|
6505
|
+
description: "volume or folder."
|
|
6468
6506
|
},
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6507
|
+
name: {
|
|
6508
|
+
type: "string",
|
|
6509
|
+
minLength: 1,
|
|
6510
|
+
description: "The volume’s name, or the folder’s path in the sandbox (/srv, not /srv/app)."
|
|
6473
6511
|
}
|
|
6474
6512
|
},
|
|
6475
6513
|
required: [
|
|
6476
6514
|
"organization",
|
|
6477
|
-
"sandboxId"
|
|
6515
|
+
"sandboxId",
|
|
6516
|
+
"kind",
|
|
6517
|
+
"name"
|
|
6478
6518
|
],
|
|
6479
6519
|
additionalProperties: false
|
|
6480
6520
|
},
|
|
@@ -6488,16 +6528,17 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6488
6528
|
}
|
|
6489
6529
|
},
|
|
6490
6530
|
{
|
|
6491
|
-
id: "
|
|
6492
|
-
name: "
|
|
6531
|
+
id: "sandboxes_commands_run",
|
|
6532
|
+
name: "sandboxes_commands_run",
|
|
6493
6533
|
cli: [
|
|
6494
6534
|
"sandboxes",
|
|
6495
|
-
"
|
|
6535
|
+
"commands",
|
|
6536
|
+
"run"
|
|
6496
6537
|
],
|
|
6497
6538
|
cliArgs: [
|
|
6498
6539
|
"sandboxId"
|
|
6499
6540
|
],
|
|
6500
|
-
description: "
|
|
6541
|
+
description: "Run a shell command in a sandbox. Waits up to 120 seconds, then returns sessionId and commandId to poll. Starts the sandbox when allowed. Sessions do not survive idle-stop: for a process that must keep running, read the sandbox-boot skill. Never put secret values in the command; it is logged.",
|
|
6501
6542
|
inputSchema: {
|
|
6502
6543
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6503
6544
|
type: "object",
|
|
@@ -6512,10 +6553,557 @@ var GENERATED_TOOL_CATALOG = [
|
|
|
6512
6553
|
minLength: 1,
|
|
6513
6554
|
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6514
6555
|
},
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6556
|
+
container: {
|
|
6557
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6558
|
+
type: "string",
|
|
6559
|
+
minLength: 1,
|
|
6560
|
+
maxLength: 255,
|
|
6561
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6562
|
+
},
|
|
6563
|
+
command: {
|
|
6564
|
+
type: "string",
|
|
6565
|
+
minLength: 1,
|
|
6566
|
+
description: "Shell command to run. Never include secret values: commands are logged."
|
|
6567
|
+
},
|
|
6568
|
+
sessionId: {
|
|
6569
|
+
description: "Session from sandboxes_shells_create, to keep cwd and environment from earlier commands. Omit for a one-off session.",
|
|
6570
|
+
type: "string",
|
|
6571
|
+
minLength: 1
|
|
6572
|
+
},
|
|
6573
|
+
cwd: {
|
|
6574
|
+
description: "Directory to run the command in.",
|
|
6575
|
+
type: "string",
|
|
6576
|
+
minLength: 1
|
|
6577
|
+
},
|
|
6578
|
+
waitSeconds: {
|
|
6579
|
+
description: "Seconds to wait before returning handles to poll: 1 to 120, default 120.",
|
|
6580
|
+
type: "number"
|
|
6581
|
+
}
|
|
6582
|
+
},
|
|
6583
|
+
required: [
|
|
6584
|
+
"organization",
|
|
6585
|
+
"sandboxId",
|
|
6586
|
+
"command"
|
|
6587
|
+
],
|
|
6588
|
+
additionalProperties: false
|
|
6589
|
+
},
|
|
6590
|
+
outputSchema: {
|
|
6591
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6592
|
+
type: "object",
|
|
6593
|
+
propertyNames: {
|
|
6594
|
+
type: "string"
|
|
6595
|
+
},
|
|
6596
|
+
additionalProperties: {}
|
|
6597
|
+
}
|
|
6598
|
+
},
|
|
6599
|
+
{
|
|
6600
|
+
id: "sandboxes_commands_get",
|
|
6601
|
+
name: "sandboxes_commands_get",
|
|
6602
|
+
cli: [
|
|
6603
|
+
"sandboxes",
|
|
6604
|
+
"commands",
|
|
6605
|
+
"get"
|
|
6606
|
+
],
|
|
6607
|
+
cliArgs: [
|
|
6608
|
+
"commandId"
|
|
6609
|
+
],
|
|
6610
|
+
description: "Get a shell command’s status and exit code.",
|
|
6611
|
+
inputSchema: {
|
|
6612
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6613
|
+
type: "object",
|
|
6614
|
+
properties: {
|
|
6615
|
+
organization: {
|
|
6616
|
+
type: "string",
|
|
6617
|
+
minLength: 1,
|
|
6618
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6619
|
+
},
|
|
6620
|
+
sandboxId: {
|
|
6621
|
+
type: "string",
|
|
6622
|
+
minLength: 1,
|
|
6623
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6624
|
+
},
|
|
6625
|
+
container: {
|
|
6626
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6627
|
+
type: "string",
|
|
6628
|
+
minLength: 1,
|
|
6629
|
+
maxLength: 255,
|
|
6630
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6631
|
+
},
|
|
6632
|
+
sessionId: {
|
|
6633
|
+
type: "string",
|
|
6634
|
+
minLength: 1,
|
|
6635
|
+
description: "Session id returned by sandboxes_commands_run together with the commandId."
|
|
6636
|
+
},
|
|
6637
|
+
commandId: {
|
|
6638
|
+
type: "string",
|
|
6639
|
+
minLength: 1,
|
|
6640
|
+
description: "Command id returned by sandboxes_commands_run."
|
|
6641
|
+
}
|
|
6642
|
+
},
|
|
6643
|
+
required: [
|
|
6644
|
+
"organization",
|
|
6645
|
+
"sandboxId",
|
|
6646
|
+
"sessionId",
|
|
6647
|
+
"commandId"
|
|
6648
|
+
],
|
|
6649
|
+
additionalProperties: false
|
|
6650
|
+
},
|
|
6651
|
+
outputSchema: {
|
|
6652
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6653
|
+
type: "object",
|
|
6654
|
+
propertyNames: {
|
|
6655
|
+
type: "string"
|
|
6656
|
+
},
|
|
6657
|
+
additionalProperties: {}
|
|
6658
|
+
}
|
|
6659
|
+
},
|
|
6660
|
+
{
|
|
6661
|
+
id: "sandboxes_commands_logs",
|
|
6662
|
+
name: "sandboxes_commands_logs",
|
|
6663
|
+
cli: [
|
|
6664
|
+
"sandboxes",
|
|
6665
|
+
"commands",
|
|
6666
|
+
"logs"
|
|
6667
|
+
],
|
|
6668
|
+
cliArgs: [
|
|
6669
|
+
"commandId"
|
|
6670
|
+
],
|
|
6671
|
+
description: "Get a page of a shell command’s stdout and stderr.",
|
|
6672
|
+
inputSchema: {
|
|
6673
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6674
|
+
type: "object",
|
|
6675
|
+
properties: {
|
|
6676
|
+
organization: {
|
|
6677
|
+
type: "string",
|
|
6678
|
+
minLength: 1,
|
|
6679
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6680
|
+
},
|
|
6681
|
+
sandboxId: {
|
|
6682
|
+
type: "string",
|
|
6683
|
+
minLength: 1,
|
|
6684
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6685
|
+
},
|
|
6686
|
+
container: {
|
|
6687
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6688
|
+
type: "string",
|
|
6689
|
+
minLength: 1,
|
|
6690
|
+
maxLength: 255,
|
|
6691
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6692
|
+
},
|
|
6693
|
+
sessionId: {
|
|
6694
|
+
type: "string",
|
|
6695
|
+
minLength: 1,
|
|
6696
|
+
description: "Session id returned by sandboxes_commands_run together with the commandId."
|
|
6697
|
+
},
|
|
6698
|
+
commandId: {
|
|
6699
|
+
type: "string",
|
|
6700
|
+
minLength: 1,
|
|
6701
|
+
description: "Command id returned by sandboxes_commands_run."
|
|
6702
|
+
},
|
|
6703
|
+
offset: {
|
|
6704
|
+
description: "Character offset to continue reading from. Default 0.",
|
|
6705
|
+
type: "integer",
|
|
6706
|
+
minimum: 0,
|
|
6707
|
+
maximum: 9007199254740991
|
|
6708
|
+
}
|
|
6709
|
+
},
|
|
6710
|
+
required: [
|
|
6711
|
+
"organization",
|
|
6712
|
+
"sandboxId",
|
|
6713
|
+
"sessionId",
|
|
6714
|
+
"commandId"
|
|
6715
|
+
],
|
|
6716
|
+
additionalProperties: false
|
|
6717
|
+
},
|
|
6718
|
+
outputSchema: {
|
|
6719
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6720
|
+
type: "object",
|
|
6721
|
+
propertyNames: {
|
|
6722
|
+
type: "string"
|
|
6723
|
+
},
|
|
6724
|
+
additionalProperties: {}
|
|
6725
|
+
}
|
|
6726
|
+
},
|
|
6727
|
+
{
|
|
6728
|
+
id: "sandboxes_commands_kill",
|
|
6729
|
+
name: "sandboxes_commands_kill",
|
|
6730
|
+
cli: [
|
|
6731
|
+
"sandboxes",
|
|
6732
|
+
"commands",
|
|
6733
|
+
"kill"
|
|
6734
|
+
],
|
|
6735
|
+
cliArgs: [
|
|
6736
|
+
"commandId"
|
|
6737
|
+
],
|
|
6738
|
+
description: "Interrupt a running shell command.",
|
|
6739
|
+
inputSchema: {
|
|
6740
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6741
|
+
type: "object",
|
|
6742
|
+
properties: {
|
|
6743
|
+
organization: {
|
|
6744
|
+
type: "string",
|
|
6745
|
+
minLength: 1,
|
|
6746
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6747
|
+
},
|
|
6748
|
+
sandboxId: {
|
|
6749
|
+
type: "string",
|
|
6750
|
+
minLength: 1,
|
|
6751
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6752
|
+
},
|
|
6753
|
+
container: {
|
|
6754
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6755
|
+
type: "string",
|
|
6756
|
+
minLength: 1,
|
|
6757
|
+
maxLength: 255,
|
|
6758
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6759
|
+
},
|
|
6760
|
+
sessionId: {
|
|
6761
|
+
type: "string",
|
|
6762
|
+
minLength: 1,
|
|
6763
|
+
description: "Session id returned by sandboxes_commands_run together with the commandId."
|
|
6764
|
+
},
|
|
6765
|
+
commandId: {
|
|
6766
|
+
type: "string",
|
|
6767
|
+
minLength: 1,
|
|
6768
|
+
description: "Command id returned by sandboxes_commands_run."
|
|
6769
|
+
}
|
|
6770
|
+
},
|
|
6771
|
+
required: [
|
|
6772
|
+
"organization",
|
|
6773
|
+
"sandboxId",
|
|
6774
|
+
"sessionId",
|
|
6775
|
+
"commandId"
|
|
6776
|
+
],
|
|
6777
|
+
additionalProperties: false
|
|
6778
|
+
},
|
|
6779
|
+
outputSchema: {
|
|
6780
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6781
|
+
type: "object",
|
|
6782
|
+
propertyNames: {
|
|
6783
|
+
type: "string"
|
|
6784
|
+
},
|
|
6785
|
+
additionalProperties: {}
|
|
6786
|
+
}
|
|
6787
|
+
},
|
|
6788
|
+
{
|
|
6789
|
+
id: "sandboxes_shells_create",
|
|
6790
|
+
name: "sandboxes_shells_create",
|
|
6791
|
+
cli: [
|
|
6792
|
+
"sandboxes",
|
|
6793
|
+
"shells",
|
|
6794
|
+
"create"
|
|
6795
|
+
],
|
|
6796
|
+
cliArgs: [
|
|
6797
|
+
"sandboxId"
|
|
6798
|
+
],
|
|
6799
|
+
description: "Open a shell session that keeps cwd and environment between commands. Starts the sandbox when allowed; the session ends at idle-stop.",
|
|
6800
|
+
inputSchema: {
|
|
6801
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6802
|
+
type: "object",
|
|
6803
|
+
properties: {
|
|
6804
|
+
organization: {
|
|
6805
|
+
type: "string",
|
|
6806
|
+
minLength: 1,
|
|
6807
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6808
|
+
},
|
|
6809
|
+
sandboxId: {
|
|
6810
|
+
type: "string",
|
|
6811
|
+
minLength: 1,
|
|
6812
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6813
|
+
},
|
|
6814
|
+
container: {
|
|
6815
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6816
|
+
type: "string",
|
|
6817
|
+
minLength: 1,
|
|
6818
|
+
maxLength: 255,
|
|
6819
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6820
|
+
},
|
|
6821
|
+
sessionId: {
|
|
6822
|
+
description: "Id for the new session: a slug; user-cmd, image-cmd and compose are reserved. Omit to generate one.",
|
|
6823
|
+
type: "string",
|
|
6824
|
+
minLength: 1
|
|
6825
|
+
}
|
|
6826
|
+
},
|
|
6827
|
+
required: [
|
|
6828
|
+
"organization",
|
|
6829
|
+
"sandboxId"
|
|
6830
|
+
],
|
|
6831
|
+
additionalProperties: false
|
|
6832
|
+
},
|
|
6833
|
+
outputSchema: {
|
|
6834
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6835
|
+
type: "object",
|
|
6836
|
+
propertyNames: {
|
|
6837
|
+
type: "string"
|
|
6838
|
+
},
|
|
6839
|
+
additionalProperties: {}
|
|
6840
|
+
}
|
|
6841
|
+
},
|
|
6842
|
+
{
|
|
6843
|
+
id: "sandboxes_shells_close",
|
|
6844
|
+
name: "sandboxes_shells_close",
|
|
6845
|
+
cli: [
|
|
6846
|
+
"sandboxes",
|
|
6847
|
+
"shells",
|
|
6848
|
+
"close"
|
|
6849
|
+
],
|
|
6850
|
+
cliArgs: [
|
|
6851
|
+
"sessionId"
|
|
6852
|
+
],
|
|
6853
|
+
description: "Close a shell session.",
|
|
6854
|
+
inputSchema: {
|
|
6855
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6856
|
+
type: "object",
|
|
6857
|
+
properties: {
|
|
6858
|
+
organization: {
|
|
6859
|
+
type: "string",
|
|
6860
|
+
minLength: 1,
|
|
6861
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6862
|
+
},
|
|
6863
|
+
sandboxId: {
|
|
6864
|
+
type: "string",
|
|
6865
|
+
minLength: 1,
|
|
6866
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6867
|
+
},
|
|
6868
|
+
container: {
|
|
6869
|
+
description: "Container to work in, by name, from sandboxes_containers_list. Default: the sandbox’s default container, else the one running container. With several running and no default the call fails and lists them.",
|
|
6870
|
+
type: "string",
|
|
6871
|
+
minLength: 1,
|
|
6872
|
+
maxLength: 255,
|
|
6873
|
+
pattern: "^[a-zA-Z0-9][a-zA-Z0-9_.-]*$"
|
|
6874
|
+
},
|
|
6875
|
+
sessionId: {
|
|
6876
|
+
type: "string",
|
|
6877
|
+
minLength: 1,
|
|
6878
|
+
description: "Session id from sandboxes_shells_create."
|
|
6879
|
+
}
|
|
6880
|
+
},
|
|
6881
|
+
required: [
|
|
6882
|
+
"organization",
|
|
6883
|
+
"sandboxId",
|
|
6884
|
+
"sessionId"
|
|
6885
|
+
],
|
|
6886
|
+
additionalProperties: false
|
|
6887
|
+
},
|
|
6888
|
+
outputSchema: {
|
|
6889
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6890
|
+
type: "object",
|
|
6891
|
+
propertyNames: {
|
|
6892
|
+
type: "string"
|
|
6893
|
+
},
|
|
6894
|
+
additionalProperties: {}
|
|
6895
|
+
}
|
|
6896
|
+
},
|
|
6897
|
+
{
|
|
6898
|
+
id: "sandboxes_set_boot",
|
|
6899
|
+
name: "sandboxes_set_boot",
|
|
6900
|
+
cli: [
|
|
6901
|
+
"sandboxes",
|
|
6902
|
+
"set-boot"
|
|
6903
|
+
],
|
|
6904
|
+
cliArgs: [
|
|
6905
|
+
"sandboxId"
|
|
6906
|
+
],
|
|
6907
|
+
description: "Register a command that starts now and again after every restart. For example bun dev. On Compose it runs after the stack; on a Dockerfile it replaces the image CMD. Snapshots cannot register one. Read the sandbox-boot skill.",
|
|
6908
|
+
inputSchema: {
|
|
6909
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6910
|
+
type: "object",
|
|
6911
|
+
properties: {
|
|
6912
|
+
organization: {
|
|
6913
|
+
type: "string",
|
|
6914
|
+
minLength: 1,
|
|
6915
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6916
|
+
},
|
|
6917
|
+
sandboxId: {
|
|
6918
|
+
type: "string",
|
|
6919
|
+
minLength: 1,
|
|
6920
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6921
|
+
},
|
|
6922
|
+
command: {
|
|
6923
|
+
type: "string",
|
|
6924
|
+
minLength: 1,
|
|
6925
|
+
description: "Command to start, e.g. bun dev."
|
|
6926
|
+
},
|
|
6927
|
+
cwd: {
|
|
6928
|
+
description: "Directory to run it in. Default /.",
|
|
6929
|
+
type: "string",
|
|
6930
|
+
minLength: 1
|
|
6931
|
+
},
|
|
6932
|
+
start: {
|
|
6933
|
+
description: "Also start it now, not only after restarts. Default true.",
|
|
6934
|
+
type: "boolean"
|
|
6935
|
+
}
|
|
6936
|
+
},
|
|
6937
|
+
required: [
|
|
6938
|
+
"organization",
|
|
6939
|
+
"sandboxId",
|
|
6940
|
+
"command"
|
|
6941
|
+
],
|
|
6942
|
+
additionalProperties: false
|
|
6943
|
+
},
|
|
6944
|
+
outputSchema: {
|
|
6945
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6946
|
+
type: "object",
|
|
6947
|
+
propertyNames: {
|
|
6948
|
+
type: "string"
|
|
6949
|
+
},
|
|
6950
|
+
additionalProperties: {}
|
|
6951
|
+
}
|
|
6952
|
+
},
|
|
6953
|
+
{
|
|
6954
|
+
id: "sandboxes_update",
|
|
6955
|
+
name: "sandboxes_update",
|
|
6956
|
+
cli: [
|
|
6957
|
+
"sandboxes",
|
|
6958
|
+
"update"
|
|
6959
|
+
],
|
|
6960
|
+
cliArgs: [
|
|
6961
|
+
"sandboxId"
|
|
6962
|
+
],
|
|
6963
|
+
description: "Change a sandbox’s display name, idle-stop or auto-delete interval. Omit a field to keep it; null resets it to the platform default.",
|
|
6964
|
+
inputSchema: {
|
|
6965
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
6966
|
+
type: "object",
|
|
6967
|
+
properties: {
|
|
6968
|
+
organization: {
|
|
6969
|
+
type: "string",
|
|
6970
|
+
minLength: 1,
|
|
6971
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
6972
|
+
},
|
|
6973
|
+
sandboxId: {
|
|
6974
|
+
type: "string",
|
|
6975
|
+
minLength: 1,
|
|
6976
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
6977
|
+
},
|
|
6978
|
+
displayName: {
|
|
6979
|
+
description: "New display name. Null clears it; omit to keep it.",
|
|
6980
|
+
anyOf: [
|
|
6981
|
+
{
|
|
6982
|
+
type: "string"
|
|
6983
|
+
},
|
|
6984
|
+
{
|
|
6985
|
+
type: "null"
|
|
6986
|
+
}
|
|
6987
|
+
]
|
|
6988
|
+
},
|
|
6989
|
+
autoStopIntervalMinutes: {
|
|
6990
|
+
description: "Minutes of inactivity before the platform worker idle-stops the sandbox. -1 always on. 0 is rejected. Null resets to the platform default. Provider-native timers are optional backup.",
|
|
6991
|
+
anyOf: [
|
|
6992
|
+
{
|
|
6993
|
+
type: "number"
|
|
6994
|
+
},
|
|
6995
|
+
{
|
|
6996
|
+
type: "null"
|
|
6997
|
+
}
|
|
6998
|
+
]
|
|
6999
|
+
},
|
|
7000
|
+
autoDeleteIntervalMinutes: {
|
|
7001
|
+
description: "Minutes the sandbox stays stopped before the record is deleted. 0 deletes it when it stops. -1 keeps it. Null resets to the platform default. Provider-native timers are optional backup.",
|
|
7002
|
+
anyOf: [
|
|
7003
|
+
{
|
|
7004
|
+
type: "number"
|
|
7005
|
+
},
|
|
7006
|
+
{
|
|
7007
|
+
type: "null"
|
|
7008
|
+
}
|
|
7009
|
+
]
|
|
7010
|
+
}
|
|
7011
|
+
},
|
|
7012
|
+
required: [
|
|
7013
|
+
"organization",
|
|
7014
|
+
"sandboxId"
|
|
7015
|
+
],
|
|
7016
|
+
additionalProperties: false
|
|
7017
|
+
},
|
|
7018
|
+
outputSchema: {
|
|
7019
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7020
|
+
type: "object",
|
|
7021
|
+
propertyNames: {
|
|
7022
|
+
type: "string"
|
|
7023
|
+
},
|
|
7024
|
+
additionalProperties: {}
|
|
7025
|
+
}
|
|
7026
|
+
},
|
|
7027
|
+
{
|
|
7028
|
+
id: "sandboxes_resize",
|
|
7029
|
+
name: "sandboxes_resize",
|
|
7030
|
+
cli: [
|
|
7031
|
+
"sandboxes",
|
|
7032
|
+
"resize"
|
|
7033
|
+
],
|
|
7034
|
+
cliArgs: [
|
|
7035
|
+
"sandboxId"
|
|
7036
|
+
],
|
|
7037
|
+
description: "Change a sandbox’s CPU and/or memory. While running only increases are allowed; stop it first to decrease (this tool does not stop it). Disk: sandboxes_resize_disk.",
|
|
7038
|
+
inputSchema: {
|
|
7039
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7040
|
+
type: "object",
|
|
7041
|
+
properties: {
|
|
7042
|
+
organization: {
|
|
7043
|
+
type: "string",
|
|
7044
|
+
minLength: 1,
|
|
7045
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
7046
|
+
},
|
|
7047
|
+
sandboxId: {
|
|
7048
|
+
type: "string",
|
|
7049
|
+
minLength: 1,
|
|
7050
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
7051
|
+
},
|
|
7052
|
+
cpu: {
|
|
7053
|
+
description: "Number of CPUs.",
|
|
7054
|
+
type: "number",
|
|
7055
|
+
exclusiveMinimum: 0
|
|
7056
|
+
},
|
|
7057
|
+
memoryGiB: {
|
|
7058
|
+
description: "Memory in GiB.",
|
|
7059
|
+
type: "number",
|
|
7060
|
+
exclusiveMinimum: 0
|
|
7061
|
+
}
|
|
7062
|
+
},
|
|
7063
|
+
required: [
|
|
7064
|
+
"organization",
|
|
7065
|
+
"sandboxId"
|
|
7066
|
+
],
|
|
7067
|
+
additionalProperties: false
|
|
7068
|
+
},
|
|
7069
|
+
outputSchema: {
|
|
7070
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7071
|
+
type: "object",
|
|
7072
|
+
propertyNames: {
|
|
7073
|
+
type: "string"
|
|
7074
|
+
},
|
|
7075
|
+
additionalProperties: {}
|
|
7076
|
+
}
|
|
7077
|
+
},
|
|
7078
|
+
{
|
|
7079
|
+
id: "sandboxes_resize_disk",
|
|
7080
|
+
name: "sandboxes_resize_disk",
|
|
7081
|
+
cli: [
|
|
7082
|
+
"sandboxes",
|
|
7083
|
+
"resize-disk"
|
|
7084
|
+
],
|
|
7085
|
+
cliArgs: [
|
|
7086
|
+
"sandboxId"
|
|
7087
|
+
],
|
|
7088
|
+
description: "Grow a sandbox’s disk. The sandbox must be stopped first (this tool does not stop it). Disk only grows, never shrinks.",
|
|
7089
|
+
inputSchema: {
|
|
7090
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
7091
|
+
type: "object",
|
|
7092
|
+
properties: {
|
|
7093
|
+
organization: {
|
|
7094
|
+
type: "string",
|
|
7095
|
+
minLength: 1,
|
|
7096
|
+
description: "Organization id or slug, from organizations_list. Ids survive renames; slugs change when the organization is renamed."
|
|
7097
|
+
},
|
|
7098
|
+
sandboxId: {
|
|
7099
|
+
type: "string",
|
|
7100
|
+
minLength: 1,
|
|
7101
|
+
description: "Sandbox name (e.g. quiet-harbor) or id, from sandboxes_list or sandboxes_create. Names are unique within the organization."
|
|
7102
|
+
},
|
|
7103
|
+
diskGiB: {
|
|
7104
|
+
type: "number",
|
|
7105
|
+
exclusiveMinimum: 0,
|
|
7106
|
+
description: "New total disk size in GiB; must be larger than the current size."
|
|
6519
7107
|
}
|
|
6520
7108
|
},
|
|
6521
7109
|
required: [
|
|
@@ -8588,7 +9176,7 @@ function getCliName(argv = process.argv) {
|
|
|
8588
9176
|
return CLI_NAMES.find((name) => name === invoked) ?? "ghostdock";
|
|
8589
9177
|
}
|
|
8590
9178
|
// package.json
|
|
8591
|
-
var version = "0.0.
|
|
9179
|
+
var version = "0.0.15";
|
|
8592
9180
|
var package_default = {
|
|
8593
9181
|
name: "ghostdock",
|
|
8594
9182
|
description: "Ghostdock CLI — device login and agent tool invocation from the command line",
|
|
@@ -9193,6 +9781,150 @@ var envCommand = defineCommand({
|
|
|
9193
9781
|
}
|
|
9194
9782
|
});
|
|
9195
9783
|
|
|
9784
|
+
// src/container-logs.ts
|
|
9785
|
+
var FOLLOW_INTERVAL_MS = 2000;
|
|
9786
|
+
function defaultLogsDeps(follow) {
|
|
9787
|
+
let stop = false;
|
|
9788
|
+
if (follow) {
|
|
9789
|
+
process.once("SIGINT", () => {
|
|
9790
|
+
stop = true;
|
|
9791
|
+
});
|
|
9792
|
+
}
|
|
9793
|
+
return {
|
|
9794
|
+
request: (input) => authorizedRequest("/api/v1/tools/sandboxes_containers_logs", {
|
|
9795
|
+
method: "POST",
|
|
9796
|
+
body: JSON.stringify(input)
|
|
9797
|
+
}),
|
|
9798
|
+
out: (line) => process.stdout.write(`${line}
|
|
9799
|
+
`),
|
|
9800
|
+
err: (line) => process.stderr.write(`${line}
|
|
9801
|
+
`),
|
|
9802
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
9803
|
+
stopped: () => stop
|
|
9804
|
+
};
|
|
9805
|
+
}
|
|
9806
|
+
async function runContainerLogs(input, options, deps = defaultLogsDeps(options.follow)) {
|
|
9807
|
+
const json = isJsonOutput();
|
|
9808
|
+
const color = colorEnabled(process.stdout);
|
|
9809
|
+
const print = (line) => {
|
|
9810
|
+
if (json) {
|
|
9811
|
+
deps.out(JSON.stringify(line));
|
|
9812
|
+
return;
|
|
9813
|
+
}
|
|
9814
|
+
const text = options.timestamps && line.time ? `${dim(line.time, color)} ${line.text}` : line.text;
|
|
9815
|
+
(line.stream === "stderr" ? deps.err : deps.out)(text);
|
|
9816
|
+
};
|
|
9817
|
+
let result = await deps.request(input);
|
|
9818
|
+
if (!result.running) {
|
|
9819
|
+
deps.err("The sandbox is stopped: it has no logs to show.");
|
|
9820
|
+
return 1;
|
|
9821
|
+
}
|
|
9822
|
+
let last = null;
|
|
9823
|
+
for (;; ) {
|
|
9824
|
+
for (const line of result.lines) {
|
|
9825
|
+
print(line);
|
|
9826
|
+
if (line.time)
|
|
9827
|
+
last = line.time;
|
|
9828
|
+
}
|
|
9829
|
+
if (!options.follow) {
|
|
9830
|
+
if (result.truncated && json) {
|
|
9831
|
+
deps.out(JSON.stringify({ truncated: true }));
|
|
9832
|
+
} else if (result.truncated) {
|
|
9833
|
+
deps.err(dim("(older lines left out: use --tail for more)", colorEnabled(process.stderr)));
|
|
9834
|
+
}
|
|
9835
|
+
return 0;
|
|
9836
|
+
}
|
|
9837
|
+
if (!result.truncated)
|
|
9838
|
+
await deps.sleep(FOLLOW_INTERVAL_MS);
|
|
9839
|
+
if (deps.stopped())
|
|
9840
|
+
return 0;
|
|
9841
|
+
const { tail: _tail, ...rest } = input;
|
|
9842
|
+
try {
|
|
9843
|
+
result = await deps.request(last ? { ...rest, after: last } : input);
|
|
9844
|
+
} catch (error) {
|
|
9845
|
+
deps.err(red(error instanceof Error ? error.message : String(error), colorEnabled(process.stderr)));
|
|
9846
|
+
return 1;
|
|
9847
|
+
}
|
|
9848
|
+
if (!result.running) {
|
|
9849
|
+
deps.err("The sandbox stopped.");
|
|
9850
|
+
return 0;
|
|
9851
|
+
}
|
|
9852
|
+
}
|
|
9853
|
+
}
|
|
9854
|
+
|
|
9855
|
+
// src/container-picker.ts
|
|
9856
|
+
import { createInterface } from "node:readline/promises";
|
|
9857
|
+
function notRunningContainerOf(error) {
|
|
9858
|
+
if (!(error instanceof ApiError) || !error.data || typeof error.data !== "object")
|
|
9859
|
+
return null;
|
|
9860
|
+
const { code, params } = error.data;
|
|
9861
|
+
if (code !== "container_not_running")
|
|
9862
|
+
return null;
|
|
9863
|
+
const container = params && typeof params === "object" ? params : {};
|
|
9864
|
+
return typeof container.container === "string" && container.container ? container.container : null;
|
|
9865
|
+
}
|
|
9866
|
+
function containerQuestionOf(error) {
|
|
9867
|
+
if (!(error instanceof ApiError) || !error.data || typeof error.data !== "object")
|
|
9868
|
+
return null;
|
|
9869
|
+
const { code, params } = error.data;
|
|
9870
|
+
if (code !== "container_choice_required" && code !== "container_default_missing")
|
|
9871
|
+
return null;
|
|
9872
|
+
const record = params && typeof params === "object" ? params : {};
|
|
9873
|
+
const running = typeof record.containers === "string" ? record.containers.split(",").map((name) => name.trim()).filter(Boolean) : [];
|
|
9874
|
+
if (running.length === 0)
|
|
9875
|
+
return null;
|
|
9876
|
+
return {
|
|
9877
|
+
running,
|
|
9878
|
+
...code === "container_default_missing" && typeof record.container === "string" ? { missingDefault: record.container } : {}
|
|
9879
|
+
};
|
|
9880
|
+
}
|
|
9881
|
+
var say = (line) => process.stderr.write(`${line}
|
|
9882
|
+
`);
|
|
9883
|
+
var chooseContainerOnTerminal = async ({ running, missingDefault }) => {
|
|
9884
|
+
if (missingDefault) {
|
|
9885
|
+
say(`
|
|
9886
|
+
The default container ${missingDefault} is gone.`);
|
|
9887
|
+
}
|
|
9888
|
+
say(missingDefault ? "Which container?" : `
|
|
9889
|
+
Several containers are running. Which one?`);
|
|
9890
|
+
running.forEach((name, index) => {
|
|
9891
|
+
say(` ${index + 1}. ${name}`);
|
|
9892
|
+
});
|
|
9893
|
+
const prompt = createInterface({ input: process.stdin, output: process.stderr });
|
|
9894
|
+
try {
|
|
9895
|
+
const answer = (await prompt.question("Number (Enter to cancel): ")).trim();
|
|
9896
|
+
const index = Number.parseInt(answer, 10) - 1;
|
|
9897
|
+
return Number.isInteger(index) && index >= 0 && index < running.length ? running[index] ?? null : null;
|
|
9898
|
+
} finally {
|
|
9899
|
+
prompt.close();
|
|
9900
|
+
}
|
|
9901
|
+
};
|
|
9902
|
+
var confirmDefaultOnTerminal = async (container) => {
|
|
9903
|
+
const prompt = createInterface({ input: process.stdin, output: process.stderr });
|
|
9904
|
+
try {
|
|
9905
|
+
const answer = (await prompt.question(`Make ${container} the default? [y/N] `)).trim();
|
|
9906
|
+
return /^y(es)?$/i.test(answer);
|
|
9907
|
+
} finally {
|
|
9908
|
+
prompt.close();
|
|
9909
|
+
}
|
|
9910
|
+
};
|
|
9911
|
+
var confirmStartOnTerminal = async (container) => {
|
|
9912
|
+
const prompt = createInterface({ input: process.stdin, output: process.stderr });
|
|
9913
|
+
try {
|
|
9914
|
+
const answer = (await prompt.question(`Container ${container} is not running. Start it? [Y/n] `)).trim();
|
|
9915
|
+
return answer === "" || /^y(es)?$/i.test(answer);
|
|
9916
|
+
} finally {
|
|
9917
|
+
prompt.close();
|
|
9918
|
+
}
|
|
9919
|
+
};
|
|
9920
|
+
function defaultContainerPickers() {
|
|
9921
|
+
return process.stdin.isTTY && process.stderr.isTTY ? {
|
|
9922
|
+
choose: chooseContainerOnTerminal,
|
|
9923
|
+
confirmDefault: confirmDefaultOnTerminal,
|
|
9924
|
+
confirmStart: confirmStartOnTerminal
|
|
9925
|
+
} : undefined;
|
|
9926
|
+
}
|
|
9927
|
+
|
|
9196
9928
|
// src/progress.ts
|
|
9197
9929
|
var PROGRESS_FRAMES = ["▂▄▆", "▄▆█", "▆█▆", "█▆▄", "▆▄▂", "▄▂▄"];
|
|
9198
9930
|
var FRAME_MS = 120;
|
|
@@ -9293,10 +10025,10 @@ function symbolForStatus(status) {
|
|
|
9293
10025
|
return "failed";
|
|
9294
10026
|
if (/^(running|active|ready|deployed|published|online|verified|ok)$/.test(s))
|
|
9295
10027
|
return "ready";
|
|
9296
|
-
if (/^(stopped|deleted|unpublished|vanished|archived|revoked|closed|killed)$/.test(s)) {
|
|
10028
|
+
if (/^(stopped|deleted|unpublished|vanished|archived|revoked|closed|killed|exited|dead|paused)$/.test(s)) {
|
|
9297
10029
|
return "stopped";
|
|
9298
10030
|
}
|
|
9299
|
-
if (/(pending|starting|spawning|stopping|building|progress|awaiting|queued|creating)/.test(s)) {
|
|
10031
|
+
if (/(pending|starting|spawning|stopping|building|progress|awaiting|queued|creating|restarting|removing)/.test(s)) {
|
|
9300
10032
|
return "progress";
|
|
9301
10033
|
}
|
|
9302
10034
|
return "item";
|
|
@@ -9311,6 +10043,9 @@ function lineKeys(item) {
|
|
|
9311
10043
|
const idKeys = "id" in item ? ID_KEYS.filter((key) => key !== "sandboxId") : ID_KEYS;
|
|
9312
10044
|
return { id: firstKey(item, idKeys), label: firstKey(item, LABEL_KEYS) };
|
|
9313
10045
|
}
|
|
10046
|
+
function shortId(id) {
|
|
10047
|
+
return /^[0-9a-f]{64}$/.test(id) ? id.slice(0, 12) : id;
|
|
10048
|
+
}
|
|
9314
10049
|
function itemLine(item, color) {
|
|
9315
10050
|
const keys = lineKeys(item);
|
|
9316
10051
|
const id = keys.id ? item[keys.id] : undefined;
|
|
@@ -9319,7 +10054,7 @@ function itemLine(item, color) {
|
|
|
9319
10054
|
const url = firstString(item, URL_KEYS);
|
|
9320
10055
|
const parts = [label ?? id ?? "(unnamed)"];
|
|
9321
10056
|
if (label && id && id !== label)
|
|
9322
|
-
parts.push(dim(id, color));
|
|
10057
|
+
parts.push(dim(shortId(id), color));
|
|
9323
10058
|
if (status)
|
|
9324
10059
|
parts.push(status);
|
|
9325
10060
|
if (url)
|
|
@@ -9552,7 +10287,7 @@ function buildToolInput(schema, rawArgs) {
|
|
|
9552
10287
|
}
|
|
9553
10288
|
|
|
9554
10289
|
// src/commands/invoke.ts
|
|
9555
|
-
async function runToolInvoke(tool, rawArgs, log = console.log, error = printError, notice = printNotice) {
|
|
10290
|
+
async function runToolInvoke(tool, rawArgs, log = console.log, error = printError, notice = printNotice, pickers = defaultContainerPickers()) {
|
|
9556
10291
|
let input;
|
|
9557
10292
|
try {
|
|
9558
10293
|
input = buildToolInput(tool.inputSchema, rawArgs);
|
|
@@ -9564,29 +10299,110 @@ async function runToolInvoke(tool, rawArgs, log = console.log, error = printErro
|
|
|
9564
10299
|
error(err instanceof Error ? err.message : String(err));
|
|
9565
10300
|
return 1;
|
|
9566
10301
|
}
|
|
10302
|
+
if (tool.name === "sandboxes_containers_logs") {
|
|
10303
|
+
try {
|
|
10304
|
+
return await runContainerLogs(input, {
|
|
10305
|
+
follow: rawArgs.follow === true,
|
|
10306
|
+
timestamps: rawArgs.timestamps === true
|
|
10307
|
+
});
|
|
10308
|
+
} catch (err) {
|
|
10309
|
+
error(err instanceof Error ? err.message : `${tool.name} failed.`);
|
|
10310
|
+
return 1;
|
|
10311
|
+
}
|
|
10312
|
+
}
|
|
9567
10313
|
try {
|
|
9568
|
-
const
|
|
10314
|
+
const send = () => authorizedRequest(`/api/v1/tools/${tool.name}`, {
|
|
9569
10315
|
method: "POST",
|
|
9570
10316
|
body: JSON.stringify(input)
|
|
9571
10317
|
});
|
|
10318
|
+
const request = () => withContainerStart(input, send, rawArgs.start === true, pickers, notice);
|
|
9572
10319
|
const waitMessage = PROGRESS_MESSAGES[tool.name];
|
|
9573
10320
|
if (!waitMessage) {
|
|
9574
|
-
const result = await request
|
|
10321
|
+
const result = await withContainerPick(tool, input, request, pickers, notice);
|
|
9575
10322
|
printResult(result, () => renderResult(result, colorEnabled(process.stdout)), log);
|
|
10323
|
+
stopNote(result, notice);
|
|
9576
10324
|
return 0;
|
|
9577
10325
|
}
|
|
9578
|
-
const { value: result, elapsed } = await withProgress(waitMessage, request);
|
|
10326
|
+
const { value: result, elapsed } = await withContainerPick(tool, input, () => withProgress(waitMessage, request), pickers, notice);
|
|
9579
10327
|
printResult(result, () => {
|
|
9580
10328
|
const color = colorEnabled(process.stdout);
|
|
9581
10329
|
const lines = renderResult(result, color);
|
|
9582
10330
|
return bootLines(result, color).length > 0 ? lines : withElapsed(lines, elapsed);
|
|
9583
10331
|
}, log);
|
|
10332
|
+
stopNote(result, notice);
|
|
9584
10333
|
return 0;
|
|
9585
10334
|
} catch (err) {
|
|
9586
10335
|
error(err instanceof Error ? err.message : `${tool.name} failed.`);
|
|
9587
10336
|
return 1;
|
|
9588
10337
|
}
|
|
9589
10338
|
}
|
|
10339
|
+
async function withContainerPick(tool, input, send, pickers, notice) {
|
|
10340
|
+
try {
|
|
10341
|
+
return await send();
|
|
10342
|
+
} catch (err) {
|
|
10343
|
+
const properties = tool.inputSchema.properties;
|
|
10344
|
+
const question = containerQuestionOf(err);
|
|
10345
|
+
if (!pickers || !question || !properties || !("container" in properties) || input.container) {
|
|
10346
|
+
throw err;
|
|
10347
|
+
}
|
|
10348
|
+
const container = await pickers.choose(question);
|
|
10349
|
+
if (!container)
|
|
10350
|
+
throw err;
|
|
10351
|
+
input.container = container;
|
|
10352
|
+
const result = await send();
|
|
10353
|
+
if (typeof input.sandboxId === "string" && await pickers.confirmDefault(container)) {
|
|
10354
|
+
try {
|
|
10355
|
+
await authorizedRequest("/api/v1/tools/sandboxes_default_container", {
|
|
10356
|
+
method: "POST",
|
|
10357
|
+
body: JSON.stringify({
|
|
10358
|
+
organization: input.organization,
|
|
10359
|
+
sandboxId: input.sandboxId,
|
|
10360
|
+
container
|
|
10361
|
+
})
|
|
10362
|
+
});
|
|
10363
|
+
notice(eventLine("done", `Default container: ${container}.`));
|
|
10364
|
+
} catch (err) {
|
|
10365
|
+
notice(eventLine("failed", `The default container was not set: ${err instanceof Error ? err.message : String(err)}`));
|
|
10366
|
+
}
|
|
10367
|
+
}
|
|
10368
|
+
return result;
|
|
10369
|
+
}
|
|
10370
|
+
}
|
|
10371
|
+
async function withContainerStart(input, send, start, pickers, notice) {
|
|
10372
|
+
try {
|
|
10373
|
+
return await send();
|
|
10374
|
+
} catch (err) {
|
|
10375
|
+
const container = notRunningContainerOf(err);
|
|
10376
|
+
if (!container || typeof input.sandboxId !== "string")
|
|
10377
|
+
throw err;
|
|
10378
|
+
if (!start && !(pickers && await pickers.confirmStart(container)))
|
|
10379
|
+
throw err;
|
|
10380
|
+
await authorizedRequest("/api/v1/tools/sandboxes_containers_start", {
|
|
10381
|
+
method: "POST",
|
|
10382
|
+
body: JSON.stringify({
|
|
10383
|
+
organization: input.organization,
|
|
10384
|
+
sandboxId: input.sandboxId,
|
|
10385
|
+
container
|
|
10386
|
+
})
|
|
10387
|
+
});
|
|
10388
|
+
notice(eventLine("done", `Started ${container}.`));
|
|
10389
|
+
return await send();
|
|
10390
|
+
}
|
|
10391
|
+
}
|
|
10392
|
+
function stopNote(result, notice) {
|
|
10393
|
+
if (!result || typeof result !== "object")
|
|
10394
|
+
return;
|
|
10395
|
+
const { action, note, container } = result;
|
|
10396
|
+
if (action !== "stop" || typeof container !== "string")
|
|
10397
|
+
return;
|
|
10398
|
+
if (note === "default") {
|
|
10399
|
+
notice(`${container} is the sandbox's default container: SSH, commands and files ask which container until it runs again.`);
|
|
10400
|
+
} else if (note === "last_running") {
|
|
10401
|
+
notice("No container is running now: SSH, commands and files have none to land in until one runs.");
|
|
10402
|
+
} else if (note === "sandbox_stopped") {
|
|
10403
|
+
notice(`The sandbox is stopped, so ${container} is too: nothing was done.`);
|
|
10404
|
+
}
|
|
10405
|
+
}
|
|
9590
10406
|
var PROGRESS_MESSAGES = {
|
|
9591
10407
|
sandboxes_create: "Creating sandbox…",
|
|
9592
10408
|
sandboxes_wake: "Waking sandbox…",
|
|
@@ -9595,6 +10411,9 @@ var PROGRESS_MESSAGES = {
|
|
|
9595
10411
|
sandboxes_resize: "Resizing sandbox…",
|
|
9596
10412
|
sandboxes_resize_disk: "Resizing disk…",
|
|
9597
10413
|
sandboxes_commands_run: "Running command…",
|
|
10414
|
+
sandboxes_containers_start: "Starting container…",
|
|
10415
|
+
sandboxes_containers_stop: "Stopping container…",
|
|
10416
|
+
sandboxes_containers_restart: "Restarting container…",
|
|
9598
10417
|
snapshots_create: "Saving snapshot…",
|
|
9599
10418
|
projects_redeploy: "Redeploying…",
|
|
9600
10419
|
providers_verify_incus: "Checking the Incus host…"
|
|
@@ -9617,6 +10436,25 @@ function cliText(catalog, skills = BUILTIN_SKILL_NAMES) {
|
|
|
9617
10436
|
return commands.replace(/\bthe ([a-z][a-z0-9-]*) skill\b/g, (phrase, skill) => skills.includes(skill) ? `the ${skill} skill (\`${getCliName()} skills get ${skill}\`)` : phrase);
|
|
9618
10437
|
};
|
|
9619
10438
|
}
|
|
10439
|
+
function cliOnlyArgs(tool) {
|
|
10440
|
+
const schema = tool.inputSchema;
|
|
10441
|
+
const args = {};
|
|
10442
|
+
if (schema.properties && "container" in schema.properties && !schema.required?.includes("container")) {
|
|
10443
|
+
args.start = {
|
|
10444
|
+
type: "boolean",
|
|
10445
|
+
description: "Start the container first when it is not running, without asking."
|
|
10446
|
+
};
|
|
10447
|
+
}
|
|
10448
|
+
if (tool.name === "sandboxes_containers_logs") {
|
|
10449
|
+
args.follow = {
|
|
10450
|
+
type: "boolean",
|
|
10451
|
+
alias: "f",
|
|
10452
|
+
description: "Keep printing new lines until Ctrl-C."
|
|
10453
|
+
};
|
|
10454
|
+
args.timestamps = { type: "boolean", description: "Put each line's time in front of it." };
|
|
10455
|
+
}
|
|
10456
|
+
return args;
|
|
10457
|
+
}
|
|
9620
10458
|
var generatedToolCommands = new WeakSet;
|
|
9621
10459
|
function createToolCommands(catalog) {
|
|
9622
10460
|
const commands = {};
|
|
@@ -9627,7 +10465,7 @@ function createToolCommands(catalog) {
|
|
|
9627
10465
|
name: tool.cli?.at(-1) ?? tool.name,
|
|
9628
10466
|
description: toCliText(tool.description)
|
|
9629
10467
|
},
|
|
9630
|
-
args: buildToolArgs(tool.inputSchema, toCliText, tool.cliArgs),
|
|
10468
|
+
args: { ...buildToolArgs(tool.inputSchema, toCliText, tool.cliArgs), ...cliOnlyArgs(tool) },
|
|
9631
10469
|
async run({ args }) {
|
|
9632
10470
|
process.exitCode = await runToolInvoke(tool, args);
|
|
9633
10471
|
}
|
|
@@ -9642,7 +10480,7 @@ function createToolCommands(catalog) {
|
|
|
9642
10480
|
import { hostname } from "node:os";
|
|
9643
10481
|
|
|
9644
10482
|
// src/commands/login-organization.ts
|
|
9645
|
-
import { createInterface } from "node:readline/promises";
|
|
10483
|
+
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
9646
10484
|
function label(organization) {
|
|
9647
10485
|
return `${organization.name} (${organization.slug ?? organization.id})`;
|
|
9648
10486
|
}
|
|
@@ -9652,7 +10490,7 @@ Which organization should commands use by default?`);
|
|
|
9652
10490
|
organizations.forEach((organization, index) => {
|
|
9653
10491
|
console.log(` ${index + 1}. ${label(organization)}`);
|
|
9654
10492
|
});
|
|
9655
|
-
const prompt =
|
|
10493
|
+
const prompt = createInterface2({ input: process.stdin, output: process.stdout });
|
|
9656
10494
|
try {
|
|
9657
10495
|
const answer = (await prompt.question(`Number (Enter to skip): `)).trim();
|
|
9658
10496
|
const index = Number.parseInt(answer, 10) - 1;
|
|
@@ -9927,14 +10765,21 @@ function renderConfig(input) {
|
|
|
9927
10765
|
if (!isDnsZone(zone))
|
|
9928
10766
|
throw new Error(`The server sent a zone that is not a DNS name: ${zone}`);
|
|
9929
10767
|
}
|
|
10768
|
+
if (!device.address || !isIPv6Address(device.address)) {
|
|
10769
|
+
throw new Error(`The server sent no IPv6 address for this device: ${device.address}`);
|
|
10770
|
+
}
|
|
9930
10771
|
if (!isIPv6Address(network.gatewayAddress)) {
|
|
9931
10772
|
throw new Error(`The server sent a gateway that is not an IPv6 address: ${network.gatewayAddress}`);
|
|
9932
10773
|
}
|
|
10774
|
+
const ipv4 = device.address4 && network.ingress4 ? { address: device.address4, ingress: network.ingress4 } : null;
|
|
10775
|
+
if (ipv4 && (!isIPv4Address(ipv4.address) || !isIPv4Address(ipv4.ingress))) {
|
|
10776
|
+
throw new Error(`The server sent an IPv4 address that is not one: ${ipv4.address}, ${ipv4.ingress}`);
|
|
10777
|
+
}
|
|
9933
10778
|
const lines = [
|
|
9934
10779
|
"# Written by `ghostdock network connect`. Run it again rather than editing this file.",
|
|
9935
10780
|
"[Interface]",
|
|
9936
10781
|
`PrivateKey = ${input.privateKey}`,
|
|
9937
|
-
`Address = ${device.address}/128`,
|
|
10782
|
+
`Address = ${device.address}/128${ipv4 ? `, ${ipv4.address}/32` : ""}`,
|
|
9938
10783
|
`MTU = ${network.mtu}`
|
|
9939
10784
|
];
|
|
9940
10785
|
if (input.dns === "macos-resolver") {
|
|
@@ -9946,7 +10791,7 @@ function renderConfig(input) {
|
|
|
9946
10791
|
const domains = zones.map((zone) => `'~${zone}'`).join(" ");
|
|
9947
10792
|
lines.push(`PostUp = resolvectl dns %i ${network.gatewayAddress} && resolvectl domain %i ${domains}`);
|
|
9948
10793
|
}
|
|
9949
|
-
lines.push("", "[Peer]", `PublicKey = ${gateway.publicKey}`, `Endpoint = ${gateway.endpoint}`, `AllowedIPs = ${network.
|
|
10794
|
+
lines.push("", "[Peer]", `PublicKey = ${gateway.publicKey}`, `Endpoint = ${gateway.endpoint}`, `AllowedIPs = ${network.prefix}${ipv4 ? `, ${ipv4.ingress}/32` : ""}`, "PersistentKeepalive = 25", "");
|
|
9950
10795
|
return lines.join(`
|
|
9951
10796
|
`);
|
|
9952
10797
|
}
|
|
@@ -9955,6 +10800,26 @@ function isDnsZone(zone) {
|
|
|
9955
10800
|
const labels = zone.split(".");
|
|
9956
10801
|
return zone.length <= 253 && labels.length >= 2 && labels.every((label) => DNS_LABEL.test(label));
|
|
9957
10802
|
}
|
|
10803
|
+
function isIPv4Address(text) {
|
|
10804
|
+
return /^(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}$/.test(text);
|
|
10805
|
+
}
|
|
10806
|
+
function ipv4RouteOwner(platform, output) {
|
|
10807
|
+
if (platform === "darwin") {
|
|
10808
|
+
if (/^\s*destination: default$/m.test(output))
|
|
10809
|
+
return null;
|
|
10810
|
+
return /^\s*interface: (\S+)$/m.exec(output)?.[1] ?? null;
|
|
10811
|
+
}
|
|
10812
|
+
for (const line of output.split(`
|
|
10813
|
+
`).map((l) => l.trim())) {
|
|
10814
|
+
if (!line || /^(default|broadcast)\b/.test(line))
|
|
10815
|
+
continue;
|
|
10816
|
+
return /\bdev (\S+)/.exec(line)?.[1] ?? "another route";
|
|
10817
|
+
}
|
|
10818
|
+
return null;
|
|
10819
|
+
}
|
|
10820
|
+
function ipv4RouteCommand(platform, address) {
|
|
10821
|
+
return platform === "darwin" ? ["route", ["-n", "get", address]] : ["ip", ["-4", "route", "show", "table", "all", "match", address]];
|
|
10822
|
+
}
|
|
9958
10823
|
function isIPv6Address(text) {
|
|
9959
10824
|
return /^[0-9a-f:]{2,39}$/.test(text) && text.includes(":");
|
|
9960
10825
|
}
|
|
@@ -9995,6 +10860,11 @@ function defaultDeps() {
|
|
|
9995
10860
|
child.on("error", reject);
|
|
9996
10861
|
child.on("close", (code) => resolve(code ?? 1));
|
|
9997
10862
|
}),
|
|
10863
|
+
output: (command, args) => {
|
|
10864
|
+
const result = spawnSync(command, args, { encoding: "utf8" });
|
|
10865
|
+
return result.status === 0 ? result.stdout : "";
|
|
10866
|
+
},
|
|
10867
|
+
platform: process.platform,
|
|
9998
10868
|
has: (command) => spawnSync("sh", ["-c", `command -v ${command}`]).status === 0,
|
|
9999
10869
|
dir: networkDir(),
|
|
10000
10870
|
up: () => tunnelUp(),
|
|
@@ -10054,7 +10924,7 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
|
|
|
10054
10924
|
await writeDeviceState({
|
|
10055
10925
|
baseUrl: getBaseUrl(),
|
|
10056
10926
|
deviceId: registered.device.id,
|
|
10057
|
-
address: registered.device.address,
|
|
10927
|
+
address: registered.device.address ?? "",
|
|
10058
10928
|
gatewayProvider: registered.provider
|
|
10059
10929
|
}, deps.dir);
|
|
10060
10930
|
const wasUp = deps.up();
|
|
@@ -10065,6 +10935,7 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
|
|
|
10065
10935
|
return 1;
|
|
10066
10936
|
}
|
|
10067
10937
|
}
|
|
10938
|
+
const ipv4Clashes = ipv4Clashes4(registered, deps);
|
|
10068
10939
|
const code = await wgQuick(deps, "up");
|
|
10069
10940
|
if (code !== 0) {
|
|
10070
10941
|
deps.error(`wg-quick exited ${code}. The config is in ${configPath(deps.dir)}.`);
|
|
@@ -10086,6 +10957,12 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
|
|
|
10086
10957
|
` Another organization: ${getCliName()} network connect --org <org>.`
|
|
10087
10958
|
] : [],
|
|
10088
10959
|
...network.netZone && pinned && shortNameOrganizationChanged ? clearingNotice(network.netCookieSite) : [],
|
|
10960
|
+
...network.ingress4 && !device.address4 ? [
|
|
10961
|
+
" No IPv4 address was free on this provider's host, so browser names work over IPv6 only:",
|
|
10962
|
+
" Chrome on a network without IPv6 cannot open them on this machine. Firefox and Safari",
|
|
10963
|
+
" can. Run connect again later: an address frees up when another device goes."
|
|
10964
|
+
] : [],
|
|
10965
|
+
...ipv4Clashes.map(({ address, owner }) => ` ${address} is already routed through ${owner} on this machine: browsers may not reach the private network's names over IPv4 while it is. Ask your Ghostdock admin about the IPv4 block.`),
|
|
10089
10966
|
...dns === "none" ? [
|
|
10090
10967
|
" No split DNS on this machine (no systemd-resolved): use the addresses from",
|
|
10091
10968
|
` \`${getCliName()} network ls\`.`
|
|
@@ -10094,6 +10971,17 @@ async function runNetworkConnect(args = {}, deps = defaultDeps()) {
|
|
|
10094
10971
|
], deps.log);
|
|
10095
10972
|
return 0;
|
|
10096
10973
|
}
|
|
10974
|
+
function ipv4Clashes4(registered, deps) {
|
|
10975
|
+
const addresses = [registered.network.ingress4, registered.device.address4].filter((a) => typeof a === "string" && isIPv4Address(a));
|
|
10976
|
+
const clashes = [];
|
|
10977
|
+
for (const address of addresses) {
|
|
10978
|
+
const [command, args] = ipv4RouteCommand(deps.platform, address);
|
|
10979
|
+
const owner = ipv4RouteOwner(deps.platform, deps.output(command, args));
|
|
10980
|
+
if (owner)
|
|
10981
|
+
clashes.push({ address, owner });
|
|
10982
|
+
}
|
|
10983
|
+
return clashes;
|
|
10984
|
+
}
|
|
10097
10985
|
function clearingNotice(cookieSite) {
|
|
10098
10986
|
const site = cookieSite?.site ?? "the net domain";
|
|
10099
10987
|
return [
|
|
@@ -10210,7 +11098,7 @@ async function runNetworkLs(args, deps = defaultDeps()) {
|
|
|
10210
11098
|
const note = unreachableNote(s, connected);
|
|
10211
11099
|
lines.push([
|
|
10212
11100
|
` ${s.name.padEnd(width)}`,
|
|
10213
|
-
s.address.padEnd(28),
|
|
11101
|
+
(s.address ?? "-").padEnd(28),
|
|
10214
11102
|
s.canonicalName.padEnd(canonicalWidth),
|
|
10215
11103
|
...s.httpsName ? [`https://${s.httpsName}`.padEnd(httpsWidth)] : [],
|
|
10216
11104
|
...s.shortName ? [`https://${s.shortName}`.padEnd(shortWidth)] : [],
|
|
@@ -11961,6 +12849,7 @@ var GROUP_DESCRIPTIONS = {
|
|
|
11961
12849
|
providers: "Sandbox providers of an organization.",
|
|
11962
12850
|
sandboxes: "Create, run and manage sandboxes.",
|
|
11963
12851
|
"sandboxes commands": "Run commands in a sandbox and read their output.",
|
|
12852
|
+
"sandboxes containers": "Containers of a sandbox’s Docker engine.",
|
|
11964
12853
|
"sandboxes env": "Environment of one sandbox.",
|
|
11965
12854
|
"sandboxes files": "Files inside a sandbox.",
|
|
11966
12855
|
"sandboxes mcps": "MCP endpoints a sandbox exposes.",
|