@ornncompute/cli 0.2.21 → 0.2.23
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 +0 -3
- package/package.json +1 -1
- package/src/cli.mjs +152 -122
- package/vendor/capabilities/capabilities/fleet.js +2 -2
- package/vendor/capabilities/capabilities/staff-gtm.d.ts +28 -57
- package/vendor/capabilities/capabilities/staff-gtm.js +71 -166
- package/vendor/capabilities/index.d.ts +1 -1
- package/vendor/capabilities/index.js +1 -1
package/README.md
CHANGED
|
@@ -137,9 +137,6 @@ ornn networks show <network-id> [--json]
|
|
|
137
137
|
ornn networks create --name <name> [--cidr <cidr>] [--description <text>] [--json]
|
|
138
138
|
ornn networks update <network-id> [--name <name>] [--description <text>] [--clear-description] [--json]
|
|
139
139
|
ornn networks delete <network-id> [--yes] [--json]
|
|
140
|
-
ornn networks reservation <reservation-id> [--json]
|
|
141
|
-
ornn networks attach <reservation-id> --network <network-id> [--json]
|
|
142
|
-
ornn networks detach <reservation-id> [--json]
|
|
143
140
|
ornn storage volumes list [--json]
|
|
144
141
|
ornn storage volumes show <drive-id> [--json]
|
|
145
142
|
ornn storage volumes create --name <name> [--source <drive-id>] [--json]
|
package/package.json
CHANGED
package/src/cli.mjs
CHANGED
|
@@ -214,9 +214,6 @@ Usage:
|
|
|
214
214
|
ornn networks create --name <name> [--cidr <cidr>] [--description <text>] [--json]
|
|
215
215
|
ornn networks update <network-id> [--name <name>] [--description <text>] [--clear-description] [--json]
|
|
216
216
|
ornn networks delete <network-id> [--yes] [--json]
|
|
217
|
-
ornn networks reservation <reservation-id> [--json]
|
|
218
|
-
ornn networks attach <reservation-id> --network <network-id> [--json]
|
|
219
|
-
ornn networks detach <reservation-id> [--json]
|
|
220
217
|
ornn storage volumes list [--json]
|
|
221
218
|
ornn storage files ls <drive-id> [--prefix <path>] [--json]
|
|
222
219
|
ornn storage files upload <drive-id> <local-file> [--destination <path>] [--content-type <type>] [--json]
|
|
@@ -3002,7 +2999,7 @@ function nodeOpUsage(subcommand) {
|
|
|
3002
2999
|
return `Usage: ornn node ${subcommand} <node-id> [--json]`;
|
|
3003
3000
|
}
|
|
3004
3001
|
|
|
3005
|
-
// Catalog: @ornn/capabilities fleet.nodes.list → GET /
|
|
3002
|
+
// Catalog: @ornn/capabilities fleet.nodes.list → GET /nodes
|
|
3006
3003
|
async function nodeOpList(rest, context) {
|
|
3007
3004
|
const options = parseCommandOptions(
|
|
3008
3005
|
rest,
|
|
@@ -3133,11 +3130,15 @@ async function resolveNodeInstanceId(nodeId, context) {
|
|
|
3133
3130
|
throw new CliApiError(`Node ${nodeId} has no assigned reservation to reboot.`);
|
|
3134
3131
|
}
|
|
3135
3132
|
const machines = await operatorRequest({
|
|
3136
|
-
endpoint: `/v1/orchestrator/nodes
|
|
3133
|
+
endpoint: `/v1/orchestrator/internal/nodes?reservation_id=${encodeURIComponent(reservationId)}`,
|
|
3137
3134
|
env: context.env,
|
|
3138
3135
|
fetchImpl: context.fetchImpl,
|
|
3139
3136
|
});
|
|
3140
|
-
const rows = Array.isArray(machines?.
|
|
3137
|
+
const rows = Array.isArray(machines?.nodes)
|
|
3138
|
+
? machines.nodes
|
|
3139
|
+
: Array.isArray(machines?.machines)
|
|
3140
|
+
? machines.machines
|
|
3141
|
+
: [];
|
|
3141
3142
|
const nodeRefs = new Set(
|
|
3142
3143
|
[nodeId, node?.id, node?.k8s_node_name]
|
|
3143
3144
|
.filter((value) => value !== null && value !== undefined && String(value) !== "")
|
|
@@ -3151,7 +3152,7 @@ async function resolveNodeInstanceId(nodeId, context) {
|
|
|
3151
3152
|
`Multiple live machines found for node ${nodeId} (reservation ${reservationId}).`
|
|
3152
3153
|
);
|
|
3153
3154
|
}
|
|
3154
|
-
const instanceId = matches[0]?.id;
|
|
3155
|
+
const instanceId = matches[0]?.node_id ?? matches[0]?.id;
|
|
3155
3156
|
if (!instanceId) {
|
|
3156
3157
|
throw new CliApiError(
|
|
3157
3158
|
`No live machine found for node ${nodeId} (reservation ${reservationId}).`
|
|
@@ -3370,7 +3371,7 @@ function writeNodeHealth(stdout, node) {
|
|
|
3370
3371
|
|
|
3371
3372
|
stdout.write(`Validation: ${node?.validation_status || "unknown"}\n`);
|
|
3372
3373
|
writeOptionalStatusLine(stdout, "Validation checked", node?.validation_checked_at);
|
|
3373
|
-
writeOptionalStatusLine(stdout, "Last heartbeat", node?.
|
|
3374
|
+
writeOptionalStatusLine(stdout, "Last heartbeat", node?.observed_at);
|
|
3374
3375
|
}
|
|
3375
3376
|
|
|
3376
3377
|
async function nodes(args, context) {
|
|
@@ -3706,10 +3707,11 @@ async function clusters(args, context) {
|
|
|
3706
3707
|
"Usage: ornn clusters list [--json]"
|
|
3707
3708
|
);
|
|
3708
3709
|
const rows = await fetchTenantClusters(context);
|
|
3710
|
+
const clusters = withNumberedClusterNames(requireArrayPayload(rows, "clusters"));
|
|
3709
3711
|
if (options.json) {
|
|
3710
|
-
writeJson(context.stdout,
|
|
3712
|
+
writeJson(context.stdout, clusters);
|
|
3711
3713
|
} else {
|
|
3712
|
-
writeClusterList(context.stdout,
|
|
3714
|
+
writeClusterList(context.stdout, clusters);
|
|
3713
3715
|
}
|
|
3714
3716
|
return 0;
|
|
3715
3717
|
}
|
|
@@ -3802,9 +3804,16 @@ async function clusters(args, context) {
|
|
|
3802
3804
|
const wait = options.wait
|
|
3803
3805
|
? await waitForClusterActive(selectedReservationId, type, waitOptions(options), context)
|
|
3804
3806
|
: null;
|
|
3805
|
-
const result = {
|
|
3807
|
+
const result = {
|
|
3808
|
+
cluster: withNumberedClusterName(launch, [launch]),
|
|
3809
|
+
reservation_id: selectedReservationId,
|
|
3810
|
+
type,
|
|
3811
|
+
wait: wait
|
|
3812
|
+
? { ...wait, cluster: withNumberedClusterName(wait.cluster, [wait.cluster]) }
|
|
3813
|
+
: null,
|
|
3814
|
+
};
|
|
3806
3815
|
if (options.json) {
|
|
3807
|
-
writeJson(context.stdout, result);
|
|
3816
|
+
writeJson(context.stdout, omitClusterName(result));
|
|
3808
3817
|
} else {
|
|
3809
3818
|
writeClusterLaunchResult(context.stdout, result);
|
|
3810
3819
|
writeNextStep(
|
|
@@ -3825,8 +3834,20 @@ async function clusters(args, context) {
|
|
|
3825
3834
|
{ boolean: ["json"], value: ["type", "mode"] },
|
|
3826
3835
|
"Usage: ornn clusters show <reservation-id> [--type kubernetes|slurm] [--json]"
|
|
3827
3836
|
);
|
|
3828
|
-
const
|
|
3829
|
-
|
|
3837
|
+
const listed = requireArrayPayload(await fetchTenantClusters(context), "clusters");
|
|
3838
|
+
let type;
|
|
3839
|
+
if (options.type || options.mode) {
|
|
3840
|
+
type = normalizeClusterType(options.type || options.mode);
|
|
3841
|
+
} else {
|
|
3842
|
+
const listedType = listed.find(
|
|
3843
|
+
(candidate) => String(candidate.reservation_id || "") === String(reservationId)
|
|
3844
|
+
)?.access_mode;
|
|
3845
|
+
if (!listedType) {
|
|
3846
|
+
throw new Error("--type is required when the cluster is not listed yet.");
|
|
3847
|
+
}
|
|
3848
|
+
type = normalizeClusterType(listedType);
|
|
3849
|
+
}
|
|
3850
|
+
const cluster = withNumberedClusterName(await fetchCluster(reservationId, type, context), listed);
|
|
3830
3851
|
if (options.json) {
|
|
3831
3852
|
writeJson(context.stdout, cluster);
|
|
3832
3853
|
} else {
|
|
@@ -3843,10 +3864,14 @@ async function clusters(args, context) {
|
|
|
3843
3864
|
);
|
|
3844
3865
|
const type = await resolveClusterTypeForReservation(reservationId, options, context);
|
|
3845
3866
|
const result = await waitForClusterActive(reservationId, type, waitOptions(options), context);
|
|
3867
|
+
const named = {
|
|
3868
|
+
...result,
|
|
3869
|
+
cluster: withNumberedClusterName(result.cluster, [result.cluster]),
|
|
3870
|
+
};
|
|
3846
3871
|
if (options.json) {
|
|
3847
|
-
writeJson(context.stdout,
|
|
3872
|
+
writeJson(context.stdout, omitClusterName(named));
|
|
3848
3873
|
} else {
|
|
3849
|
-
writeClusterWaitResult(context.stdout,
|
|
3874
|
+
writeClusterWaitResult(context.stdout, named);
|
|
3850
3875
|
}
|
|
3851
3876
|
return 0;
|
|
3852
3877
|
}
|
|
@@ -3952,13 +3977,14 @@ async function clusters(args, context) {
|
|
|
3952
3977
|
subcommand === "add-node"
|
|
3953
3978
|
? await addClusterNode(reservationId, nodeId, context)
|
|
3954
3979
|
: await removeClusterNode(reservationId, nodeId, context);
|
|
3980
|
+
const named = withNumberedClusterName(cluster, [cluster]);
|
|
3955
3981
|
if (options.json) {
|
|
3956
|
-
writeJson(context.stdout,
|
|
3982
|
+
writeJson(context.stdout, named);
|
|
3957
3983
|
} else {
|
|
3958
3984
|
context.stdout.write(
|
|
3959
3985
|
`Cluster node ${subcommand === "add-node" ? "add" : "remove"} queued.\n`
|
|
3960
3986
|
);
|
|
3961
|
-
writeClusterDetail(context.stdout,
|
|
3987
|
+
writeClusterDetail(context.stdout, named);
|
|
3962
3988
|
}
|
|
3963
3989
|
return 0;
|
|
3964
3990
|
}
|
|
@@ -3971,7 +3997,7 @@ async function clusters(args, context) {
|
|
|
3971
3997
|
);
|
|
3972
3998
|
if (!(await confirmClusterTeardown(options, context, reservationId))) return 1;
|
|
3973
3999
|
const type = await resolveClusterTypeForReservation(reservationId, options, context);
|
|
3974
|
-
const cluster = await teardownCluster(reservationId, type, context);
|
|
4000
|
+
const cluster = withNumberedClusterName(await teardownCluster(reservationId, type, context), []);
|
|
3975
4001
|
if (options.json) {
|
|
3976
4002
|
writeJson(context.stdout, cluster);
|
|
3977
4003
|
} else {
|
|
@@ -4002,9 +4028,16 @@ async function slurm(args, context) {
|
|
|
4002
4028
|
const wait = options.wait
|
|
4003
4029
|
? await waitForClusterActive(reservationId, "slurm", waitOptions(options), context)
|
|
4004
4030
|
: null;
|
|
4005
|
-
const result = {
|
|
4031
|
+
const result = {
|
|
4032
|
+
cluster: withNumberedClusterName(launch, [launch]),
|
|
4033
|
+
reservation_id: reservationId,
|
|
4034
|
+
type: "slurm",
|
|
4035
|
+
wait: wait
|
|
4036
|
+
? { ...wait, cluster: withNumberedClusterName(wait.cluster, [wait.cluster]) }
|
|
4037
|
+
: null,
|
|
4038
|
+
};
|
|
4006
4039
|
if (options.json) {
|
|
4007
|
-
writeJson(context.stdout, result);
|
|
4040
|
+
writeJson(context.stdout, omitClusterName(result));
|
|
4008
4041
|
} else {
|
|
4009
4042
|
writeClusterLaunchResult(context.stdout, result);
|
|
4010
4043
|
}
|
|
@@ -4018,7 +4051,10 @@ async function slurm(args, context) {
|
|
|
4018
4051
|
"Usage: ornn slurm teardown <reservation-id> [--yes] [--json]"
|
|
4019
4052
|
);
|
|
4020
4053
|
if (!(await confirmClusterTeardown(options, context, reservationId))) return 1;
|
|
4021
|
-
const cluster =
|
|
4054
|
+
const cluster = withNumberedClusterName(
|
|
4055
|
+
await teardownCluster(reservationId, "slurm", context),
|
|
4056
|
+
[]
|
|
4057
|
+
);
|
|
4022
4058
|
if (options.json) {
|
|
4023
4059
|
writeJson(context.stdout, cluster);
|
|
4024
4060
|
} else {
|
|
@@ -4034,7 +4070,7 @@ async function slurm(args, context) {
|
|
|
4034
4070
|
{ boolean: ["json"] },
|
|
4035
4071
|
"Usage: ornn slurm status <reservation-id> [--json]"
|
|
4036
4072
|
);
|
|
4037
|
-
const cluster = await fetchCluster(reservationId, "slurm", context);
|
|
4073
|
+
const cluster = withNumberedClusterName(await fetchCluster(reservationId, "slurm", context), []);
|
|
4038
4074
|
if (options.json) {
|
|
4039
4075
|
writeJson(context.stdout, cluster);
|
|
4040
4076
|
} else {
|
|
@@ -4100,9 +4136,16 @@ async function kubernetes(args, context) {
|
|
|
4100
4136
|
const wait = options.wait
|
|
4101
4137
|
? await waitForClusterActive(reservationId, "kubernetes", waitOptions(options), context)
|
|
4102
4138
|
: null;
|
|
4103
|
-
const result = {
|
|
4139
|
+
const result = {
|
|
4140
|
+
cluster: withNumberedClusterName(launch, [launch]),
|
|
4141
|
+
reservation_id: reservationId,
|
|
4142
|
+
type: "kubernetes",
|
|
4143
|
+
wait: wait
|
|
4144
|
+
? { ...wait, cluster: withNumberedClusterName(wait.cluster, [wait.cluster]) }
|
|
4145
|
+
: null,
|
|
4146
|
+
};
|
|
4104
4147
|
if (options.json) {
|
|
4105
|
-
writeJson(context.stdout, result);
|
|
4148
|
+
writeJson(context.stdout, omitClusterName(result));
|
|
4106
4149
|
} else {
|
|
4107
4150
|
writeClusterLaunchResult(context.stdout, result);
|
|
4108
4151
|
}
|
|
@@ -4116,7 +4159,10 @@ async function kubernetes(args, context) {
|
|
|
4116
4159
|
"Usage: ornn kubernetes teardown <reservation-id> [--yes] [--json]"
|
|
4117
4160
|
);
|
|
4118
4161
|
if (!(await confirmClusterTeardown(options, context, reservationId))) return 1;
|
|
4119
|
-
const cluster =
|
|
4162
|
+
const cluster = withNumberedClusterName(
|
|
4163
|
+
await teardownCluster(reservationId, "kubernetes", context),
|
|
4164
|
+
[]
|
|
4165
|
+
);
|
|
4120
4166
|
if (options.json) {
|
|
4121
4167
|
writeJson(context.stdout, cluster);
|
|
4122
4168
|
} else {
|
|
@@ -4132,7 +4178,10 @@ async function kubernetes(args, context) {
|
|
|
4132
4178
|
{ boolean: ["json"] },
|
|
4133
4179
|
"Usage: ornn kubernetes status <reservation-id> [--json]"
|
|
4134
4180
|
);
|
|
4135
|
-
const cluster =
|
|
4181
|
+
const cluster = withNumberedClusterName(
|
|
4182
|
+
await fetchCluster(reservationId, "kubernetes", context),
|
|
4183
|
+
[]
|
|
4184
|
+
);
|
|
4136
4185
|
if (options.json) {
|
|
4137
4186
|
writeJson(context.stdout, cluster);
|
|
4138
4187
|
} else {
|
|
@@ -4326,71 +4375,11 @@ async function networks(args, context) {
|
|
|
4326
4375
|
return 0;
|
|
4327
4376
|
}
|
|
4328
4377
|
|
|
4329
|
-
if (subcommand === "reservation"
|
|
4330
|
-
|
|
4331
|
-
rest,
|
|
4332
|
-
{ boolean: ["json"] },
|
|
4333
|
-
"Usage: ornn networks reservation <reservation-id> [--json]"
|
|
4334
|
-
);
|
|
4335
|
-
const payload = await cliRequest({
|
|
4336
|
-
endpoint: `/v1/workflows/compute/nodes/reservations/${encodeURIComponent(id)}/network`,
|
|
4337
|
-
env: context.env,
|
|
4338
|
-
fetchImpl: context.fetchImpl,
|
|
4339
|
-
});
|
|
4340
|
-
if (options.json) {
|
|
4341
|
-
writeJson(context.stdout, payload);
|
|
4342
|
-
} else {
|
|
4343
|
-
writeReservationNetwork(context.stdout, payload);
|
|
4344
|
-
}
|
|
4345
|
-
return 0;
|
|
4346
|
-
}
|
|
4347
|
-
|
|
4348
|
-
if (subcommand === "attach" && id) {
|
|
4349
|
-
const options = parseCommandOptions(
|
|
4350
|
-
rest,
|
|
4351
|
-
{ boolean: ["json"], value: ["network", "network-id"] },
|
|
4352
|
-
"Usage: ornn networks attach <reservation-id> --network <network-id> [--json]"
|
|
4353
|
-
);
|
|
4354
|
-
const networkId = requiredOption(options.network || options.networkId, "--network");
|
|
4355
|
-
const payload = await cliRequest({
|
|
4356
|
-
body: { network_id: networkId },
|
|
4357
|
-
endpoint: `/v1/workflows/compute/nodes/reservations/${encodeURIComponent(id)}/network`,
|
|
4358
|
-
env: context.env,
|
|
4359
|
-
fetchImpl: context.fetchImpl,
|
|
4360
|
-
method: "POST",
|
|
4361
|
-
});
|
|
4362
|
-
if (options.json) {
|
|
4363
|
-
writeJson(context.stdout, payload);
|
|
4364
|
-
} else {
|
|
4365
|
-
writeColored(context.stdout, "green", "Reservation network attached.");
|
|
4366
|
-
writeReservationNetwork(context.stdout, payload);
|
|
4367
|
-
}
|
|
4368
|
-
return 0;
|
|
4369
|
-
}
|
|
4370
|
-
|
|
4371
|
-
if (subcommand === "detach" && id) {
|
|
4372
|
-
const options = parseCommandOptions(
|
|
4373
|
-
rest,
|
|
4374
|
-
{ boolean: ["json"] },
|
|
4375
|
-
"Usage: ornn networks detach <reservation-id> [--json]"
|
|
4376
|
-
);
|
|
4377
|
-
const payload = await cliRequest({
|
|
4378
|
-
body: { network_id: null },
|
|
4379
|
-
endpoint: `/v1/workflows/compute/nodes/reservations/${encodeURIComponent(id)}/network`,
|
|
4380
|
-
env: context.env,
|
|
4381
|
-
fetchImpl: context.fetchImpl,
|
|
4382
|
-
method: "POST",
|
|
4383
|
-
});
|
|
4384
|
-
if (options.json) {
|
|
4385
|
-
writeJson(context.stdout, payload);
|
|
4386
|
-
} else {
|
|
4387
|
-
writeColored(context.stdout, "green", "Reservation network detached.");
|
|
4388
|
-
writeReservationNetwork(context.stdout, payload);
|
|
4389
|
-
}
|
|
4390
|
-
return 0;
|
|
4378
|
+
if (subcommand === "reservation" || subcommand === "attach" || subcommand === "detach") {
|
|
4379
|
+
throw new Error("network_attach_removed");
|
|
4391
4380
|
}
|
|
4392
4381
|
|
|
4393
|
-
throw new Error("Usage: ornn networks list|show|create|update|delete
|
|
4382
|
+
throw new Error("Usage: ornn networks list|show|create|update|delete");
|
|
4394
4383
|
}
|
|
4395
4384
|
|
|
4396
4385
|
function normalizeStorageDestination(value) {
|
|
@@ -6061,6 +6050,8 @@ function inventoryAvailableGpuCount(record) {
|
|
|
6061
6050
|
function normalizeInventoryListing(record) {
|
|
6062
6051
|
const gpuCount = inventoryAvailableGpuCount(record);
|
|
6063
6052
|
const facility = record.site_nickname ?? record.facility ?? record.site ?? "Unknown facility";
|
|
6053
|
+
// Customer availability never exposes real supplier/operator identity.
|
|
6054
|
+
// Display branding stays in the text formatter, not on the JSON envelope.
|
|
6064
6055
|
return {
|
|
6065
6056
|
id: record.id,
|
|
6066
6057
|
kind: "inventory",
|
|
@@ -6855,13 +6846,21 @@ async function resolveStorageMountUsers(attachment, context) {
|
|
|
6855
6846
|
return users.size ? users : null;
|
|
6856
6847
|
}
|
|
6857
6848
|
|
|
6849
|
+
function reservationHostsFromPayload(payload) {
|
|
6850
|
+
if (Array.isArray(payload)) return payload;
|
|
6851
|
+
if (Array.isArray(payload?.nodes)) return payload.nodes;
|
|
6852
|
+
if (Array.isArray(payload?.machines)) return payload.machines;
|
|
6853
|
+
return [];
|
|
6854
|
+
}
|
|
6855
|
+
|
|
6858
6856
|
async function getReservationMachines(reservationId, context) {
|
|
6859
6857
|
const payload = await cliRequest({
|
|
6860
|
-
endpoint: `/v1/workflows/compute/nodes
|
|
6858
|
+
endpoint: `/v1/workflows/compute/nodes?reservation_id=${encodeURIComponent(reservationId)}`,
|
|
6861
6859
|
env: context.env,
|
|
6862
6860
|
fetchImpl: context.fetchImpl,
|
|
6863
6861
|
});
|
|
6864
|
-
|
|
6862
|
+
const nodes = reservationHostsFromPayload(payload);
|
|
6863
|
+
return { ...(payload && typeof payload === "object" ? payload : {}), machines: nodes };
|
|
6865
6864
|
}
|
|
6866
6865
|
|
|
6867
6866
|
async function fetchBillingInvoices(context) {
|
|
@@ -6967,13 +6966,6 @@ async function launchReservationAccess(
|
|
|
6967
6966
|
"--storage-save-drive-id"
|
|
6968
6967
|
);
|
|
6969
6968
|
}
|
|
6970
|
-
const access = await cliRequest({
|
|
6971
|
-
body: { access_mode: mode, image_id: null },
|
|
6972
|
-
endpoint: `/v1/workflows/commerce/reservations/${reservationId}/access-mode`,
|
|
6973
|
-
env: context.env,
|
|
6974
|
-
fetchImpl: context.fetchImpl,
|
|
6975
|
-
method: "POST",
|
|
6976
|
-
});
|
|
6977
6969
|
const launch = await cliRequest({
|
|
6978
6970
|
body: launchPayload,
|
|
6979
6971
|
endpoint: `/v1/workflows/compute/nodes/reservations/${reservationId}/launch`,
|
|
@@ -6992,7 +6984,7 @@ async function launchReservationAccess(
|
|
|
6992
6984
|
? await waitForSshReady(reservationId, waitOptions(options), context)
|
|
6993
6985
|
: null;
|
|
6994
6986
|
return {
|
|
6995
|
-
access,
|
|
6987
|
+
access: launch,
|
|
6996
6988
|
launch,
|
|
6997
6989
|
mode,
|
|
6998
6990
|
opened,
|
|
@@ -7027,7 +7019,7 @@ async function switchReservationAccess(reservationId, options, context) {
|
|
|
7027
7019
|
fetchImpl: context.fetchImpl,
|
|
7028
7020
|
method: "POST",
|
|
7029
7021
|
});
|
|
7030
|
-
const machines =
|
|
7022
|
+
const machines = reservationHostsFromPayload(switched);
|
|
7031
7023
|
const wait = options.wait
|
|
7032
7024
|
? await waitForSshReady(reservationId, waitOptions(options), context)
|
|
7033
7025
|
: null;
|
|
@@ -7045,7 +7037,7 @@ async function switchReservationAccess(reservationId, options, context) {
|
|
|
7045
7037
|
|
|
7046
7038
|
function accessActivateJsonResult(result) {
|
|
7047
7039
|
return {
|
|
7048
|
-
access: result.
|
|
7040
|
+
access: { access_mode: result.mode },
|
|
7049
7041
|
launch: result.launch,
|
|
7050
7042
|
opened: Boolean(result.opened?.opened),
|
|
7051
7043
|
url: result.opened?.url ?? null,
|
|
@@ -7062,11 +7054,11 @@ async function fetchTenantClusters(context) {
|
|
|
7062
7054
|
|
|
7063
7055
|
async function fetchEligibleClusterNodes(reservationId, type, networkMode, context) {
|
|
7064
7056
|
const payload = await cliRequest({
|
|
7065
|
-
endpoint: `/v1/workflows/compute/nodes
|
|
7057
|
+
endpoint: `/v1/workflows/compute/nodes?reservation_id=${encodeURIComponent(reservationId)}`,
|
|
7066
7058
|
env: context.env,
|
|
7067
7059
|
fetchImpl: context.fetchImpl,
|
|
7068
7060
|
});
|
|
7069
|
-
const machines =
|
|
7061
|
+
const machines = reservationHostsFromPayload(payload);
|
|
7070
7062
|
return {
|
|
7071
7063
|
reservation_id: reservationId,
|
|
7072
7064
|
access_mode: type,
|
|
@@ -7803,7 +7795,7 @@ function writeAccessDetail(stdout, payload = {}) {
|
|
|
7803
7795
|
}
|
|
7804
7796
|
|
|
7805
7797
|
function writeAccessLaunchSummary(stdout, launch = {}) {
|
|
7806
|
-
const machines =
|
|
7798
|
+
const machines = reservationHostsFromPayload(launch);
|
|
7807
7799
|
if (!machines.length) {
|
|
7808
7800
|
stdout.write("Provisioning response received.\n");
|
|
7809
7801
|
return;
|
|
@@ -8011,18 +8003,6 @@ function writeNetworkDetail(stdout, network = {}) {
|
|
|
8011
8003
|
writeOptionalStatusLine(stdout, "Updated", network.updated_at);
|
|
8012
8004
|
}
|
|
8013
8005
|
|
|
8014
|
-
function writeReservationNetwork(stdout, payload = {}) {
|
|
8015
|
-
stdout.write(`${payload.reservation_id || "reservation"}\n`);
|
|
8016
|
-
if (!payload.network_id || !payload.network) {
|
|
8017
|
-
stdout.write("Network: shared\n");
|
|
8018
|
-
return;
|
|
8019
|
-
}
|
|
8020
|
-
stdout.write(`Network: ${payload.network.name || payload.network_id}\n`);
|
|
8021
|
-
stdout.write(`Network ID: ${payload.network_id}\n`);
|
|
8022
|
-
writeOptionalStatusLine(stdout, "CIDR", payload.network.cidr);
|
|
8023
|
-
writeOptionalStatusLine(stdout, "Status", payload.network.status);
|
|
8024
|
-
}
|
|
8025
|
-
|
|
8026
8006
|
function writeReservationStorageAttachment(stdout, attachment = {}, options = {}) {
|
|
8027
8007
|
if (!attachment) {
|
|
8028
8008
|
stdout.write("No volume is attached to this reservation.\n");
|
|
@@ -8950,10 +8930,10 @@ function metricSnapshotFromLivePayload(fallbackMachine, payload = {}) {
|
|
|
8950
8930
|
function metricSnapshotFromMachine(machine, extras = {}) {
|
|
8951
8931
|
const resourceMetrics = machine.resource_metrics || machine.resourceMetrics || {};
|
|
8952
8932
|
const lastHeartbeatAt =
|
|
8933
|
+
machine.observed_at ||
|
|
8934
|
+
resourceMetrics.observed_at ||
|
|
8953
8935
|
resourceMetrics.last_heartbeat_at ||
|
|
8954
8936
|
resourceMetrics.lastHeartbeatAt ||
|
|
8955
|
-
machine.last_heartbeat_at ||
|
|
8956
|
-
machine.lastHeartbeatAt ||
|
|
8957
8937
|
null;
|
|
8958
8938
|
return {
|
|
8959
8939
|
connection_status:
|
|
@@ -9033,6 +9013,51 @@ function writeWaitResult(stdout, result) {
|
|
|
9033
9013
|
stdout.write(`SSH: ${result.command}\n`);
|
|
9034
9014
|
}
|
|
9035
9015
|
|
|
9016
|
+
function clusterIdentity(cluster) {
|
|
9017
|
+
return String(cluster?.controller_id || cluster?.id || cluster?.reservation_id || "").trim();
|
|
9018
|
+
}
|
|
9019
|
+
|
|
9020
|
+
function numberedClusterName(clusters, target) {
|
|
9021
|
+
const ordered = [...clusters].sort((left, right) => {
|
|
9022
|
+
const leftCreatedAt = Date.parse(left.created_at ?? "");
|
|
9023
|
+
const rightCreatedAt = Date.parse(right.created_at ?? "");
|
|
9024
|
+
const leftTime = Number.isFinite(leftCreatedAt) ? leftCreatedAt : Number.MAX_SAFE_INTEGER;
|
|
9025
|
+
const rightTime = Number.isFinite(rightCreatedAt) ? rightCreatedAt : Number.MAX_SAFE_INTEGER;
|
|
9026
|
+
return leftTime - rightTime || clusterIdentity(left).localeCompare(clusterIdentity(right));
|
|
9027
|
+
});
|
|
9028
|
+
const index = ordered.findIndex((cluster) => clusterIdentity(cluster) === clusterIdentity(target));
|
|
9029
|
+
return `Cluster ${index >= 0 ? index + 1 : 1}`;
|
|
9030
|
+
}
|
|
9031
|
+
|
|
9032
|
+
function omitClusterName(value) {
|
|
9033
|
+
if (Array.isArray(value)) {
|
|
9034
|
+
return value.map(omitClusterName);
|
|
9035
|
+
}
|
|
9036
|
+
if (!value || typeof value !== "object") {
|
|
9037
|
+
return value;
|
|
9038
|
+
}
|
|
9039
|
+
const { cluster_name: _ignored, ...rest } = value;
|
|
9040
|
+
if ("cluster" in rest) {
|
|
9041
|
+
rest.cluster = omitClusterName(rest.cluster);
|
|
9042
|
+
}
|
|
9043
|
+
if (rest.wait && typeof rest.wait === "object") {
|
|
9044
|
+
rest.wait = omitClusterName(rest.wait);
|
|
9045
|
+
}
|
|
9046
|
+
return rest;
|
|
9047
|
+
}
|
|
9048
|
+
|
|
9049
|
+
function withNumberedClusterName(cluster, siblings) {
|
|
9050
|
+
const rows = siblings.length ? siblings : [cluster];
|
|
9051
|
+
return {
|
|
9052
|
+
...omitClusterName(cluster),
|
|
9053
|
+
name: numberedClusterName(rows, cluster),
|
|
9054
|
+
};
|
|
9055
|
+
}
|
|
9056
|
+
|
|
9057
|
+
function withNumberedClusterNames(clusters) {
|
|
9058
|
+
return clusters.map((cluster) => withNumberedClusterName(cluster, clusters));
|
|
9059
|
+
}
|
|
9060
|
+
|
|
9036
9061
|
function writeClusterList(stdout, clusters) {
|
|
9037
9062
|
if (!clusters.length) {
|
|
9038
9063
|
stdout.write("No clusters found.\n");
|
|
@@ -9067,7 +9092,7 @@ function writeClusterList(stdout, clusters) {
|
|
|
9067
9092
|
stdout.write("Clusters:\n");
|
|
9068
9093
|
for (const cluster of clusters) {
|
|
9069
9094
|
stdout.write(
|
|
9070
|
-
`- ${cluster.reservation_id || cluster.id || "cluster"} ${displayClusterType(cluster.access_mode)} ${cluster.state || "unknown"}`
|
|
9095
|
+
`- ${cluster.name || numberedClusterName(clusters, cluster)} ${cluster.reservation_id || cluster.id || "cluster"} ${displayClusterType(cluster.access_mode)} ${cluster.state || "unknown"}`
|
|
9071
9096
|
);
|
|
9072
9097
|
stdout.write(` ${cluster.node_count ?? "?"} nodes/${cluster.gpu_count ?? "?"} GPUs`);
|
|
9073
9098
|
stdout.write(` network=${cluster.network_mode || "public"}`);
|
|
@@ -9157,13 +9182,13 @@ function writeEligibleClusterNodes(stdout, payload) {
|
|
|
9157
9182
|
|
|
9158
9183
|
function writeClusterDetail(stdout, cluster = {}) {
|
|
9159
9184
|
stdout.write(`${cluster.reservation_id || cluster.id || "cluster"}\n`);
|
|
9185
|
+
stdout.write(`Name: ${cluster.name || numberedClusterName([cluster], cluster)}\n`);
|
|
9160
9186
|
stdout.write(`Type: ${displayClusterType(cluster.access_mode)}\n`);
|
|
9161
9187
|
stdout.write(`State: ${cluster.state || "unknown"}\n`);
|
|
9162
9188
|
stdout.write(`Network: ${cluster.network_mode || "public"}\n`);
|
|
9163
9189
|
stdout.write(`Nodes: ${cluster.node_count ?? "unknown"}\n`);
|
|
9164
9190
|
stdout.write(`GPUs: ${cluster.gpu_count ?? "unknown"}\n`);
|
|
9165
9191
|
writeOptionalStatusLine(stdout, "GPU type", cluster.gpu_type);
|
|
9166
|
-
writeOptionalStatusLine(stdout, "Name", cluster.cluster_name);
|
|
9167
9192
|
writeOptionalStatusLine(stdout, "Endpoint", cluster.endpoint);
|
|
9168
9193
|
writeOptionalStatusLine(stdout, "Namespace", cluster.namespace);
|
|
9169
9194
|
writeOptionalStatusLine(stdout, "Credentials", cluster.credential_state);
|
|
@@ -9635,7 +9660,12 @@ function looksLikePublicKey(value) {
|
|
|
9635
9660
|
function looksLikePath(value) {
|
|
9636
9661
|
const text = String(value || "").trim();
|
|
9637
9662
|
return (
|
|
9638
|
-
text.startsWith("~") ||
|
|
9663
|
+
text.startsWith("~") ||
|
|
9664
|
+
text.startsWith(".") ||
|
|
9665
|
+
text.includes("/") ||
|
|
9666
|
+
text.includes("\\") ||
|
|
9667
|
+
/^[A-Za-z]:/.test(text) ||
|
|
9668
|
+
text.endsWith(".pub")
|
|
9639
9669
|
);
|
|
9640
9670
|
}
|
|
9641
9671
|
|
|
@@ -79,7 +79,7 @@ export const listNodesCapability = defineCapability({
|
|
|
79
79
|
roles: ["user", "reviewer", "admin"],
|
|
80
80
|
description: "List nodes. Users see their own reserved machines. Reviewers and admins see enrolled, ghost, and off-grid nodes. Call with no filters for the whole fleet. Optional email lists nodes for that user's organizations. Optional operator_id, facility_id, and status (ghost, off-grid, bare-metal) narrow the same list. Never invent nodes. Never print private keys.",
|
|
81
81
|
mutation: "read",
|
|
82
|
-
http: { method: "GET", path: "/
|
|
82
|
+
http: { method: "GET", path: "/nodes" },
|
|
83
83
|
slack: {
|
|
84
84
|
parameters: {
|
|
85
85
|
type: "object",
|
|
@@ -107,7 +107,7 @@ export const listNodesCapability = defineCapability({
|
|
|
107
107
|
if (ctx.role === "user") {
|
|
108
108
|
return ctx.fetch("/nodes", { method: "GET" });
|
|
109
109
|
}
|
|
110
|
-
return ctx.fetch(queryPath("/
|
|
110
|
+
return ctx.fetch(queryPath("/nodes", {
|
|
111
111
|
operator_id: parsed.operator_id ?? parsed.operatorId ?? parsed.operator,
|
|
112
112
|
facility_id: parsed.facility_id ?? parsed.facilityId,
|
|
113
113
|
status: parsed.status,
|
|
@@ -18,36 +18,42 @@ export declare const gtmDealListInput: z.ZodObject<{
|
|
|
18
18
|
}, z.core.$strip>;
|
|
19
19
|
export declare const gtmDealListCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
20
20
|
export declare const gtmDealWriteInput: z.ZodObject<{
|
|
21
|
-
listingId: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<"">]>>;
|
|
22
|
-
currentBid: z.ZodOptional<z.ZodString>;
|
|
23
|
-
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
-
customer: z.ZodString;
|
|
25
|
-
owner: z.ZodString;
|
|
26
|
-
supplier: z.ZodString;
|
|
27
|
-
gpuType: z.ZodString;
|
|
28
21
|
dealId: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
listingId: z.ZodOptional<z.ZodString>;
|
|
23
|
+
customer: z.ZodOptional<z.ZodString>;
|
|
24
|
+
owner: z.ZodOptional<z.ZodString>;
|
|
25
|
+
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
29
26
|
}, z.core.$strip>;
|
|
30
27
|
export declare const gtmDealWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
31
28
|
export declare const gtmCommentListInput: z.ZodObject<{
|
|
32
29
|
dealId: z.ZodOptional<z.ZodNumber>;
|
|
33
30
|
companyId: z.ZodOptional<z.ZodNumber>;
|
|
31
|
+
taskId: z.ZodOptional<z.ZodNumber>;
|
|
32
|
+
field: z.ZodOptional<z.ZodEnum<{
|
|
33
|
+
name: "name";
|
|
34
|
+
notes: "notes";
|
|
35
|
+
owner_tags: "owner_tags";
|
|
36
|
+
tickets: "tickets";
|
|
37
|
+
}>>;
|
|
34
38
|
}, z.core.$strip>;
|
|
35
39
|
export declare const gtmCommentListCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
36
40
|
export declare const gtmCommentWriteInput: z.ZodObject<{
|
|
37
|
-
dealId: z.ZodOptional<z.ZodNumber>;
|
|
38
|
-
companyId: z.ZodOptional<z.ZodNumber>;
|
|
39
41
|
commentId: z.ZodOptional<z.ZodNumber>;
|
|
40
42
|
parentId: z.ZodOptional<z.ZodNumber>;
|
|
41
43
|
body: z.ZodString;
|
|
42
44
|
bid: z.ZodDefault<z.ZodBoolean>;
|
|
43
45
|
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
46
|
+
dealId: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
companyId: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
taskId: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
field: z.ZodOptional<z.ZodEnum<{
|
|
50
|
+
name: "name";
|
|
51
|
+
notes: "notes";
|
|
52
|
+
owner_tags: "owner_tags";
|
|
53
|
+
tickets: "tickets";
|
|
54
|
+
}>>;
|
|
44
55
|
}, z.core.$strip>;
|
|
45
56
|
export declare const gtmCommentWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
46
|
-
export declare const gtmMentionDismissInput: z.ZodObject<{
|
|
47
|
-
commentId: z.ZodNumber;
|
|
48
|
-
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
49
|
-
}, z.core.$strip>;
|
|
50
|
-
export declare const gtmMentionDismissCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
51
57
|
export declare const gtmWorkspaceShowInput: z.ZodObject<{}, z.core.$strip>;
|
|
52
58
|
export declare const gtmWorkspaceShowCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
53
59
|
export declare const gtmTaskListInput: z.ZodObject<{
|
|
@@ -74,11 +80,6 @@ export declare const gtmCompanyDeleteInput: z.ZodObject<{
|
|
|
74
80
|
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
75
81
|
}, z.core.$strip>;
|
|
76
82
|
export declare const gtmCompanyDeleteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
77
|
-
export declare const gtmDealDeleteInput: z.ZodObject<{
|
|
78
|
-
[x: string]: z.ZodNumber | z.ZodOptional<z.ZodBoolean>;
|
|
79
|
-
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
-
}, z.core.$strip>;
|
|
81
|
-
export declare const gtmDealDeleteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
82
83
|
export declare const gtmCommentDeleteInput: z.ZodObject<{
|
|
83
84
|
[x: string]: z.ZodNumber | z.ZodOptional<z.ZodBoolean>;
|
|
84
85
|
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -97,7 +98,13 @@ export declare const gtmTaskDeleteCapability: import("../capability.ts").Capabil
|
|
|
97
98
|
*/
|
|
98
99
|
export declare const gtmListingListInput: z.ZodObject<{
|
|
99
100
|
gpuType: z.ZodOptional<z.ZodString>;
|
|
101
|
+
state: z.ZodOptional<z.ZodEnum<{
|
|
102
|
+
delisted: "delisted";
|
|
103
|
+
available: "available";
|
|
104
|
+
internal: "internal";
|
|
105
|
+
}>>;
|
|
100
106
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
107
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
101
108
|
}, z.core.$strip>;
|
|
102
109
|
export declare const gtmListingListCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
103
110
|
export declare const gtmListingUpdateInput: z.ZodObject<{
|
|
@@ -110,8 +117,8 @@ export declare const gtmListingUpdateInput: z.ZodObject<{
|
|
|
110
117
|
capacityNodes: z.ZodOptional<z.ZodNumber>;
|
|
111
118
|
state: z.ZodOptional<z.ZodEnum<{
|
|
112
119
|
delisted: "delisted";
|
|
113
|
-
|
|
114
|
-
|
|
120
|
+
available: "available";
|
|
121
|
+
internal: "internal";
|
|
115
122
|
}>>;
|
|
116
123
|
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
117
124
|
}, z.core.$strip>;
|
|
@@ -120,42 +127,6 @@ export declare const gtmTaskActivityListInput: z.ZodObject<{
|
|
|
120
127
|
taskId: z.ZodNumber;
|
|
121
128
|
}, z.core.$strip>;
|
|
122
129
|
export declare const gtmTaskActivityListCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
123
|
-
export declare const gtmTaskActivityWriteInput: z.ZodObject<{
|
|
124
|
-
taskId: z.ZodNumber;
|
|
125
|
-
body: z.ZodString;
|
|
126
|
-
parentId: z.ZodOptional<z.ZodNumber>;
|
|
127
|
-
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
128
|
-
}, z.core.$strip>;
|
|
129
|
-
export declare const gtmTaskActivityWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
130
|
-
export declare const gtmCellCommentListInput: z.ZodObject<{
|
|
131
|
-
companyId: z.ZodNumber;
|
|
132
|
-
field: z.ZodEnum<{
|
|
133
|
-
name: "name";
|
|
134
|
-
notes: "notes";
|
|
135
|
-
owner_tags: "owner_tags";
|
|
136
|
-
tickets: "tickets";
|
|
137
|
-
}>;
|
|
138
|
-
}, z.core.$strip>;
|
|
139
|
-
export declare const gtmCellCommentListCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
140
|
-
export declare const gtmCellCommentWriteInput: z.ZodObject<{
|
|
141
|
-
companyId: z.ZodOptional<z.ZodNumber>;
|
|
142
|
-
field: z.ZodOptional<z.ZodEnum<{
|
|
143
|
-
name: "name";
|
|
144
|
-
notes: "notes";
|
|
145
|
-
owner_tags: "owner_tags";
|
|
146
|
-
tickets: "tickets";
|
|
147
|
-
}>>;
|
|
148
|
-
commentId: z.ZodOptional<z.ZodNumber>;
|
|
149
|
-
parentId: z.ZodOptional<z.ZodNumber>;
|
|
150
|
-
body: z.ZodString;
|
|
151
|
-
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
152
|
-
}, z.core.$strip>;
|
|
153
|
-
export declare const gtmCellCommentWriteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
154
|
-
export declare const gtmCellCommentDeleteInput: z.ZodObject<{
|
|
155
|
-
[x: string]: z.ZodNumber | z.ZodOptional<z.ZodBoolean>;
|
|
156
|
-
confirm: z.ZodOptional<z.ZodBoolean>;
|
|
157
|
-
}, z.core.$strip>;
|
|
158
|
-
export declare const gtmCellCommentDeleteCapability: import("../capability.ts").Capability<unknown, unknown>;
|
|
159
130
|
/**
|
|
160
131
|
* Bulk owner-tag reassignment. This is the one GTM edit that is genuinely
|
|
161
132
|
* N-at-a-time — a book of companies moving to a new owner — and doing it one
|
|
@@ -59,12 +59,6 @@ export const gtmCompanyWriteCapability = defineStaffMcpCapability({
|
|
|
59
59
|
: "/internal/v1/gtm/companies", { method: parsed.companyId ? "PATCH" : "POST", body });
|
|
60
60
|
},
|
|
61
61
|
});
|
|
62
|
-
const dealFields = {
|
|
63
|
-
customer: z.string().min(1),
|
|
64
|
-
owner: z.string().min(1),
|
|
65
|
-
supplier: z.string().min(1),
|
|
66
|
-
gpuType: z.string().min(1),
|
|
67
|
-
};
|
|
68
62
|
export const gtmDealListInput = z.object({ ...listFilterFields });
|
|
69
63
|
export const gtmDealListCapability = defineStaffMcpCapability({
|
|
70
64
|
id: "gtm.deal.list",
|
|
@@ -80,34 +74,40 @@ export const gtmDealListCapability = defineStaffMcpCapability({
|
|
|
80
74
|
});
|
|
81
75
|
export const gtmDealWriteInput = z.object({
|
|
82
76
|
dealId: z.number().int().positive().optional(),
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
/** Required to create: a deal is that Commerce listing's GTM record. Cannot change. */
|
|
78
|
+
listingId: z.string().uuid().optional(),
|
|
79
|
+
/** Optional extras, unspecified until filled in. "" clears one. */
|
|
80
|
+
customer: z.string().optional(),
|
|
81
|
+
owner: z.string().optional(),
|
|
88
82
|
confirm: z.boolean().optional(),
|
|
89
83
|
});
|
|
90
84
|
export const gtmDealWriteCapability = defineStaffMcpCapability({
|
|
91
85
|
id: "gtm.deal.write",
|
|
92
86
|
domain: "gtm",
|
|
93
87
|
roles: ["reviewer", "admin"],
|
|
94
|
-
description: 'GTM staff only:
|
|
88
|
+
description: 'GTM staff only: a deal is the GTM record of one Commerce listing, and its comments hang off it. Create one with listingId (one deal per listing; a second is a conflict), or update one with dealId. customer and owner are optional; on update only the fields you pass change, and "" clears one. The listing cannot change. A bid is a comment with bid: true (see comment_write); the newest one is the current bid. Requires confirm: true.',
|
|
95
89
|
mutation: "preview-confirm",
|
|
96
90
|
http: { method: "POST", path: "/internal/v1/gtm/deals" },
|
|
97
91
|
input: gtmDealWriteInput,
|
|
98
92
|
execute: async (ctx, input) => {
|
|
99
93
|
const parsed = gtmDealWriteInput.parse(input);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
94
|
+
if (parsed.dealId === undefined && parsed.listingId === undefined) {
|
|
95
|
+
throw new Error("listingId is required to create a deal");
|
|
96
|
+
}
|
|
97
|
+
if (parsed.dealId !== undefined && parsed.listingId !== undefined) {
|
|
98
|
+
throw new Error("a deal's listing cannot change; omit listingId when updating");
|
|
99
|
+
}
|
|
100
|
+
// Only what the caller passed is sent: omitted is unspecified on create
|
|
101
|
+
// and untouched on update; "" clears.
|
|
102
|
+
const body = {};
|
|
103
|
+
for (const [key, value] of [
|
|
104
|
+
["listing_id", parsed.listingId],
|
|
105
|
+
["customer", parsed.customer],
|
|
106
|
+
["owner", parsed.owner],
|
|
107
|
+
]) {
|
|
108
|
+
if (value !== undefined)
|
|
109
|
+
body[key] = value;
|
|
110
|
+
}
|
|
111
111
|
if (!ctx.confirmed) {
|
|
112
112
|
return preview("gtm.deal.write", { dealId: parsed.dealId, ...body });
|
|
113
113
|
}
|
|
@@ -116,26 +116,33 @@ export const gtmDealWriteCapability = defineStaffMcpCapability({
|
|
|
116
116
|
: "/internal/v1/gtm/deals", { method: parsed.dealId ? "PATCH" : "POST", body });
|
|
117
117
|
},
|
|
118
118
|
});
|
|
119
|
-
|
|
119
|
+
/** Company fields that carry their own side thread. */
|
|
120
|
+
const companyField = z.enum(["name", "owner_tags", "notes", "tickets"]);
|
|
121
|
+
/** A thread hangs off one deal, one company (or one of its fields), or one ticket. */
|
|
122
|
+
const commentThread = {
|
|
120
123
|
dealId: z.number().int().positive().optional(),
|
|
121
124
|
companyId: z.number().int().positive().optional(),
|
|
122
|
-
|
|
125
|
+
taskId: z.number().int().positive().optional(),
|
|
126
|
+
/** With companyId: that field's side thread instead of the main one. */
|
|
127
|
+
field: companyField.optional(),
|
|
128
|
+
};
|
|
129
|
+
export const gtmCommentListInput = z.object(commentThread);
|
|
123
130
|
export const gtmCommentListCapability = defineStaffMcpCapability({
|
|
124
131
|
id: "gtm.comment.list",
|
|
125
132
|
domain: "gtm",
|
|
126
133
|
roles: ["reviewer", "admin"],
|
|
127
|
-
description: "GTM staff only: list the plaintext comment thread for one deal or one company, replies included. A reply carries parent_id.",
|
|
134
|
+
description: "GTM staff only: list the plaintext comment thread for one deal, one company (or one company field with field), or one ticket (taskId), replies included. A reply carries parent_id.",
|
|
128
135
|
mutation: "read",
|
|
129
136
|
http: { method: "GET", path: "/internal/v1/gtm/deals/{dealId}/comments" },
|
|
130
137
|
input: gtmCommentListInput,
|
|
131
138
|
execute: (ctx, input) => {
|
|
132
139
|
const parsed = gtmCommentListInput.parse(input);
|
|
133
|
-
|
|
140
|
+
const query = parsed.field ? `?field=${encodeURIComponent(parsed.field)}` : "";
|
|
141
|
+
return ctx.fetch(commentThreadPath(parsed) + query, { method: "GET" });
|
|
134
142
|
},
|
|
135
143
|
});
|
|
136
144
|
export const gtmCommentWriteInput = z.object({
|
|
137
|
-
|
|
138
|
-
companyId: z.number().int().positive().optional(),
|
|
145
|
+
...commentThread,
|
|
139
146
|
commentId: z.number().int().positive().optional(),
|
|
140
147
|
/** Set to reply to an existing comment. Threads are one level deep. */
|
|
141
148
|
parentId: z.number().int().positive().optional(),
|
|
@@ -147,14 +154,14 @@ export const gtmCommentWriteCapability = defineStaffMcpCapability({
|
|
|
147
154
|
id: "gtm.comment.write",
|
|
148
155
|
domain: "gtm",
|
|
149
156
|
roles: ["reviewer", "admin"],
|
|
150
|
-
description: "GTM staff only: append a plaintext comment to a deal or
|
|
157
|
+
description: "GTM staff only: append a plaintext comment to a deal, a company (or one company field with field), or a ticket (taskId); reply to one with parentId, or replace one when commentId is supplied. bid=true adds only the BID tag and changes no other behavior. Mention a teammate by writing @name in the body. Requires confirm: true.",
|
|
151
158
|
mutation: "preview-confirm",
|
|
152
159
|
http: { method: "POST", path: "/internal/v1/gtm/deals/{dealId}/comments" },
|
|
153
160
|
input: gtmCommentWriteInput,
|
|
154
161
|
execute: async (ctx, input) => {
|
|
155
162
|
const parsed = gtmCommentWriteInput.parse(input);
|
|
156
|
-
if (!parsed.commentId && !parsed.dealId && !parsed.companyId) {
|
|
157
|
-
throw new Error("dealId or
|
|
163
|
+
if (!parsed.commentId && !parsed.dealId && !parsed.companyId && !parsed.taskId) {
|
|
164
|
+
throw new Error("dealId, companyId or taskId is required when creating a comment");
|
|
158
165
|
}
|
|
159
166
|
const body = {
|
|
160
167
|
body: parsed.body,
|
|
@@ -163,10 +170,14 @@ export const gtmCommentWriteCapability = defineStaffMcpCapability({
|
|
|
163
170
|
if (parsed.parentId) {
|
|
164
171
|
body.parent_id = parsed.parentId;
|
|
165
172
|
}
|
|
173
|
+
if (parsed.field) {
|
|
174
|
+
body.field = parsed.field;
|
|
175
|
+
}
|
|
166
176
|
if (!ctx.confirmed) {
|
|
167
177
|
return preview("gtm.comment.write", {
|
|
168
178
|
dealId: parsed.dealId,
|
|
169
179
|
companyId: parsed.companyId,
|
|
180
|
+
taskId: parsed.taskId,
|
|
170
181
|
commentId: parsed.commentId,
|
|
171
182
|
...body,
|
|
172
183
|
});
|
|
@@ -181,39 +192,20 @@ function commentThreadPath(parsed) {
|
|
|
181
192
|
if (parsed.companyId) {
|
|
182
193
|
return `/internal/v1/gtm/companies/${seg(String(parsed.companyId))}/comments`;
|
|
183
194
|
}
|
|
195
|
+
if (parsed.taskId) {
|
|
196
|
+
return `/internal/v1/gtm/tasks/${seg(String(parsed.taskId))}/comments`;
|
|
197
|
+
}
|
|
184
198
|
if (parsed.dealId) {
|
|
185
199
|
return `/internal/v1/gtm/deals/${seg(String(parsed.dealId))}/comments`;
|
|
186
200
|
}
|
|
187
|
-
throw new Error("dealId or
|
|
201
|
+
throw new Error("dealId, companyId or taskId is required");
|
|
188
202
|
}
|
|
189
|
-
export const gtmMentionDismissInput = z.object({
|
|
190
|
-
commentId: z.number().int().positive(),
|
|
191
|
-
confirm: z.boolean().optional(),
|
|
192
|
-
});
|
|
193
|
-
export const gtmMentionDismissCapability = defineStaffMcpCapability({
|
|
194
|
-
id: "gtm.mention.dismiss",
|
|
195
|
-
domain: "gtm",
|
|
196
|
-
roles: ["reviewer", "admin"],
|
|
197
|
-
description: "GTM staff only: dismiss one mention for the signed-in user. The comment is untouched and everyone else still sees it. Requires confirm: true.",
|
|
198
|
-
mutation: "preview-confirm",
|
|
199
|
-
http: { method: "POST", path: "/internal/v1/gtm/comments/{commentId}/dismiss" },
|
|
200
|
-
input: gtmMentionDismissInput,
|
|
201
|
-
execute: async (ctx, input) => {
|
|
202
|
-
const parsed = gtmMentionDismissInput.parse(input);
|
|
203
|
-
if (!ctx.confirmed) {
|
|
204
|
-
return preview("gtm.mention.dismiss", { commentId: parsed.commentId });
|
|
205
|
-
}
|
|
206
|
-
return ctx.fetch(`/internal/v1/gtm/comments/${seg(String(parsed.commentId))}/dismiss`, {
|
|
207
|
-
method: "POST",
|
|
208
|
-
});
|
|
209
|
-
},
|
|
210
|
-
});
|
|
211
203
|
export const gtmWorkspaceShowInput = z.object({});
|
|
212
204
|
export const gtmWorkspaceShowCapability = defineStaffMcpCapability({
|
|
213
205
|
id: "gtm.workspace.show",
|
|
214
206
|
domain: "gtm",
|
|
215
207
|
roles: ["reviewer", "admin"],
|
|
216
|
-
description: "GTM staff only: show companies tagged to the signed-in user, deals they own,
|
|
208
|
+
description: "GTM staff only: show companies tagged to the signed-in user, deals they own, mentions of them (answered once they comment in that thread), and tickets assigned to them.",
|
|
217
209
|
mutation: "read",
|
|
218
210
|
http: { method: "GET", path: "/internal/v1/gtm/me" },
|
|
219
211
|
input: gtmWorkspaceShowInput,
|
|
@@ -308,9 +300,6 @@ function gtmDeleteCapability(entity, idKey, route, consequence) {
|
|
|
308
300
|
const companyDelete = gtmDeleteCapability("company", "companyId", "/internal/v1/gtm/companies", "Refused while the company still has deals or tickets.");
|
|
309
301
|
export const gtmCompanyDeleteInput = companyDelete.input;
|
|
310
302
|
export const gtmCompanyDeleteCapability = companyDelete.capability;
|
|
311
|
-
const dealDelete = gtmDeleteCapability("deal", "dealId", "/internal/v1/gtm/deals", "Its comments are deleted with it; tickets that referenced it are kept.");
|
|
312
|
-
export const gtmDealDeleteInput = dealDelete.input;
|
|
313
|
-
export const gtmDealDeleteCapability = dealDelete.capability;
|
|
314
303
|
const commentDelete = gtmDeleteCapability("comment", "commentId", "/internal/v1/gtm/comments", "Removes only that comment.");
|
|
315
304
|
export const gtmCommentDeleteInput = commentDelete.input;
|
|
316
305
|
export const gtmCommentDeleteCapability = commentDelete.capability;
|
|
@@ -325,13 +314,16 @@ export const gtmTaskDeleteCapability = taskDelete.capability;
|
|
|
325
314
|
*/
|
|
326
315
|
export const gtmListingListInput = z.object({
|
|
327
316
|
gpuType: z.string().optional(),
|
|
328
|
-
|
|
317
|
+
state: z.enum(["available", "internal", "delisted"]).optional(),
|
|
318
|
+
/** Commerce serves at most 100 per page; pass nextCursor back for the rest. */
|
|
319
|
+
limit: z.number().int().positive().max(100).optional(),
|
|
320
|
+
cursor: z.string().optional(),
|
|
329
321
|
});
|
|
330
322
|
export const gtmListingListCapability = defineStaffMcpCapability({
|
|
331
323
|
id: "gtm.listing.list",
|
|
332
324
|
domain: "gtm",
|
|
333
325
|
roles: ["reviewer", "admin"],
|
|
334
|
-
description: "GTM staff only: list Commerce listings
|
|
326
|
+
description: "GTM staff only: list Commerce listings (each can carry one GTM deal), optionally filtered by GPU type or state. Returns at most 100 per call with nextCursor; pass it back as cursor for the next page. Includes provider (staff-only). Read-only; this is Commerce's catalog, not CRM data.",
|
|
335
327
|
mutation: "read",
|
|
336
328
|
http: { method: "GET", path: "/internal/v1/listings" },
|
|
337
329
|
input: gtmListingListInput,
|
|
@@ -340,10 +332,17 @@ export const gtmListingListCapability = defineStaffMcpCapability({
|
|
|
340
332
|
const parts = [`limit=${encodeURIComponent(String(parsed.limit ?? 50))}`];
|
|
341
333
|
if (parsed.gpuType)
|
|
342
334
|
parts.push(`q=${encodeURIComponent(parsed.gpuType)}`);
|
|
335
|
+
if (parsed.state)
|
|
336
|
+
parts.push(`state=${encodeURIComponent(parsed.state)}`);
|
|
337
|
+
if (parsed.cursor)
|
|
338
|
+
parts.push(`cursor=${encodeURIComponent(parsed.cursor)}`);
|
|
343
339
|
const page = (await ctx.fetch(`/internal/v1/listings?${parts.join("&")}`, {
|
|
344
340
|
method: "GET",
|
|
345
341
|
}));
|
|
346
|
-
return {
|
|
342
|
+
return {
|
|
343
|
+
listings: (page.listings ?? []).map(staffListing),
|
|
344
|
+
nextCursor: page.nextCursor ?? null,
|
|
345
|
+
};
|
|
347
346
|
},
|
|
348
347
|
});
|
|
349
348
|
export const gtmListingUpdateInput = z.object({
|
|
@@ -355,7 +354,7 @@ export const gtmListingUpdateInput = z.object({
|
|
|
355
354
|
allowsDepositPlan: z.boolean().optional(),
|
|
356
355
|
downPaymentPct: z.string().optional(),
|
|
357
356
|
capacityNodes: z.number().int().positive().optional(),
|
|
358
|
-
state: z.enum(["
|
|
357
|
+
state: z.enum(["available", "internal", "delisted"]).optional(),
|
|
359
358
|
confirm: z.boolean().optional(),
|
|
360
359
|
});
|
|
361
360
|
export const gtmListingUpdateCapability = defineStaffMcpCapability({
|
|
@@ -383,9 +382,14 @@ export const gtmListingUpdateCapability = defineStaffMcpCapability({
|
|
|
383
382
|
* region are allowed; operator ids and provider names are not. Every listing
|
|
384
383
|
* this module returns -- list, update, and the apply result -- goes through it.
|
|
385
384
|
*/
|
|
386
|
-
|
|
385
|
+
/**
|
|
386
|
+
* GTM tools are staff-only, behind the reviewer boundary, so they keep the
|
|
387
|
+
* listing's provider -- a deal's supplier is its listing's. The operator
|
|
388
|
+
* record's own id and legal name still stay out.
|
|
389
|
+
*/
|
|
390
|
+
function staffListing(raw) {
|
|
387
391
|
const listing = raw;
|
|
388
|
-
const { operatorId: _operatorId, operatorName: _operatorName,
|
|
392
|
+
const { operatorId: _operatorId, operatorName: _operatorName, ...safe } = listing;
|
|
389
393
|
return safe;
|
|
390
394
|
}
|
|
391
395
|
/**
|
|
@@ -404,7 +408,7 @@ async function patchListing(ctx, listingId, body) {
|
|
|
404
408
|
method: "PATCH",
|
|
405
409
|
body: { ...body, version: current.version },
|
|
406
410
|
});
|
|
407
|
-
return
|
|
411
|
+
return staffListing(updated);
|
|
408
412
|
}
|
|
409
413
|
function listingPatchBody(parsed) {
|
|
410
414
|
const body = {};
|
|
@@ -434,7 +438,7 @@ export const gtmTaskActivityListCapability = defineStaffMcpCapability({
|
|
|
434
438
|
id: "gtm.task.activity.list",
|
|
435
439
|
domain: "gtm",
|
|
436
440
|
roles: ["reviewer", "admin"],
|
|
437
|
-
description: "GTM staff only: read one ticket's
|
|
441
|
+
description: "GTM staff only: read one ticket's history — its creation and the field changes recorded against it, oldest first. Its comments are gtm.comment.list with taskId.",
|
|
438
442
|
mutation: "read",
|
|
439
443
|
http: { method: "GET", path: "/internal/v1/gtm/tasks/{taskId}/activity" },
|
|
440
444
|
input: gtmTaskActivityListInput,
|
|
@@ -445,99 +449,6 @@ export const gtmTaskActivityListCapability = defineStaffMcpCapability({
|
|
|
445
449
|
});
|
|
446
450
|
},
|
|
447
451
|
});
|
|
448
|
-
export const gtmTaskActivityWriteInput = z.object({
|
|
449
|
-
taskId: z.number().int().positive(),
|
|
450
|
-
body: z.string().min(1),
|
|
451
|
-
/** Set to reply to a comment on the same ticket. Threads are one level deep. */
|
|
452
|
-
parentId: z.number().int().positive().optional(),
|
|
453
|
-
confirm: z.boolean().optional(),
|
|
454
|
-
});
|
|
455
|
-
export const gtmTaskActivityWriteCapability = defineStaffMcpCapability({
|
|
456
|
-
id: "gtm.task.activity.write",
|
|
457
|
-
domain: "gtm",
|
|
458
|
-
roles: ["reviewer", "admin"],
|
|
459
|
-
description: "GTM staff only: add a plaintext comment to a ticket, or reply to one with parentId. Mention a teammate by writing @name in the body. Requires confirm: true.",
|
|
460
|
-
mutation: "preview-confirm",
|
|
461
|
-
http: { method: "POST", path: "/internal/v1/gtm/tasks/{taskId}/activity" },
|
|
462
|
-
input: gtmTaskActivityWriteInput,
|
|
463
|
-
execute: async (ctx, input) => {
|
|
464
|
-
const parsed = gtmTaskActivityWriteInput.parse(input);
|
|
465
|
-
const body = { body: parsed.body, parent_id: parsed.parentId ?? null };
|
|
466
|
-
if (!ctx.confirmed) {
|
|
467
|
-
return preview("gtm.task.activity.write", { taskId: parsed.taskId, ...body });
|
|
468
|
-
}
|
|
469
|
-
return ctx.fetch(`/internal/v1/gtm/tasks/${seg(String(parsed.taskId))}/activity`, {
|
|
470
|
-
method: "POST",
|
|
471
|
-
body,
|
|
472
|
-
});
|
|
473
|
-
},
|
|
474
|
-
});
|
|
475
|
-
/**
|
|
476
|
-
* Company cell comments. These hang off one field of one company — the
|
|
477
|
-
* discussion about a name, its owner tags, its summary, or its tickets —
|
|
478
|
-
* rather than off the company's main thread.
|
|
479
|
-
*/
|
|
480
|
-
const cellField = z.enum(["name", "owner_tags", "notes", "tickets"]);
|
|
481
|
-
export const gtmCellCommentListInput = z.object({
|
|
482
|
-
companyId: z.number().int().positive(),
|
|
483
|
-
field: cellField,
|
|
484
|
-
});
|
|
485
|
-
export const gtmCellCommentListCapability = defineStaffMcpCapability({
|
|
486
|
-
id: "gtm.cell.comment.list",
|
|
487
|
-
domain: "gtm",
|
|
488
|
-
roles: ["reviewer", "admin"],
|
|
489
|
-
description: "GTM staff only: read the comments attached to one field of one company (name, owner_tags, notes or tickets), replies included.",
|
|
490
|
-
mutation: "read",
|
|
491
|
-
http: { method: "GET", path: "/internal/v1/gtm/companies/{companyId}/cells/{field}/comments" },
|
|
492
|
-
input: gtmCellCommentListInput,
|
|
493
|
-
execute: (ctx, input) => {
|
|
494
|
-
const parsed = gtmCellCommentListInput.parse(input);
|
|
495
|
-
return ctx.fetch(`/internal/v1/gtm/companies/${seg(String(parsed.companyId))}/cells/${seg(parsed.field)}/comments`, { method: "GET" });
|
|
496
|
-
},
|
|
497
|
-
});
|
|
498
|
-
export const gtmCellCommentWriteInput = z.object({
|
|
499
|
-
companyId: z.number().int().positive().optional(),
|
|
500
|
-
field: cellField.optional(),
|
|
501
|
-
/** Set to replace an existing cell comment; companyId and field are then unused. */
|
|
502
|
-
commentId: z.number().int().positive().optional(),
|
|
503
|
-
parentId: z.number().int().positive().optional(),
|
|
504
|
-
body: z.string().min(1),
|
|
505
|
-
confirm: z.boolean().optional(),
|
|
506
|
-
});
|
|
507
|
-
export const gtmCellCommentWriteCapability = defineStaffMcpCapability({
|
|
508
|
-
id: "gtm.cell.comment.write",
|
|
509
|
-
domain: "gtm",
|
|
510
|
-
roles: ["reviewer", "admin"],
|
|
511
|
-
description: "GTM staff only: comment on one field of one company, reply to such a comment with parentId, or replace one when commentId is supplied. Requires confirm: true.",
|
|
512
|
-
mutation: "preview-confirm",
|
|
513
|
-
http: { method: "POST", path: "/internal/v1/gtm/companies/{companyId}/cells/{field}/comments" },
|
|
514
|
-
input: gtmCellCommentWriteInput,
|
|
515
|
-
execute: async (ctx, input) => {
|
|
516
|
-
const parsed = gtmCellCommentWriteInput.parse(input);
|
|
517
|
-
if (!parsed.commentId && (!parsed.companyId || !parsed.field)) {
|
|
518
|
-
throw new Error("companyId and field are required unless commentId is supplied");
|
|
519
|
-
}
|
|
520
|
-
if (!ctx.confirmed) {
|
|
521
|
-
return preview("gtm.cell.comment.write", {
|
|
522
|
-
companyId: parsed.companyId,
|
|
523
|
-
field: parsed.field,
|
|
524
|
-
commentId: parsed.commentId,
|
|
525
|
-
parentId: parsed.parentId,
|
|
526
|
-
body: parsed.body,
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
if (parsed.commentId) {
|
|
530
|
-
return ctx.fetch(`/internal/v1/gtm/company-comments/${seg(String(parsed.commentId))}`, {
|
|
531
|
-
method: "PATCH",
|
|
532
|
-
body: { body: parsed.body },
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
return ctx.fetch(`/internal/v1/gtm/companies/${seg(String(parsed.companyId))}/cells/${seg(parsed.field)}/comments`, { method: "POST", body: { body: parsed.body, parent_id: parsed.parentId ?? null } });
|
|
536
|
-
},
|
|
537
|
-
});
|
|
538
|
-
const cellCommentDelete = gtmDeleteCapability("cell.comment", "commentId", "/internal/v1/gtm/company-comments", "Removes that field comment and its replies.");
|
|
539
|
-
export const gtmCellCommentDeleteInput = cellCommentDelete.input;
|
|
540
|
-
export const gtmCellCommentDeleteCapability = cellCommentDelete.capability;
|
|
541
452
|
/**
|
|
542
453
|
* Bulk owner-tag reassignment. This is the one GTM edit that is genuinely
|
|
543
454
|
* N-at-a-time — a book of companies moving to a new owner — and doing it one
|
|
@@ -597,20 +508,14 @@ export const staffGTMCapabilities = [
|
|
|
597
508
|
gtmCompanyBulkRetagCapability,
|
|
598
509
|
gtmDealListCapability,
|
|
599
510
|
gtmDealWriteCapability,
|
|
600
|
-
gtmDealDeleteCapability,
|
|
601
511
|
gtmCommentListCapability,
|
|
602
512
|
gtmCommentWriteCapability,
|
|
603
513
|
gtmCommentDeleteCapability,
|
|
604
|
-
gtmCellCommentListCapability,
|
|
605
|
-
gtmCellCommentWriteCapability,
|
|
606
|
-
gtmCellCommentDeleteCapability,
|
|
607
514
|
gtmTaskListCapability,
|
|
608
515
|
gtmTaskWriteCapability,
|
|
609
516
|
gtmTaskDeleteCapability,
|
|
610
517
|
gtmTaskActivityListCapability,
|
|
611
|
-
gtmTaskActivityWriteCapability,
|
|
612
518
|
gtmListingListCapability,
|
|
613
519
|
gtmListingUpdateCapability,
|
|
614
|
-
gtmMentionDismissCapability,
|
|
615
520
|
gtmWorkspaceShowCapability,
|
|
616
521
|
];
|
|
@@ -11,6 +11,6 @@ export { logsLatestCapability, logsTailCapability, observabilityCapabilities, te
|
|
|
11
11
|
export { enrollmentTokenRevokeCapability, enrollmentTokenRevokeInput, facilityCreateCapability, facilityCreateInput, facilityUpdateCapability, facilityUpdateInput, nodeAdminKeyCapability, nodeAdminKeyInput, nodeBenchmarkCapability, nodeBenchmarkInput, nodeDeployCapability, nodeDeployInput, nodeDetailsUpdateCapability, nodeDetailsUpdateInput, nodeHardResetCapability, nodeHardResetInput, nodeOperatorTransferCapability, nodeOperatorTransferInput, nodeRebootCapability, nodeRebootInput, nodeShowCapability, nodeShowInput, nodeTestResultCapability, nodeTestResultInput, nodeTestTriggerCapability, nodeTestTriggerInput, nodeUpdateCapability, nodeUpdateInput, operatorCreateCapability, operatorCreateInput, operatorDeleteCapability, operatorDeleteInput, operatorUpdateCapability, operatorUpdateInput, staffFleetCapabilities, } from "./capabilities/staff-fleet.ts";
|
|
12
12
|
export { bidShowCapability, bidShowInput, bidAcceptCapability, bidAcceptInput, bidRejectCapability, bidRejectInput, billingInvoicesListCapability, billingInvoicesListInput, inventoryDelistCapability, inventoryDelistInput, inventoryUpdateCapability, inventoryUpdateInput, reservationActivateCapability, reservationActivateInput, reservationCancelCapability, reservationCancelInput, reservationCompleteCapability, reservationCompleteInput, reservationDraftCreateCapability, reservationDraftCreateInput, reservationListCapability, reservationListInput, reservationMachinesListCapability, reservationMachinesListInput, reservationPublishCapability, reservationPublishInput, reservationShowCapability, reservationShowInput, reservationSshKeyAddCapability, reservationSshKeyAddInput, reservationSshKeyRemoveCapability, reservationSshKeyRemoveInput, reservationTransferCapability, reservationTransferInput, reservationUpdateCapability, reservationUpdateInput, staffCommerceCapabilities, tenantCreditProfileShowCapability, tenantCreditProfileShowInput, } from "./capabilities/staff-commerce.ts";
|
|
13
13
|
export { sshKeyAddCapability, sshKeyAddInput, sshKeyPushCapability, sshKeyPushInput, sshKeyRevokeCapability, sshKeyRevokeInput, staffAccessCapabilities, } from "./capabilities/staff-access.ts";
|
|
14
|
-
export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput,
|
|
14
|
+
export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput, gtmDealListCapability, gtmDealListInput, gtmListingListCapability, gtmListingListInput, gtmListingUpdateCapability, gtmListingUpdateInput, gtmDealWriteCapability, gtmDealWriteInput, gtmTaskDeleteCapability, gtmTaskDeleteInput, gtmTaskListCapability, gtmTaskListInput, gtmTaskWriteCapability, gtmTaskWriteInput, gtmTaskActivityListCapability, gtmTaskActivityListInput, gtmWorkspaceShowCapability, gtmWorkspaceShowInput, staffGTMCapabilities, } from "./capabilities/staff-gtm.ts";
|
|
15
15
|
export { CLIENTS, parseRole, roleAtLeast, ROLES, type ClientKind, type Role } from "./role.ts";
|
|
16
16
|
export { bindHardwareFields, HARDWARE_CATALOG_PATH, HARDWARE_KINDS, HARDWARE_LISTING_FIELDS, HARDWARE_LISTING_FILTERS, loadHardwareCatalog, looksLikeSpecDump, normalizeCatalogQuery, parseHardwareCatalog, projectCatalogTerms, proposeListingPayload, resolveCatalogTerm, UNRESOLVED_CATALOG_HINT, type CatalogBindResult, type CatalogTerm, type HardwareCatalog, type HardwareKind, type ResolvedCatalogTerm, } from "./spec-catalog.ts";
|
|
@@ -11,6 +11,6 @@ export { logsLatestCapability, logsTailCapability, observabilityCapabilities, te
|
|
|
11
11
|
export { enrollmentTokenRevokeCapability, enrollmentTokenRevokeInput, facilityCreateCapability, facilityCreateInput, facilityUpdateCapability, facilityUpdateInput, nodeAdminKeyCapability, nodeAdminKeyInput, nodeBenchmarkCapability, nodeBenchmarkInput, nodeDeployCapability, nodeDeployInput, nodeDetailsUpdateCapability, nodeDetailsUpdateInput, nodeHardResetCapability, nodeHardResetInput, nodeOperatorTransferCapability, nodeOperatorTransferInput, nodeRebootCapability, nodeRebootInput, nodeShowCapability, nodeShowInput, nodeTestResultCapability, nodeTestResultInput, nodeTestTriggerCapability, nodeTestTriggerInput, nodeUpdateCapability, nodeUpdateInput, operatorCreateCapability, operatorCreateInput, operatorDeleteCapability, operatorDeleteInput, operatorUpdateCapability, operatorUpdateInput, staffFleetCapabilities, } from "./capabilities/staff-fleet.js";
|
|
12
12
|
export { bidShowCapability, bidShowInput, bidAcceptCapability, bidAcceptInput, bidRejectCapability, bidRejectInput, billingInvoicesListCapability, billingInvoicesListInput, inventoryDelistCapability, inventoryDelistInput, inventoryUpdateCapability, inventoryUpdateInput, reservationActivateCapability, reservationActivateInput, reservationCancelCapability, reservationCancelInput, reservationCompleteCapability, reservationCompleteInput, reservationDraftCreateCapability, reservationDraftCreateInput, reservationListCapability, reservationListInput, reservationMachinesListCapability, reservationMachinesListInput, reservationPublishCapability, reservationPublishInput, reservationShowCapability, reservationShowInput, reservationSshKeyAddCapability, reservationSshKeyAddInput, reservationSshKeyRemoveCapability, reservationSshKeyRemoveInput, reservationTransferCapability, reservationTransferInput, reservationUpdateCapability, reservationUpdateInput, staffCommerceCapabilities, tenantCreditProfileShowCapability, tenantCreditProfileShowInput, } from "./capabilities/staff-commerce.js";
|
|
13
13
|
export { sshKeyAddCapability, sshKeyAddInput, sshKeyPushCapability, sshKeyPushInput, sshKeyRevokeCapability, sshKeyRevokeInput, staffAccessCapabilities, } from "./capabilities/staff-access.js";
|
|
14
|
-
export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput,
|
|
14
|
+
export { gtmCommentDeleteCapability, gtmCommentDeleteInput, gtmCommentListCapability, gtmCommentListInput, gtmCommentWriteCapability, gtmCommentWriteInput, gtmCompanyDeleteCapability, gtmCompanyDeleteInput, gtmCompanyListCapability, gtmCompanyListInput, gtmCompanyWriteCapability, gtmCompanyWriteInput, gtmCompanyBulkRetagCapability, gtmCompanyBulkRetagInput, gtmDealListCapability, gtmDealListInput, gtmListingListCapability, gtmListingListInput, gtmListingUpdateCapability, gtmListingUpdateInput, gtmDealWriteCapability, gtmDealWriteInput, gtmTaskDeleteCapability, gtmTaskDeleteInput, gtmTaskListCapability, gtmTaskListInput, gtmTaskWriteCapability, gtmTaskWriteInput, gtmTaskActivityListCapability, gtmTaskActivityListInput, gtmWorkspaceShowCapability, gtmWorkspaceShowInput, staffGTMCapabilities, } from "./capabilities/staff-gtm.js";
|
|
15
15
|
export { CLIENTS, parseRole, roleAtLeast, ROLES } from "./role.js";
|
|
16
16
|
export { bindHardwareFields, HARDWARE_CATALOG_PATH, HARDWARE_KINDS, HARDWARE_LISTING_FIELDS, HARDWARE_LISTING_FILTERS, loadHardwareCatalog, looksLikeSpecDump, normalizeCatalogQuery, parseHardwareCatalog, projectCatalogTerms, proposeListingPayload, resolveCatalogTerm, UNRESOLVED_CATALOG_HINT, } from "./spec-catalog.js";
|