@camstack/addon-terminal 0.1.29 → 0.1.31
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/addon.js +350 -30
- package/dist/addon.mjs +350 -30
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -20003,6 +20003,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
|
|
|
20003
20003
|
location: StorageLocationSchema,
|
|
20004
20004
|
relativePath: string()
|
|
20005
20005
|
}), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
|
|
20006
|
+
/** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
|
|
20007
|
+
var ProfileSettingsSchemaBridge = unknown().nullable();
|
|
20008
|
+
var ProfileSettingsBagSchema = record(string(), unknown());
|
|
20006
20009
|
/**
|
|
20007
20010
|
* A live terminal session hosted by the provider addon. Output and input do
|
|
20008
20011
|
* NOT flow through the capability — they use the addon data plane
|
|
@@ -20032,7 +20035,14 @@ var TerminalSessionInfoSchema = object({
|
|
|
20032
20035
|
var TerminalProfileInfoSchema = object({
|
|
20033
20036
|
profileId: string(),
|
|
20034
20037
|
label: string(),
|
|
20035
|
-
description: string().optional()
|
|
20038
|
+
description: string().optional(),
|
|
20039
|
+
/** Spawn defaults the instance form copies on create. */
|
|
20040
|
+
executable: string().optional(),
|
|
20041
|
+
args: array(string()).readonly().optional(),
|
|
20042
|
+
cwd: string().optional(),
|
|
20043
|
+
environment: array(string()).readonly().optional(),
|
|
20044
|
+
/** ConfigUISchema for instance knobs, or null when the profile has none. */
|
|
20045
|
+
settingsSchema: ProfileSettingsSchemaBridge.optional()
|
|
20036
20046
|
});
|
|
20037
20047
|
/**
|
|
20038
20048
|
* A durable operator-created Terminal instance. Profiles are templates; only
|
|
@@ -20045,7 +20055,12 @@ var TerminalInstanceInfoSchema = object({
|
|
|
20045
20055
|
profileId: string(),
|
|
20046
20056
|
profileLabel: string(),
|
|
20047
20057
|
name: string(),
|
|
20048
|
-
enabled: boolean()
|
|
20058
|
+
enabled: boolean(),
|
|
20059
|
+
executable: string(),
|
|
20060
|
+
args: array(string()).readonly(),
|
|
20061
|
+
cwd: string(),
|
|
20062
|
+
environment: array(string()).readonly(),
|
|
20063
|
+
profileSettings: ProfileSettingsBagSchema
|
|
20049
20064
|
});
|
|
20050
20065
|
var TerminalLegacyCameraSchema = object({
|
|
20051
20066
|
stableId: string(),
|
|
@@ -20091,7 +20106,24 @@ var terminalSessionCapability = {
|
|
|
20091
20106
|
createInstance: method(object({
|
|
20092
20107
|
targetNodeId: string().min(1),
|
|
20093
20108
|
profileId: string().min(1),
|
|
20094
|
-
name: string().trim().min(1).max(160).optional()
|
|
20109
|
+
name: string().trim().min(1).max(160).optional(),
|
|
20110
|
+
executable: string().max(1024).optional(),
|
|
20111
|
+
args: array(string().max(2048)).max(64).optional(),
|
|
20112
|
+
cwd: string().max(1024).optional(),
|
|
20113
|
+
environment: array(string().max(4096)).max(64).optional(),
|
|
20114
|
+
profileSettings: ProfileSettingsBagSchema.optional()
|
|
20115
|
+
}), TerminalInstanceInfoSchema, {
|
|
20116
|
+
kind: "mutation",
|
|
20117
|
+
auth: "admin"
|
|
20118
|
+
}),
|
|
20119
|
+
updateInstance: method(object({
|
|
20120
|
+
instanceId: string().min(1),
|
|
20121
|
+
name: string().trim().min(1).max(160).optional(),
|
|
20122
|
+
executable: string().max(1024).optional(),
|
|
20123
|
+
args: array(string().max(2048)).max(64).optional(),
|
|
20124
|
+
cwd: string().max(1024).optional(),
|
|
20125
|
+
environment: array(string().max(4096)).max(64).optional(),
|
|
20126
|
+
profileSettings: ProfileSettingsBagSchema.optional()
|
|
20095
20127
|
}), TerminalInstanceInfoSchema, {
|
|
20096
20128
|
kind: "mutation",
|
|
20097
20129
|
auth: "admin"
|
|
@@ -20126,7 +20158,11 @@ var terminalSessionCapability = {
|
|
|
20126
20158
|
openSession: method(object({
|
|
20127
20159
|
profileId: string(),
|
|
20128
20160
|
cols: number().int().positive(),
|
|
20129
|
-
rows: number().int().positive()
|
|
20161
|
+
rows: number().int().positive(),
|
|
20162
|
+
executable: string().max(1024).optional(),
|
|
20163
|
+
args: array(string().max(2048)).max(64).optional(),
|
|
20164
|
+
cwd: string().max(1024).optional(),
|
|
20165
|
+
environment: array(string().max(4096)).max(64).optional()
|
|
20130
20166
|
}), TerminalSessionInfoSchema, {
|
|
20131
20167
|
kind: "mutation",
|
|
20132
20168
|
auth: "admin"
|
|
@@ -24015,10 +24051,10 @@ var lawnMowerControlCapability = {
|
|
|
24015
24051
|
*
|
|
24016
24052
|
* • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
|
|
24017
24053
|
* to receive an ordered list of candidate base URLs it should race
|
|
24018
|
-
* on connect — LAN IPv4 first (lowest latency
|
|
24019
|
-
* then public hostname (if a tunnel is
|
|
24020
|
-
* race them with short timeouts and stick with the
|
|
24021
|
-
* session.
|
|
24054
|
+
* on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
|
|
24055
|
+
* when on the same network), then public hostname (if a tunnel is
|
|
24056
|
+
* up). The SDK can race them with short timeouts and stick with the
|
|
24057
|
+
* winner for the session.
|
|
24022
24058
|
*
|
|
24023
24059
|
* Why hub-only: agents are not directly addressable by the operator's
|
|
24024
24060
|
* clients — they reverse-connect to the hub. Exposing their interfaces
|
|
@@ -24181,6 +24217,20 @@ var AllowedAddressesSchema = object({
|
|
|
24181
24217
|
* Network Addresses admin page and persisted by the addon.
|
|
24182
24218
|
*/
|
|
24183
24219
|
addresses: array(string()).readonly() });
|
|
24220
|
+
var TlsStatusSchema = object({
|
|
24221
|
+
mode: _enum([
|
|
24222
|
+
"generated",
|
|
24223
|
+
"uploaded",
|
|
24224
|
+
"disabled"
|
|
24225
|
+
]),
|
|
24226
|
+
leafFingerprintSha256: string().nullable(),
|
|
24227
|
+
caFingerprintSha256: string().nullable(),
|
|
24228
|
+
validTo: string().nullable(),
|
|
24229
|
+
sans: array(string()),
|
|
24230
|
+
caCertPem: string().nullable(),
|
|
24231
|
+
reissueError: string().nullable(),
|
|
24232
|
+
restartRequired: boolean()
|
|
24233
|
+
});
|
|
24184
24234
|
method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
|
|
24185
24235
|
/**
|
|
24186
24236
|
* LEGACY HINT — do not send from new code. Kept optional so clients
|
|
@@ -24200,7 +24250,20 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
24200
24250
|
* to avoid mixed-content blocks in the browser. The public
|
|
24201
24251
|
* tunnel always emits `https://` regardless. */
|
|
24202
24252
|
scheme: _enum(["http", "https"]).optional()
|
|
24203
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" })
|
|
24253
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
24254
|
+
kind: "mutation",
|
|
24255
|
+
auth: "admin"
|
|
24256
|
+
}), method(object({
|
|
24257
|
+
certPem: string().min(1),
|
|
24258
|
+
keyPem: string().min(1),
|
|
24259
|
+
caPem: string().optional()
|
|
24260
|
+
}), TlsStatusSchema, {
|
|
24261
|
+
kind: "mutation",
|
|
24262
|
+
auth: "admin"
|
|
24263
|
+
}), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
|
|
24264
|
+
kind: "mutation",
|
|
24265
|
+
auth: "admin"
|
|
24266
|
+
});
|
|
24204
24267
|
var LockControlStatusSchema = object({
|
|
24205
24268
|
/** Lifecycle state of the lock. `jammed` means the motor reported
|
|
24206
24269
|
* failure to reach the target — operator intervention required. */
|
|
@@ -32225,6 +32288,12 @@ Object.freeze({
|
|
|
32225
32288
|
addonId: null,
|
|
32226
32289
|
access: "create"
|
|
32227
32290
|
},
|
|
32291
|
+
"localNetwork.downloadCa": {
|
|
32292
|
+
capName: "local-network",
|
|
32293
|
+
capScope: "system",
|
|
32294
|
+
addonId: null,
|
|
32295
|
+
access: "view"
|
|
32296
|
+
},
|
|
32228
32297
|
"localNetwork.getAllowedAddresses": {
|
|
32229
32298
|
capName: "local-network",
|
|
32230
32299
|
capScope: "system",
|
|
@@ -32249,18 +32318,36 @@ Object.freeze({
|
|
|
32249
32318
|
addonId: null,
|
|
32250
32319
|
access: "view"
|
|
32251
32320
|
},
|
|
32321
|
+
"localNetwork.getTlsStatus": {
|
|
32322
|
+
capName: "local-network",
|
|
32323
|
+
capScope: "system",
|
|
32324
|
+
addonId: null,
|
|
32325
|
+
access: "view"
|
|
32326
|
+
},
|
|
32252
32327
|
"localNetwork.list": {
|
|
32253
32328
|
capName: "local-network",
|
|
32254
32329
|
capScope: "system",
|
|
32255
32330
|
addonId: null,
|
|
32256
32331
|
access: "view"
|
|
32257
32332
|
},
|
|
32333
|
+
"localNetwork.regenerateCertificate": {
|
|
32334
|
+
capName: "local-network",
|
|
32335
|
+
capScope: "system",
|
|
32336
|
+
addonId: null,
|
|
32337
|
+
access: "create"
|
|
32338
|
+
},
|
|
32258
32339
|
"localNetwork.resetAllowlistToBestMatch": {
|
|
32259
32340
|
capName: "local-network",
|
|
32260
32341
|
capScope: "system",
|
|
32261
32342
|
addonId: null,
|
|
32262
32343
|
access: "delete"
|
|
32263
32344
|
},
|
|
32345
|
+
"localNetwork.revertToGeneratedCertificate": {
|
|
32346
|
+
capName: "local-network",
|
|
32347
|
+
capScope: "system",
|
|
32348
|
+
addonId: null,
|
|
32349
|
+
access: "create"
|
|
32350
|
+
},
|
|
32264
32351
|
"localNetwork.setAllowedAddresses": {
|
|
32265
32352
|
capName: "local-network",
|
|
32266
32353
|
capScope: "system",
|
|
@@ -32273,6 +32360,12 @@ Object.freeze({
|
|
|
32273
32360
|
addonId: null,
|
|
32274
32361
|
access: "create"
|
|
32275
32362
|
},
|
|
32363
|
+
"localNetwork.uploadCertificate": {
|
|
32364
|
+
capName: "local-network",
|
|
32365
|
+
capScope: "system",
|
|
32366
|
+
addonId: null,
|
|
32367
|
+
access: "create"
|
|
32368
|
+
},
|
|
32276
32369
|
"lockControl.lock": {
|
|
32277
32370
|
capName: "lock-control",
|
|
32278
32371
|
capScope: "device",
|
|
@@ -35153,6 +35246,12 @@ Object.freeze({
|
|
|
35153
35246
|
addonId: null,
|
|
35154
35247
|
access: "create"
|
|
35155
35248
|
},
|
|
35249
|
+
"terminalSession.updateInstance": {
|
|
35250
|
+
capName: "terminal-session",
|
|
35251
|
+
capScope: "system",
|
|
35252
|
+
addonId: null,
|
|
35253
|
+
access: "create"
|
|
35254
|
+
},
|
|
35156
35255
|
"terminalSession.writeInput": {
|
|
35157
35256
|
capName: "terminal-session",
|
|
35158
35257
|
capScope: "system",
|
|
@@ -37640,6 +37739,35 @@ Object.freeze(Object.fromEntries([{
|
|
|
37640
37739
|
}]
|
|
37641
37740
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
37642
37741
|
string().min(1);
|
|
37742
|
+
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
37743
|
+
stepId: "face-embedding",
|
|
37744
|
+
key: "minLandmarkFaceSize",
|
|
37745
|
+
label: "Min face size for recognition (detection px)",
|
|
37746
|
+
description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
|
|
37747
|
+
type: "slider",
|
|
37748
|
+
min: 0,
|
|
37749
|
+
max: 64,
|
|
37750
|
+
step: 2,
|
|
37751
|
+
default: 24
|
|
37752
|
+
}];
|
|
37753
|
+
function clusterStepSettingKey(stepId, fieldKey) {
|
|
37754
|
+
return `clusterStepSetting:${stepId}:${fieldKey}`;
|
|
37755
|
+
}
|
|
37756
|
+
var ClusterSettingNumberSchema = number().finite();
|
|
37757
|
+
function readClusterStepSettings(config) {
|
|
37758
|
+
const out = {};
|
|
37759
|
+
for (const field of CLUSTER_STEP_SETTING_FIELDS) {
|
|
37760
|
+
const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
|
|
37761
|
+
const value = parsed.success ? parsed.data : field.default;
|
|
37762
|
+
const existing = out[field.stepId] ?? {};
|
|
37763
|
+
out[field.stepId] = {
|
|
37764
|
+
...existing,
|
|
37765
|
+
[field.key]: value
|
|
37766
|
+
};
|
|
37767
|
+
}
|
|
37768
|
+
return out;
|
|
37769
|
+
}
|
|
37770
|
+
readClusterStepSettings({});
|
|
37643
37771
|
object({
|
|
37644
37772
|
/**
|
|
37645
37773
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -43172,7 +43300,7 @@ var require_xterm_headless = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
43172
43300
|
var import_addon_serialize = require_addon_serialize();
|
|
43173
43301
|
var import_xterm_headless = require_xterm_headless();
|
|
43174
43302
|
var SCROLLBACK_LINES = 2e3;
|
|
43175
|
-
function createXtermScreen(cols, rows) {
|
|
43303
|
+
function createXtermScreen$1(cols, rows) {
|
|
43176
43304
|
const term = new import_xterm_headless.Terminal({
|
|
43177
43305
|
cols,
|
|
43178
43306
|
rows,
|
|
@@ -43316,7 +43444,7 @@ var TerminalCameraRelay = class {
|
|
|
43316
43444
|
instanceId,
|
|
43317
43445
|
nodeId,
|
|
43318
43446
|
profileId,
|
|
43319
|
-
screen: createXtermScreen(120, 40),
|
|
43447
|
+
screen: createXtermScreen$1(120, 40),
|
|
43320
43448
|
sessionId: null,
|
|
43321
43449
|
cursor: 0,
|
|
43322
43450
|
clients: 0,
|
|
@@ -43347,7 +43475,8 @@ var TerminalCameraRelay = class {
|
|
|
43347
43475
|
const opening = this.api.openSession(state.nodeId, {
|
|
43348
43476
|
profileId: state.profileId,
|
|
43349
43477
|
cols: 120,
|
|
43350
|
-
rows: 40
|
|
43478
|
+
rows: 40,
|
|
43479
|
+
instanceId: state.instanceId
|
|
43351
43480
|
});
|
|
43352
43481
|
state.openPromise = opening;
|
|
43353
43482
|
try {
|
|
@@ -43372,7 +43501,7 @@ var TerminalCameraRelay = class {
|
|
|
43372
43501
|
applyBatch(state, batch) {
|
|
43373
43502
|
if (batch.reset) {
|
|
43374
43503
|
state.screen.dispose();
|
|
43375
|
-
state.screen = createXtermScreen(120, 40);
|
|
43504
|
+
state.screen = createXtermScreen$1(120, 40);
|
|
43376
43505
|
if (batch.snapshot) state.screen.write(batch.snapshot);
|
|
43377
43506
|
}
|
|
43378
43507
|
let exited = false;
|
|
@@ -43734,8 +43863,26 @@ var TerminalInstanceSchema = object({
|
|
|
43734
43863
|
profileId: string().min(1).max(64),
|
|
43735
43864
|
profileLabel: string().min(1).max(120),
|
|
43736
43865
|
name: string().min(1).max(160),
|
|
43737
|
-
enabled: boolean()
|
|
43866
|
+
enabled: boolean(),
|
|
43867
|
+
executable: string().max(1024).default(""),
|
|
43868
|
+
args: array(string().max(2048)).max(64).default([]),
|
|
43869
|
+
cwd: string().max(1024).default(""),
|
|
43870
|
+
environment: array(string().max(4096)).max(64).default([]),
|
|
43871
|
+
profileSettings: record(string(), unknown()).default({})
|
|
43738
43872
|
});
|
|
43873
|
+
function environmentEntriesToRecord(entries) {
|
|
43874
|
+
const out = {};
|
|
43875
|
+
for (const entry of entries) {
|
|
43876
|
+
const eq = entry.indexOf("=");
|
|
43877
|
+
if (eq <= 0) continue;
|
|
43878
|
+
out[entry.slice(0, eq)] = entry.slice(eq + 1);
|
|
43879
|
+
}
|
|
43880
|
+
return out;
|
|
43881
|
+
}
|
|
43882
|
+
function environmentRecordToEntries(env) {
|
|
43883
|
+
if (env === void 0) return [];
|
|
43884
|
+
return Object.entries(env).map(([name, value]) => `${name}=${value}`);
|
|
43885
|
+
}
|
|
43739
43886
|
/**
|
|
43740
43887
|
* Config is operator-writable, so malformed or duplicate rows are ignored
|
|
43741
43888
|
* rather than allowed to make declaration reconciliation destructive.
|
|
@@ -43935,6 +44082,108 @@ function findProfile(profiles, profileId) {
|
|
|
43935
44082
|
return profiles.find((p) => p.profileId === profileId);
|
|
43936
44083
|
}
|
|
43937
44084
|
//#endregion
|
|
44085
|
+
//#region src/profile-settings.ts
|
|
44086
|
+
var GLANCES_PLUGINS = [
|
|
44087
|
+
{
|
|
44088
|
+
key: "showCpu",
|
|
44089
|
+
plugin: "cpu",
|
|
44090
|
+
label: "CPU"
|
|
44091
|
+
},
|
|
44092
|
+
{
|
|
44093
|
+
key: "showMem",
|
|
44094
|
+
plugin: "mem",
|
|
44095
|
+
label: "Memory"
|
|
44096
|
+
},
|
|
44097
|
+
{
|
|
44098
|
+
key: "showLoad",
|
|
44099
|
+
plugin: "load",
|
|
44100
|
+
label: "Load"
|
|
44101
|
+
},
|
|
44102
|
+
{
|
|
44103
|
+
key: "showNetwork",
|
|
44104
|
+
plugin: "network",
|
|
44105
|
+
label: "Network"
|
|
44106
|
+
},
|
|
44107
|
+
{
|
|
44108
|
+
key: "showDiskIo",
|
|
44109
|
+
plugin: "diskio",
|
|
44110
|
+
label: "Disk I/O"
|
|
44111
|
+
},
|
|
44112
|
+
{
|
|
44113
|
+
key: "showFs",
|
|
44114
|
+
plugin: "fs",
|
|
44115
|
+
label: "Filesystems"
|
|
44116
|
+
},
|
|
44117
|
+
{
|
|
44118
|
+
key: "showProcessList",
|
|
44119
|
+
plugin: "processlist",
|
|
44120
|
+
label: "Process list"
|
|
44121
|
+
},
|
|
44122
|
+
{
|
|
44123
|
+
key: "showContainers",
|
|
44124
|
+
plugin: "containers",
|
|
44125
|
+
label: "Containers"
|
|
44126
|
+
},
|
|
44127
|
+
{
|
|
44128
|
+
key: "showSensors",
|
|
44129
|
+
plugin: "sensors",
|
|
44130
|
+
label: "Sensors"
|
|
44131
|
+
}
|
|
44132
|
+
];
|
|
44133
|
+
function glancesBooleanField(key, label) {
|
|
44134
|
+
return {
|
|
44135
|
+
type: "boolean",
|
|
44136
|
+
key,
|
|
44137
|
+
label,
|
|
44138
|
+
default: true,
|
|
44139
|
+
style: "switch"
|
|
44140
|
+
};
|
|
44141
|
+
}
|
|
44142
|
+
function glancesSettingsSchema() {
|
|
44143
|
+
return { sections: [{
|
|
44144
|
+
id: "glances-panels",
|
|
44145
|
+
title: "Glances panels",
|
|
44146
|
+
description: "Turn off a panel to pass --disable-plugin to this Terminal only. All on is the measured default (~1% of one core at the camera grid).",
|
|
44147
|
+
columns: 2,
|
|
44148
|
+
fields: GLANCES_PLUGINS.map((plugin) => glancesBooleanField(plugin.key, plugin.label))
|
|
44149
|
+
}] };
|
|
44150
|
+
}
|
|
44151
|
+
function settingsSchemaForProfile(profileId) {
|
|
44152
|
+
if (profileId === "glances") return glancesSettingsSchema();
|
|
44153
|
+
return null;
|
|
44154
|
+
}
|
|
44155
|
+
function glancesSettingsToArgs(settings) {
|
|
44156
|
+
const disabled = GLANCES_PLUGINS.filter((plugin) => settings[plugin.key] === false).map((plugin) => plugin.plugin);
|
|
44157
|
+
if (disabled.length === 0) return [];
|
|
44158
|
+
return ["--disable-plugin", disabled.join(",")];
|
|
44159
|
+
}
|
|
44160
|
+
function sanitizeProfileSettings(profileId, raw) {
|
|
44161
|
+
if (profileId !== "glances") return {};
|
|
44162
|
+
const bag = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
44163
|
+
const out = {
|
|
44164
|
+
showCpu: true,
|
|
44165
|
+
showMem: true,
|
|
44166
|
+
showLoad: true,
|
|
44167
|
+
showNetwork: true,
|
|
44168
|
+
showDiskIo: true,
|
|
44169
|
+
showFs: true,
|
|
44170
|
+
showProcessList: true,
|
|
44171
|
+
showContainers: true,
|
|
44172
|
+
showSensors: true
|
|
44173
|
+
};
|
|
44174
|
+
for (const plugin of GLANCES_PLUGINS) if (typeof bag[plugin.key] === "boolean") out[plugin.key] = bag[plugin.key];
|
|
44175
|
+
return out;
|
|
44176
|
+
}
|
|
44177
|
+
function profileSettingsToArgs(profileId, settings) {
|
|
44178
|
+
if (profileId !== "glances") return [];
|
|
44179
|
+
return glancesSettingsToArgs(sanitizeProfileSettings(profileId, settings));
|
|
44180
|
+
}
|
|
44181
|
+
function spawnArgsForInstance(input) {
|
|
44182
|
+
const extra = profileSettingsToArgs(input.profileId, input.profileSettings);
|
|
44183
|
+
if (input.instanceArgs.length > 0) return [...input.instanceArgs, ...extra];
|
|
44184
|
+
if (extra.length > 0) return [...input.profileArgs, ...extra];
|
|
44185
|
+
}
|
|
44186
|
+
//#endregion
|
|
43938
44187
|
//#region src/terminal-session-manager.ts
|
|
43939
44188
|
var MIN_GRID = 1;
|
|
43940
44189
|
var MAX_COLS = 1e3;
|
|
@@ -43999,7 +44248,12 @@ var TerminalSessionManager = class {
|
|
|
43999
44248
|
return this.profiles.map((p) => ({
|
|
44000
44249
|
profileId: p.profileId,
|
|
44001
44250
|
label: p.label,
|
|
44002
|
-
...p.description !== void 0 ? { description: p.description } : {}
|
|
44251
|
+
...p.description !== void 0 ? { description: p.description } : {},
|
|
44252
|
+
executable: p.file,
|
|
44253
|
+
args: [...p.args],
|
|
44254
|
+
cwd: p.cwd ?? "",
|
|
44255
|
+
environment: environmentRecordToEntries(p.env),
|
|
44256
|
+
settingsSchema: settingsSchemaForProfile(p.profileId)
|
|
44003
44257
|
}));
|
|
44004
44258
|
}
|
|
44005
44259
|
setInstanceControl(control) {
|
|
@@ -44011,6 +44265,9 @@ var TerminalSessionManager = class {
|
|
|
44011
44265
|
async createInstance(input) {
|
|
44012
44266
|
return this.requireInstanceControl().createInstance(input);
|
|
44013
44267
|
}
|
|
44268
|
+
async updateInstance(input) {
|
|
44269
|
+
return this.requireInstanceControl().updateInstance(input);
|
|
44270
|
+
}
|
|
44014
44271
|
async deleteInstance(input) {
|
|
44015
44272
|
await this.requireInstanceControl().deleteInstance(input);
|
|
44016
44273
|
}
|
|
@@ -44033,24 +44290,29 @@ var TerminalSessionManager = class {
|
|
|
44033
44290
|
const cols = clampDimension(input.cols, MAX_COLS);
|
|
44034
44291
|
const rows = clampDimension(input.rows, MAX_ROWS);
|
|
44035
44292
|
const sessionId = this.mintId();
|
|
44293
|
+
const file = input.executable?.trim() || profile.file;
|
|
44294
|
+
const args = input.args !== void 0 ? [...input.args] : [...profile.args];
|
|
44295
|
+
const cwd = input.cwd?.trim() || profile.cwd || this.opts.cwd;
|
|
44296
|
+
const env = {
|
|
44297
|
+
...this.opts.env,
|
|
44298
|
+
...profile.env,
|
|
44299
|
+
...environmentEntriesToRecord(input.environment ?? [])
|
|
44300
|
+
};
|
|
44036
44301
|
const executable = [{
|
|
44037
|
-
file
|
|
44038
|
-
args
|
|
44039
|
-
}, ...profile.fallbacks ?? []].map((candidate) => ({
|
|
44302
|
+
file,
|
|
44303
|
+
args
|
|
44304
|
+
}, ...input.executable?.trim() ? [] : profile.fallbacks ?? []].map((candidate) => ({
|
|
44040
44305
|
...candidate,
|
|
44041
44306
|
resolvedFile: this.resolveBinary(candidate.file)
|
|
44042
44307
|
})).find((candidate) => candidate.resolvedFile !== null);
|
|
44043
|
-
if (executable === void 0) throw new Error(`Terminal profile '${profile.profileId}' cannot start: executable '${
|
|
44308
|
+
if (executable === void 0) throw new Error(`Terminal profile '${profile.profileId}' cannot start: executable '${file}' was not found on PATH. Install it in the server image or set its path in Terminal settings.`);
|
|
44044
44309
|
const pty = this.opts.spawn({
|
|
44045
44310
|
file: executable.resolvedFile,
|
|
44046
44311
|
args: executable.args,
|
|
44047
44312
|
cols,
|
|
44048
44313
|
rows,
|
|
44049
|
-
...
|
|
44050
|
-
...
|
|
44051
|
-
...this.opts.env,
|
|
44052
|
-
...profile.env
|
|
44053
|
-
} } : {}
|
|
44314
|
+
...cwd !== void 0 && cwd !== "" ? { cwd } : {},
|
|
44315
|
+
...Object.keys(env).length > 0 ? { env } : {}
|
|
44054
44316
|
});
|
|
44055
44317
|
const screen = this.opts.screenFactory(cols, rows);
|
|
44056
44318
|
const info = {
|
|
@@ -44148,7 +44410,7 @@ var TerminalSessionManager = class {
|
|
|
44148
44410
|
const oldestSeq = session.output[0]?.seq ?? session.nextSeq;
|
|
44149
44411
|
if (input.afterSeq === 0 || input.afterSeq < oldestSeq - 1 || input.afterSeq > cursor) {
|
|
44150
44412
|
await session.screen.flush();
|
|
44151
|
-
const exit =
|
|
44413
|
+
const exit = session.output.toReversed().find((event) => event.kind === "exit");
|
|
44152
44414
|
return {
|
|
44153
44415
|
cursor,
|
|
44154
44416
|
reset: true,
|
|
@@ -44392,7 +44654,28 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44392
44654
|
const localNodeId = declarationOwnerNodeId(this.ctx.kernel.localNodeId);
|
|
44393
44655
|
const cameraRelay = new TerminalCameraRelay({
|
|
44394
44656
|
listProfiles: (nodeId) => nodeId === localNodeId ? manager.listProfiles() : this.ctx.api.terminalSession.listProfiles.query(void 0, nodePin(nodeId)),
|
|
44395
|
-
openSession: (nodeId, input) =>
|
|
44657
|
+
openSession: async (nodeId, input) => {
|
|
44658
|
+
const instance = input.instanceId ? this.terminalInstances().find((row) => row.id === input.instanceId) : void 0;
|
|
44659
|
+
const profile = (nodeId === localNodeId ? await manager.listProfiles() : await this.ctx.api.terminalSession.listProfiles.query(void 0, nodePin(nodeId))).find((candidate) => candidate.profileId === (instance?.profileId ?? input.profileId));
|
|
44660
|
+
const args = instance ? spawnArgsForInstance({
|
|
44661
|
+
profileId: instance.profileId,
|
|
44662
|
+
instanceArgs: instance.args,
|
|
44663
|
+
profileArgs: profile?.args ?? [],
|
|
44664
|
+
profileSettings: instance.profileSettings
|
|
44665
|
+
}) : void 0;
|
|
44666
|
+
const payload = {
|
|
44667
|
+
profileId: input.profileId,
|
|
44668
|
+
cols: input.cols,
|
|
44669
|
+
rows: input.rows,
|
|
44670
|
+
...instance ? {
|
|
44671
|
+
...instance.executable ? { executable: instance.executable } : {},
|
|
44672
|
+
...args !== void 0 ? { args: [...args] } : {},
|
|
44673
|
+
...instance.cwd ? { cwd: instance.cwd } : {},
|
|
44674
|
+
...instance.environment.length > 0 ? { environment: [...instance.environment] } : {}
|
|
44675
|
+
} : {}
|
|
44676
|
+
};
|
|
44677
|
+
return nodeId === localNodeId ? manager.openSession(payload) : this.ctx.api.terminalSession.openSession.mutate(payload, nodePin(nodeId));
|
|
44678
|
+
},
|
|
44396
44679
|
pullOutput: (nodeId, input) => nodeId === localNodeId ? manager.pullOutput(input) : this.ctx.api.terminalSession.pullOutput.mutate(input, nodePin(nodeId)),
|
|
44397
44680
|
closeSession: async (nodeId, sessionId) => {
|
|
44398
44681
|
if (nodeId === localNodeId) await manager.close({ sessionId });
|
|
@@ -44597,6 +44880,7 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44597
44880
|
return {
|
|
44598
44881
|
listInstances: async () => this.terminalInstances().map((instance) => this.instanceInfo(instance)),
|
|
44599
44882
|
createInstance: async (input) => this.createTerminalInstance(input),
|
|
44883
|
+
updateInstance: async (input) => this.updateTerminalInstance(input),
|
|
44600
44884
|
deleteInstance: async ({ instanceId }) => this.deleteTerminalInstance(instanceId),
|
|
44601
44885
|
setInstanceEnabled: async ({ instanceId, enabled }) => this.setTerminalInstanceEnabled(instanceId, enabled),
|
|
44602
44886
|
listLegacyCameras: async () => this.listLegacyTerminalCameras(),
|
|
@@ -44616,7 +44900,12 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44616
44900
|
profileId: instance.profileId,
|
|
44617
44901
|
profileLabel: instance.profileLabel,
|
|
44618
44902
|
name: instance.name,
|
|
44619
|
-
enabled: instance.enabled
|
|
44903
|
+
enabled: instance.enabled,
|
|
44904
|
+
executable: instance.executable,
|
|
44905
|
+
args: instance.args,
|
|
44906
|
+
cwd: instance.cwd,
|
|
44907
|
+
environment: instance.environment,
|
|
44908
|
+
profileSettings: instance.profileSettings
|
|
44620
44909
|
};
|
|
44621
44910
|
}
|
|
44622
44911
|
replaceTerminalCameraTombstones(stableIds) {
|
|
@@ -44644,11 +44933,37 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44644
44933
|
profileId: profile.profileId,
|
|
44645
44934
|
profileLabel: profile.label,
|
|
44646
44935
|
name,
|
|
44647
|
-
enabled: true
|
|
44936
|
+
enabled: true,
|
|
44937
|
+
executable: input.executable?.trim() || profile.executable || "",
|
|
44938
|
+
args: input.args ? [...input.args] : [...profile.args ?? []],
|
|
44939
|
+
cwd: input.cwd?.trim() || profile.cwd || "",
|
|
44940
|
+
environment: input.environment ? [...input.environment] : [...profile.environment ?? []],
|
|
44941
|
+
profileSettings: sanitizeProfileSettings(profile.profileId, input.profileSettings)
|
|
44648
44942
|
};
|
|
44649
44943
|
await this.updateGlobalSettings({ terminalInstances: [...this.config.terminalInstances, instance] });
|
|
44650
44944
|
return this.instanceInfo(instance);
|
|
44651
44945
|
}
|
|
44946
|
+
async updateTerminalInstance(input) {
|
|
44947
|
+
const updated = await this.instanceMutationQueue.run(() => this.updateTerminalInstanceUnlocked(input));
|
|
44948
|
+
await this.cameraRelay?.closeInstance(updated.instanceId);
|
|
44949
|
+
await this.reconcileTerminalCameras();
|
|
44950
|
+
return updated;
|
|
44951
|
+
}
|
|
44952
|
+
async updateTerminalInstanceUnlocked(input) {
|
|
44953
|
+
const instance = this.terminalInstances().find((candidate) => candidate.id === input.instanceId);
|
|
44954
|
+
if (!instance) throw new Error(`No such Terminal instance: ${input.instanceId}`);
|
|
44955
|
+
const updated = {
|
|
44956
|
+
...instance,
|
|
44957
|
+
...input.name !== void 0 ? { name: input.name.trim() } : {},
|
|
44958
|
+
...input.executable !== void 0 ? { executable: input.executable.trim() } : {},
|
|
44959
|
+
...input.args !== void 0 ? { args: [...input.args] } : {},
|
|
44960
|
+
...input.cwd !== void 0 ? { cwd: input.cwd.trim() } : {},
|
|
44961
|
+
...input.environment !== void 0 ? { environment: [...input.environment] } : {},
|
|
44962
|
+
...input.profileSettings !== void 0 ? { profileSettings: sanitizeProfileSettings(instance.profileId, input.profileSettings) } : {}
|
|
44963
|
+
};
|
|
44964
|
+
await this.updateGlobalSettings({ terminalInstances: this.config.terminalInstances.map((candidate) => candidate.id === input.instanceId ? updated : candidate) });
|
|
44965
|
+
return this.instanceInfo(updated);
|
|
44966
|
+
}
|
|
44652
44967
|
async deleteTerminalInstance(instanceId) {
|
|
44653
44968
|
await this.instanceMutationQueue.run(() => this.deleteTerminalInstanceUnlocked(instanceId));
|
|
44654
44969
|
await this.reconcileTerminalCameras();
|
|
@@ -44708,7 +45023,12 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44708
45023
|
profileId: "monitor",
|
|
44709
45024
|
profileLabel: legacy.profileLabel,
|
|
44710
45025
|
name: requestedName?.trim() || legacy.name,
|
|
44711
|
-
enabled: true
|
|
45026
|
+
enabled: true,
|
|
45027
|
+
executable: "",
|
|
45028
|
+
args: [],
|
|
45029
|
+
cwd: "",
|
|
45030
|
+
environment: [],
|
|
45031
|
+
profileSettings: {}
|
|
44712
45032
|
};
|
|
44713
45033
|
await this.updateGlobalSettings({ terminalInstances: [...this.config.terminalInstances, instance] });
|
|
44714
45034
|
return this.instanceInfo(instance);
|
|
@@ -44947,7 +45267,7 @@ exports.buildCellRuns = buildCellRuns;
|
|
|
44947
45267
|
exports.buildProfiles = buildProfiles;
|
|
44948
45268
|
exports.createNodePtySpawner = createNodePtySpawner;
|
|
44949
45269
|
exports.createTerminalDataPlaneHandler = createTerminalDataPlaneHandler;
|
|
44950
|
-
exports.createXtermScreen = createXtermScreen;
|
|
45270
|
+
exports.createXtermScreen = createXtermScreen$1;
|
|
44951
45271
|
exports.findProfile = findProfile;
|
|
44952
45272
|
exports.resolveCellStyle = resolveCellStyle;
|
|
44953
45273
|
exports.terminalPaletteColor = terminalPaletteColor;
|
package/dist/addon.mjs
CHANGED
|
@@ -19980,6 +19980,9 @@ method(_void(), ProviderInfoSchema), method(object({ config: record(string(), un
|
|
|
19980
19980
|
location: StorageLocationSchema,
|
|
19981
19981
|
relativePath: string()
|
|
19982
19982
|
}), _void(), { kind: "mutation" }), method(object({ location: StorageLocationSchema }), number().nullable()), method(BeginUploadInputSchema, BeginUploadResultSchema, { kind: "mutation" }), method(WriteChunkInputSchema, _void(), { kind: "mutation" }), method(FinalizeUploadInputSchema, _void(), { kind: "mutation" }), method(AbortUploadInputSchema, _void(), { kind: "mutation" }), method(BeginDownloadInputSchema, BeginDownloadResultSchema, { kind: "mutation" }), method(ReadChunkInputSchema, _instanceof(Uint8Array)), method(EndDownloadInputSchema, _void(), { kind: "mutation" });
|
|
19983
|
+
/** Profile-exported FormBuilder schema. Shape is ConfigUISchema at the UI. */
|
|
19984
|
+
var ProfileSettingsSchemaBridge = unknown().nullable();
|
|
19985
|
+
var ProfileSettingsBagSchema = record(string(), unknown());
|
|
19983
19986
|
/**
|
|
19984
19987
|
* A live terminal session hosted by the provider addon. Output and input do
|
|
19985
19988
|
* NOT flow through the capability — they use the addon data plane
|
|
@@ -20009,7 +20012,14 @@ var TerminalSessionInfoSchema = object({
|
|
|
20009
20012
|
var TerminalProfileInfoSchema = object({
|
|
20010
20013
|
profileId: string(),
|
|
20011
20014
|
label: string(),
|
|
20012
|
-
description: string().optional()
|
|
20015
|
+
description: string().optional(),
|
|
20016
|
+
/** Spawn defaults the instance form copies on create. */
|
|
20017
|
+
executable: string().optional(),
|
|
20018
|
+
args: array(string()).readonly().optional(),
|
|
20019
|
+
cwd: string().optional(),
|
|
20020
|
+
environment: array(string()).readonly().optional(),
|
|
20021
|
+
/** ConfigUISchema for instance knobs, or null when the profile has none. */
|
|
20022
|
+
settingsSchema: ProfileSettingsSchemaBridge.optional()
|
|
20013
20023
|
});
|
|
20014
20024
|
/**
|
|
20015
20025
|
* A durable operator-created Terminal instance. Profiles are templates; only
|
|
@@ -20022,7 +20032,12 @@ var TerminalInstanceInfoSchema = object({
|
|
|
20022
20032
|
profileId: string(),
|
|
20023
20033
|
profileLabel: string(),
|
|
20024
20034
|
name: string(),
|
|
20025
|
-
enabled: boolean()
|
|
20035
|
+
enabled: boolean(),
|
|
20036
|
+
executable: string(),
|
|
20037
|
+
args: array(string()).readonly(),
|
|
20038
|
+
cwd: string(),
|
|
20039
|
+
environment: array(string()).readonly(),
|
|
20040
|
+
profileSettings: ProfileSettingsBagSchema
|
|
20026
20041
|
});
|
|
20027
20042
|
var TerminalLegacyCameraSchema = object({
|
|
20028
20043
|
stableId: string(),
|
|
@@ -20068,7 +20083,24 @@ var terminalSessionCapability = {
|
|
|
20068
20083
|
createInstance: method(object({
|
|
20069
20084
|
targetNodeId: string().min(1),
|
|
20070
20085
|
profileId: string().min(1),
|
|
20071
|
-
name: string().trim().min(1).max(160).optional()
|
|
20086
|
+
name: string().trim().min(1).max(160).optional(),
|
|
20087
|
+
executable: string().max(1024).optional(),
|
|
20088
|
+
args: array(string().max(2048)).max(64).optional(),
|
|
20089
|
+
cwd: string().max(1024).optional(),
|
|
20090
|
+
environment: array(string().max(4096)).max(64).optional(),
|
|
20091
|
+
profileSettings: ProfileSettingsBagSchema.optional()
|
|
20092
|
+
}), TerminalInstanceInfoSchema, {
|
|
20093
|
+
kind: "mutation",
|
|
20094
|
+
auth: "admin"
|
|
20095
|
+
}),
|
|
20096
|
+
updateInstance: method(object({
|
|
20097
|
+
instanceId: string().min(1),
|
|
20098
|
+
name: string().trim().min(1).max(160).optional(),
|
|
20099
|
+
executable: string().max(1024).optional(),
|
|
20100
|
+
args: array(string().max(2048)).max(64).optional(),
|
|
20101
|
+
cwd: string().max(1024).optional(),
|
|
20102
|
+
environment: array(string().max(4096)).max(64).optional(),
|
|
20103
|
+
profileSettings: ProfileSettingsBagSchema.optional()
|
|
20072
20104
|
}), TerminalInstanceInfoSchema, {
|
|
20073
20105
|
kind: "mutation",
|
|
20074
20106
|
auth: "admin"
|
|
@@ -20103,7 +20135,11 @@ var terminalSessionCapability = {
|
|
|
20103
20135
|
openSession: method(object({
|
|
20104
20136
|
profileId: string(),
|
|
20105
20137
|
cols: number().int().positive(),
|
|
20106
|
-
rows: number().int().positive()
|
|
20138
|
+
rows: number().int().positive(),
|
|
20139
|
+
executable: string().max(1024).optional(),
|
|
20140
|
+
args: array(string().max(2048)).max(64).optional(),
|
|
20141
|
+
cwd: string().max(1024).optional(),
|
|
20142
|
+
environment: array(string().max(4096)).max(64).optional()
|
|
20107
20143
|
}), TerminalSessionInfoSchema, {
|
|
20108
20144
|
kind: "mutation",
|
|
20109
20145
|
auth: "admin"
|
|
@@ -23992,10 +24028,10 @@ var lawnMowerControlCapability = {
|
|
|
23992
24028
|
*
|
|
23993
24029
|
* • The SDK (mobile / web client) consumes `getConnectionEndpoints()`
|
|
23994
24030
|
* to receive an ordered list of candidate base URLs it should race
|
|
23995
|
-
* on connect — LAN IPv4 first (lowest latency
|
|
23996
|
-
* then public hostname (if a tunnel is
|
|
23997
|
-
* race them with short timeouts and stick with the
|
|
23998
|
-
* session.
|
|
24031
|
+
* on connect — LAN IPv4 and stable LAN IPv6 first (lowest latency
|
|
24032
|
+
* when on the same network), then public hostname (if a tunnel is
|
|
24033
|
+
* up). The SDK can race them with short timeouts and stick with the
|
|
24034
|
+
* winner for the session.
|
|
23999
24035
|
*
|
|
24000
24036
|
* Why hub-only: agents are not directly addressable by the operator's
|
|
24001
24037
|
* clients — they reverse-connect to the hub. Exposing their interfaces
|
|
@@ -24158,6 +24194,20 @@ var AllowedAddressesSchema = object({
|
|
|
24158
24194
|
* Network Addresses admin page and persisted by the addon.
|
|
24159
24195
|
*/
|
|
24160
24196
|
addresses: array(string()).readonly() });
|
|
24197
|
+
var TlsStatusSchema = object({
|
|
24198
|
+
mode: _enum([
|
|
24199
|
+
"generated",
|
|
24200
|
+
"uploaded",
|
|
24201
|
+
"disabled"
|
|
24202
|
+
]),
|
|
24203
|
+
leafFingerprintSha256: string().nullable(),
|
|
24204
|
+
caFingerprintSha256: string().nullable(),
|
|
24205
|
+
validTo: string().nullable(),
|
|
24206
|
+
sans: array(string()),
|
|
24207
|
+
caCertPem: string().nullable(),
|
|
24208
|
+
reissueError: string().nullable(),
|
|
24209
|
+
restartRequired: boolean()
|
|
24210
|
+
});
|
|
24161
24211
|
method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(object({
|
|
24162
24212
|
/**
|
|
24163
24213
|
* LEGACY HINT — do not send from new code. Kept optional so clients
|
|
@@ -24177,7 +24227,20 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
24177
24227
|
* to avoid mixed-content blocks in the browser. The public
|
|
24178
24228
|
* tunnel always emits `https://` regardless. */
|
|
24179
24229
|
scheme: _enum(["http", "https"]).optional()
|
|
24180
|
-
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" })
|
|
24230
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
24231
|
+
kind: "mutation",
|
|
24232
|
+
auth: "admin"
|
|
24233
|
+
}), method(object({
|
|
24234
|
+
certPem: string().min(1),
|
|
24235
|
+
keyPem: string().min(1),
|
|
24236
|
+
caPem: string().optional()
|
|
24237
|
+
}), TlsStatusSchema, {
|
|
24238
|
+
kind: "mutation",
|
|
24239
|
+
auth: "admin"
|
|
24240
|
+
}), method(_void(), object({ pem: string() })), method(_void(), TlsStatusSchema, {
|
|
24241
|
+
kind: "mutation",
|
|
24242
|
+
auth: "admin"
|
|
24243
|
+
});
|
|
24181
24244
|
var LockControlStatusSchema = object({
|
|
24182
24245
|
/** Lifecycle state of the lock. `jammed` means the motor reported
|
|
24183
24246
|
* failure to reach the target — operator intervention required. */
|
|
@@ -32202,6 +32265,12 @@ Object.freeze({
|
|
|
32202
32265
|
addonId: null,
|
|
32203
32266
|
access: "create"
|
|
32204
32267
|
},
|
|
32268
|
+
"localNetwork.downloadCa": {
|
|
32269
|
+
capName: "local-network",
|
|
32270
|
+
capScope: "system",
|
|
32271
|
+
addonId: null,
|
|
32272
|
+
access: "view"
|
|
32273
|
+
},
|
|
32205
32274
|
"localNetwork.getAllowedAddresses": {
|
|
32206
32275
|
capName: "local-network",
|
|
32207
32276
|
capScope: "system",
|
|
@@ -32226,18 +32295,36 @@ Object.freeze({
|
|
|
32226
32295
|
addonId: null,
|
|
32227
32296
|
access: "view"
|
|
32228
32297
|
},
|
|
32298
|
+
"localNetwork.getTlsStatus": {
|
|
32299
|
+
capName: "local-network",
|
|
32300
|
+
capScope: "system",
|
|
32301
|
+
addonId: null,
|
|
32302
|
+
access: "view"
|
|
32303
|
+
},
|
|
32229
32304
|
"localNetwork.list": {
|
|
32230
32305
|
capName: "local-network",
|
|
32231
32306
|
capScope: "system",
|
|
32232
32307
|
addonId: null,
|
|
32233
32308
|
access: "view"
|
|
32234
32309
|
},
|
|
32310
|
+
"localNetwork.regenerateCertificate": {
|
|
32311
|
+
capName: "local-network",
|
|
32312
|
+
capScope: "system",
|
|
32313
|
+
addonId: null,
|
|
32314
|
+
access: "create"
|
|
32315
|
+
},
|
|
32235
32316
|
"localNetwork.resetAllowlistToBestMatch": {
|
|
32236
32317
|
capName: "local-network",
|
|
32237
32318
|
capScope: "system",
|
|
32238
32319
|
addonId: null,
|
|
32239
32320
|
access: "delete"
|
|
32240
32321
|
},
|
|
32322
|
+
"localNetwork.revertToGeneratedCertificate": {
|
|
32323
|
+
capName: "local-network",
|
|
32324
|
+
capScope: "system",
|
|
32325
|
+
addonId: null,
|
|
32326
|
+
access: "create"
|
|
32327
|
+
},
|
|
32241
32328
|
"localNetwork.setAllowedAddresses": {
|
|
32242
32329
|
capName: "local-network",
|
|
32243
32330
|
capScope: "system",
|
|
@@ -32250,6 +32337,12 @@ Object.freeze({
|
|
|
32250
32337
|
addonId: null,
|
|
32251
32338
|
access: "create"
|
|
32252
32339
|
},
|
|
32340
|
+
"localNetwork.uploadCertificate": {
|
|
32341
|
+
capName: "local-network",
|
|
32342
|
+
capScope: "system",
|
|
32343
|
+
addonId: null,
|
|
32344
|
+
access: "create"
|
|
32345
|
+
},
|
|
32253
32346
|
"lockControl.lock": {
|
|
32254
32347
|
capName: "lock-control",
|
|
32255
32348
|
capScope: "device",
|
|
@@ -35130,6 +35223,12 @@ Object.freeze({
|
|
|
35130
35223
|
addonId: null,
|
|
35131
35224
|
access: "create"
|
|
35132
35225
|
},
|
|
35226
|
+
"terminalSession.updateInstance": {
|
|
35227
|
+
capName: "terminal-session",
|
|
35228
|
+
capScope: "system",
|
|
35229
|
+
addonId: null,
|
|
35230
|
+
access: "create"
|
|
35231
|
+
},
|
|
35133
35232
|
"terminalSession.writeInput": {
|
|
35134
35233
|
capName: "terminal-session",
|
|
35135
35234
|
capScope: "system",
|
|
@@ -37617,6 +37716,35 @@ Object.freeze(Object.fromEntries([{
|
|
|
37617
37716
|
}]
|
|
37618
37717
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
37619
37718
|
string().min(1);
|
|
37719
|
+
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
37720
|
+
stepId: "face-embedding",
|
|
37721
|
+
key: "minLandmarkFaceSize",
|
|
37722
|
+
label: "Min face size for recognition (detection px)",
|
|
37723
|
+
description: "Refuse to embed a face smaller than this IN THE DETECTION FRAME. Applies to every node — the enrolled gallery is one index, and two admission floors would fill it from two policies. 0 disables the gate.",
|
|
37724
|
+
type: "slider",
|
|
37725
|
+
min: 0,
|
|
37726
|
+
max: 64,
|
|
37727
|
+
step: 2,
|
|
37728
|
+
default: 24
|
|
37729
|
+
}];
|
|
37730
|
+
function clusterStepSettingKey(stepId, fieldKey) {
|
|
37731
|
+
return `clusterStepSetting:${stepId}:${fieldKey}`;
|
|
37732
|
+
}
|
|
37733
|
+
var ClusterSettingNumberSchema = number().finite();
|
|
37734
|
+
function readClusterStepSettings(config) {
|
|
37735
|
+
const out = {};
|
|
37736
|
+
for (const field of CLUSTER_STEP_SETTING_FIELDS) {
|
|
37737
|
+
const parsed = ClusterSettingNumberSchema.safeParse(config[clusterStepSettingKey(field.stepId, field.key)]);
|
|
37738
|
+
const value = parsed.success ? parsed.data : field.default;
|
|
37739
|
+
const existing = out[field.stepId] ?? {};
|
|
37740
|
+
out[field.stepId] = {
|
|
37741
|
+
...existing,
|
|
37742
|
+
[field.key]: value
|
|
37743
|
+
};
|
|
37744
|
+
}
|
|
37745
|
+
return out;
|
|
37746
|
+
}
|
|
37747
|
+
readClusterStepSettings({});
|
|
37620
37748
|
object({
|
|
37621
37749
|
/**
|
|
37622
37750
|
* Fraction of the box's own size added on EACH side before cutting.
|
|
@@ -43149,7 +43277,7 @@ var require_xterm_headless = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
43149
43277
|
var import_addon_serialize = require_addon_serialize();
|
|
43150
43278
|
var import_xterm_headless = require_xterm_headless();
|
|
43151
43279
|
var SCROLLBACK_LINES = 2e3;
|
|
43152
|
-
function createXtermScreen(cols, rows) {
|
|
43280
|
+
function createXtermScreen$1(cols, rows) {
|
|
43153
43281
|
const term = new import_xterm_headless.Terminal({
|
|
43154
43282
|
cols,
|
|
43155
43283
|
rows,
|
|
@@ -43293,7 +43421,7 @@ var TerminalCameraRelay = class {
|
|
|
43293
43421
|
instanceId,
|
|
43294
43422
|
nodeId,
|
|
43295
43423
|
profileId,
|
|
43296
|
-
screen: createXtermScreen(120, 40),
|
|
43424
|
+
screen: createXtermScreen$1(120, 40),
|
|
43297
43425
|
sessionId: null,
|
|
43298
43426
|
cursor: 0,
|
|
43299
43427
|
clients: 0,
|
|
@@ -43324,7 +43452,8 @@ var TerminalCameraRelay = class {
|
|
|
43324
43452
|
const opening = this.api.openSession(state.nodeId, {
|
|
43325
43453
|
profileId: state.profileId,
|
|
43326
43454
|
cols: 120,
|
|
43327
|
-
rows: 40
|
|
43455
|
+
rows: 40,
|
|
43456
|
+
instanceId: state.instanceId
|
|
43328
43457
|
});
|
|
43329
43458
|
state.openPromise = opening;
|
|
43330
43459
|
try {
|
|
@@ -43349,7 +43478,7 @@ var TerminalCameraRelay = class {
|
|
|
43349
43478
|
applyBatch(state, batch) {
|
|
43350
43479
|
if (batch.reset) {
|
|
43351
43480
|
state.screen.dispose();
|
|
43352
|
-
state.screen = createXtermScreen(120, 40);
|
|
43481
|
+
state.screen = createXtermScreen$1(120, 40);
|
|
43353
43482
|
if (batch.snapshot) state.screen.write(batch.snapshot);
|
|
43354
43483
|
}
|
|
43355
43484
|
let exited = false;
|
|
@@ -43711,8 +43840,26 @@ var TerminalInstanceSchema = object({
|
|
|
43711
43840
|
profileId: string().min(1).max(64),
|
|
43712
43841
|
profileLabel: string().min(1).max(120),
|
|
43713
43842
|
name: string().min(1).max(160),
|
|
43714
|
-
enabled: boolean()
|
|
43843
|
+
enabled: boolean(),
|
|
43844
|
+
executable: string().max(1024).default(""),
|
|
43845
|
+
args: array(string().max(2048)).max(64).default([]),
|
|
43846
|
+
cwd: string().max(1024).default(""),
|
|
43847
|
+
environment: array(string().max(4096)).max(64).default([]),
|
|
43848
|
+
profileSettings: record(string(), unknown()).default({})
|
|
43715
43849
|
});
|
|
43850
|
+
function environmentEntriesToRecord(entries) {
|
|
43851
|
+
const out = {};
|
|
43852
|
+
for (const entry of entries) {
|
|
43853
|
+
const eq = entry.indexOf("=");
|
|
43854
|
+
if (eq <= 0) continue;
|
|
43855
|
+
out[entry.slice(0, eq)] = entry.slice(eq + 1);
|
|
43856
|
+
}
|
|
43857
|
+
return out;
|
|
43858
|
+
}
|
|
43859
|
+
function environmentRecordToEntries(env) {
|
|
43860
|
+
if (env === void 0) return [];
|
|
43861
|
+
return Object.entries(env).map(([name, value]) => `${name}=${value}`);
|
|
43862
|
+
}
|
|
43716
43863
|
/**
|
|
43717
43864
|
* Config is operator-writable, so malformed or duplicate rows are ignored
|
|
43718
43865
|
* rather than allowed to make declaration reconciliation destructive.
|
|
@@ -43912,6 +44059,108 @@ function findProfile(profiles, profileId) {
|
|
|
43912
44059
|
return profiles.find((p) => p.profileId === profileId);
|
|
43913
44060
|
}
|
|
43914
44061
|
//#endregion
|
|
44062
|
+
//#region src/profile-settings.ts
|
|
44063
|
+
var GLANCES_PLUGINS = [
|
|
44064
|
+
{
|
|
44065
|
+
key: "showCpu",
|
|
44066
|
+
plugin: "cpu",
|
|
44067
|
+
label: "CPU"
|
|
44068
|
+
},
|
|
44069
|
+
{
|
|
44070
|
+
key: "showMem",
|
|
44071
|
+
plugin: "mem",
|
|
44072
|
+
label: "Memory"
|
|
44073
|
+
},
|
|
44074
|
+
{
|
|
44075
|
+
key: "showLoad",
|
|
44076
|
+
plugin: "load",
|
|
44077
|
+
label: "Load"
|
|
44078
|
+
},
|
|
44079
|
+
{
|
|
44080
|
+
key: "showNetwork",
|
|
44081
|
+
plugin: "network",
|
|
44082
|
+
label: "Network"
|
|
44083
|
+
},
|
|
44084
|
+
{
|
|
44085
|
+
key: "showDiskIo",
|
|
44086
|
+
plugin: "diskio",
|
|
44087
|
+
label: "Disk I/O"
|
|
44088
|
+
},
|
|
44089
|
+
{
|
|
44090
|
+
key: "showFs",
|
|
44091
|
+
plugin: "fs",
|
|
44092
|
+
label: "Filesystems"
|
|
44093
|
+
},
|
|
44094
|
+
{
|
|
44095
|
+
key: "showProcessList",
|
|
44096
|
+
plugin: "processlist",
|
|
44097
|
+
label: "Process list"
|
|
44098
|
+
},
|
|
44099
|
+
{
|
|
44100
|
+
key: "showContainers",
|
|
44101
|
+
plugin: "containers",
|
|
44102
|
+
label: "Containers"
|
|
44103
|
+
},
|
|
44104
|
+
{
|
|
44105
|
+
key: "showSensors",
|
|
44106
|
+
plugin: "sensors",
|
|
44107
|
+
label: "Sensors"
|
|
44108
|
+
}
|
|
44109
|
+
];
|
|
44110
|
+
function glancesBooleanField(key, label) {
|
|
44111
|
+
return {
|
|
44112
|
+
type: "boolean",
|
|
44113
|
+
key,
|
|
44114
|
+
label,
|
|
44115
|
+
default: true,
|
|
44116
|
+
style: "switch"
|
|
44117
|
+
};
|
|
44118
|
+
}
|
|
44119
|
+
function glancesSettingsSchema() {
|
|
44120
|
+
return { sections: [{
|
|
44121
|
+
id: "glances-panels",
|
|
44122
|
+
title: "Glances panels",
|
|
44123
|
+
description: "Turn off a panel to pass --disable-plugin to this Terminal only. All on is the measured default (~1% of one core at the camera grid).",
|
|
44124
|
+
columns: 2,
|
|
44125
|
+
fields: GLANCES_PLUGINS.map((plugin) => glancesBooleanField(plugin.key, plugin.label))
|
|
44126
|
+
}] };
|
|
44127
|
+
}
|
|
44128
|
+
function settingsSchemaForProfile(profileId) {
|
|
44129
|
+
if (profileId === "glances") return glancesSettingsSchema();
|
|
44130
|
+
return null;
|
|
44131
|
+
}
|
|
44132
|
+
function glancesSettingsToArgs(settings) {
|
|
44133
|
+
const disabled = GLANCES_PLUGINS.filter((plugin) => settings[plugin.key] === false).map((plugin) => plugin.plugin);
|
|
44134
|
+
if (disabled.length === 0) return [];
|
|
44135
|
+
return ["--disable-plugin", disabled.join(",")];
|
|
44136
|
+
}
|
|
44137
|
+
function sanitizeProfileSettings(profileId, raw) {
|
|
44138
|
+
if (profileId !== "glances") return {};
|
|
44139
|
+
const bag = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
44140
|
+
const out = {
|
|
44141
|
+
showCpu: true,
|
|
44142
|
+
showMem: true,
|
|
44143
|
+
showLoad: true,
|
|
44144
|
+
showNetwork: true,
|
|
44145
|
+
showDiskIo: true,
|
|
44146
|
+
showFs: true,
|
|
44147
|
+
showProcessList: true,
|
|
44148
|
+
showContainers: true,
|
|
44149
|
+
showSensors: true
|
|
44150
|
+
};
|
|
44151
|
+
for (const plugin of GLANCES_PLUGINS) if (typeof bag[plugin.key] === "boolean") out[plugin.key] = bag[plugin.key];
|
|
44152
|
+
return out;
|
|
44153
|
+
}
|
|
44154
|
+
function profileSettingsToArgs(profileId, settings) {
|
|
44155
|
+
if (profileId !== "glances") return [];
|
|
44156
|
+
return glancesSettingsToArgs(sanitizeProfileSettings(profileId, settings));
|
|
44157
|
+
}
|
|
44158
|
+
function spawnArgsForInstance(input) {
|
|
44159
|
+
const extra = profileSettingsToArgs(input.profileId, input.profileSettings);
|
|
44160
|
+
if (input.instanceArgs.length > 0) return [...input.instanceArgs, ...extra];
|
|
44161
|
+
if (extra.length > 0) return [...input.profileArgs, ...extra];
|
|
44162
|
+
}
|
|
44163
|
+
//#endregion
|
|
43915
44164
|
//#region src/terminal-session-manager.ts
|
|
43916
44165
|
var MIN_GRID = 1;
|
|
43917
44166
|
var MAX_COLS = 1e3;
|
|
@@ -43976,7 +44225,12 @@ var TerminalSessionManager = class {
|
|
|
43976
44225
|
return this.profiles.map((p) => ({
|
|
43977
44226
|
profileId: p.profileId,
|
|
43978
44227
|
label: p.label,
|
|
43979
|
-
...p.description !== void 0 ? { description: p.description } : {}
|
|
44228
|
+
...p.description !== void 0 ? { description: p.description } : {},
|
|
44229
|
+
executable: p.file,
|
|
44230
|
+
args: [...p.args],
|
|
44231
|
+
cwd: p.cwd ?? "",
|
|
44232
|
+
environment: environmentRecordToEntries(p.env),
|
|
44233
|
+
settingsSchema: settingsSchemaForProfile(p.profileId)
|
|
43980
44234
|
}));
|
|
43981
44235
|
}
|
|
43982
44236
|
setInstanceControl(control) {
|
|
@@ -43988,6 +44242,9 @@ var TerminalSessionManager = class {
|
|
|
43988
44242
|
async createInstance(input) {
|
|
43989
44243
|
return this.requireInstanceControl().createInstance(input);
|
|
43990
44244
|
}
|
|
44245
|
+
async updateInstance(input) {
|
|
44246
|
+
return this.requireInstanceControl().updateInstance(input);
|
|
44247
|
+
}
|
|
43991
44248
|
async deleteInstance(input) {
|
|
43992
44249
|
await this.requireInstanceControl().deleteInstance(input);
|
|
43993
44250
|
}
|
|
@@ -44010,24 +44267,29 @@ var TerminalSessionManager = class {
|
|
|
44010
44267
|
const cols = clampDimension(input.cols, MAX_COLS);
|
|
44011
44268
|
const rows = clampDimension(input.rows, MAX_ROWS);
|
|
44012
44269
|
const sessionId = this.mintId();
|
|
44270
|
+
const file = input.executable?.trim() || profile.file;
|
|
44271
|
+
const args = input.args !== void 0 ? [...input.args] : [...profile.args];
|
|
44272
|
+
const cwd = input.cwd?.trim() || profile.cwd || this.opts.cwd;
|
|
44273
|
+
const env = {
|
|
44274
|
+
...this.opts.env,
|
|
44275
|
+
...profile.env,
|
|
44276
|
+
...environmentEntriesToRecord(input.environment ?? [])
|
|
44277
|
+
};
|
|
44013
44278
|
const executable = [{
|
|
44014
|
-
file
|
|
44015
|
-
args
|
|
44016
|
-
}, ...profile.fallbacks ?? []].map((candidate) => ({
|
|
44279
|
+
file,
|
|
44280
|
+
args
|
|
44281
|
+
}, ...input.executable?.trim() ? [] : profile.fallbacks ?? []].map((candidate) => ({
|
|
44017
44282
|
...candidate,
|
|
44018
44283
|
resolvedFile: this.resolveBinary(candidate.file)
|
|
44019
44284
|
})).find((candidate) => candidate.resolvedFile !== null);
|
|
44020
|
-
if (executable === void 0) throw new Error(`Terminal profile '${profile.profileId}' cannot start: executable '${
|
|
44285
|
+
if (executable === void 0) throw new Error(`Terminal profile '${profile.profileId}' cannot start: executable '${file}' was not found on PATH. Install it in the server image or set its path in Terminal settings.`);
|
|
44021
44286
|
const pty = this.opts.spawn({
|
|
44022
44287
|
file: executable.resolvedFile,
|
|
44023
44288
|
args: executable.args,
|
|
44024
44289
|
cols,
|
|
44025
44290
|
rows,
|
|
44026
|
-
...
|
|
44027
|
-
...
|
|
44028
|
-
...this.opts.env,
|
|
44029
|
-
...profile.env
|
|
44030
|
-
} } : {}
|
|
44291
|
+
...cwd !== void 0 && cwd !== "" ? { cwd } : {},
|
|
44292
|
+
...Object.keys(env).length > 0 ? { env } : {}
|
|
44031
44293
|
});
|
|
44032
44294
|
const screen = this.opts.screenFactory(cols, rows);
|
|
44033
44295
|
const info = {
|
|
@@ -44125,7 +44387,7 @@ var TerminalSessionManager = class {
|
|
|
44125
44387
|
const oldestSeq = session.output[0]?.seq ?? session.nextSeq;
|
|
44126
44388
|
if (input.afterSeq === 0 || input.afterSeq < oldestSeq - 1 || input.afterSeq > cursor) {
|
|
44127
44389
|
await session.screen.flush();
|
|
44128
|
-
const exit =
|
|
44390
|
+
const exit = session.output.toReversed().find((event) => event.kind === "exit");
|
|
44129
44391
|
return {
|
|
44130
44392
|
cursor,
|
|
44131
44393
|
reset: true,
|
|
@@ -44369,7 +44631,28 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44369
44631
|
const localNodeId = declarationOwnerNodeId(this.ctx.kernel.localNodeId);
|
|
44370
44632
|
const cameraRelay = new TerminalCameraRelay({
|
|
44371
44633
|
listProfiles: (nodeId) => nodeId === localNodeId ? manager.listProfiles() : this.ctx.api.terminalSession.listProfiles.query(void 0, nodePin(nodeId)),
|
|
44372
|
-
openSession: (nodeId, input) =>
|
|
44634
|
+
openSession: async (nodeId, input) => {
|
|
44635
|
+
const instance = input.instanceId ? this.terminalInstances().find((row) => row.id === input.instanceId) : void 0;
|
|
44636
|
+
const profile = (nodeId === localNodeId ? await manager.listProfiles() : await this.ctx.api.terminalSession.listProfiles.query(void 0, nodePin(nodeId))).find((candidate) => candidate.profileId === (instance?.profileId ?? input.profileId));
|
|
44637
|
+
const args = instance ? spawnArgsForInstance({
|
|
44638
|
+
profileId: instance.profileId,
|
|
44639
|
+
instanceArgs: instance.args,
|
|
44640
|
+
profileArgs: profile?.args ?? [],
|
|
44641
|
+
profileSettings: instance.profileSettings
|
|
44642
|
+
}) : void 0;
|
|
44643
|
+
const payload = {
|
|
44644
|
+
profileId: input.profileId,
|
|
44645
|
+
cols: input.cols,
|
|
44646
|
+
rows: input.rows,
|
|
44647
|
+
...instance ? {
|
|
44648
|
+
...instance.executable ? { executable: instance.executable } : {},
|
|
44649
|
+
...args !== void 0 ? { args: [...args] } : {},
|
|
44650
|
+
...instance.cwd ? { cwd: instance.cwd } : {},
|
|
44651
|
+
...instance.environment.length > 0 ? { environment: [...instance.environment] } : {}
|
|
44652
|
+
} : {}
|
|
44653
|
+
};
|
|
44654
|
+
return nodeId === localNodeId ? manager.openSession(payload) : this.ctx.api.terminalSession.openSession.mutate(payload, nodePin(nodeId));
|
|
44655
|
+
},
|
|
44373
44656
|
pullOutput: (nodeId, input) => nodeId === localNodeId ? manager.pullOutput(input) : this.ctx.api.terminalSession.pullOutput.mutate(input, nodePin(nodeId)),
|
|
44374
44657
|
closeSession: async (nodeId, sessionId) => {
|
|
44375
44658
|
if (nodeId === localNodeId) await manager.close({ sessionId });
|
|
@@ -44574,6 +44857,7 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44574
44857
|
return {
|
|
44575
44858
|
listInstances: async () => this.terminalInstances().map((instance) => this.instanceInfo(instance)),
|
|
44576
44859
|
createInstance: async (input) => this.createTerminalInstance(input),
|
|
44860
|
+
updateInstance: async (input) => this.updateTerminalInstance(input),
|
|
44577
44861
|
deleteInstance: async ({ instanceId }) => this.deleteTerminalInstance(instanceId),
|
|
44578
44862
|
setInstanceEnabled: async ({ instanceId, enabled }) => this.setTerminalInstanceEnabled(instanceId, enabled),
|
|
44579
44863
|
listLegacyCameras: async () => this.listLegacyTerminalCameras(),
|
|
@@ -44593,7 +44877,12 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44593
44877
|
profileId: instance.profileId,
|
|
44594
44878
|
profileLabel: instance.profileLabel,
|
|
44595
44879
|
name: instance.name,
|
|
44596
|
-
enabled: instance.enabled
|
|
44880
|
+
enabled: instance.enabled,
|
|
44881
|
+
executable: instance.executable,
|
|
44882
|
+
args: instance.args,
|
|
44883
|
+
cwd: instance.cwd,
|
|
44884
|
+
environment: instance.environment,
|
|
44885
|
+
profileSettings: instance.profileSettings
|
|
44597
44886
|
};
|
|
44598
44887
|
}
|
|
44599
44888
|
replaceTerminalCameraTombstones(stableIds) {
|
|
@@ -44621,11 +44910,37 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44621
44910
|
profileId: profile.profileId,
|
|
44622
44911
|
profileLabel: profile.label,
|
|
44623
44912
|
name,
|
|
44624
|
-
enabled: true
|
|
44913
|
+
enabled: true,
|
|
44914
|
+
executable: input.executable?.trim() || profile.executable || "",
|
|
44915
|
+
args: input.args ? [...input.args] : [...profile.args ?? []],
|
|
44916
|
+
cwd: input.cwd?.trim() || profile.cwd || "",
|
|
44917
|
+
environment: input.environment ? [...input.environment] : [...profile.environment ?? []],
|
|
44918
|
+
profileSettings: sanitizeProfileSettings(profile.profileId, input.profileSettings)
|
|
44625
44919
|
};
|
|
44626
44920
|
await this.updateGlobalSettings({ terminalInstances: [...this.config.terminalInstances, instance] });
|
|
44627
44921
|
return this.instanceInfo(instance);
|
|
44628
44922
|
}
|
|
44923
|
+
async updateTerminalInstance(input) {
|
|
44924
|
+
const updated = await this.instanceMutationQueue.run(() => this.updateTerminalInstanceUnlocked(input));
|
|
44925
|
+
await this.cameraRelay?.closeInstance(updated.instanceId);
|
|
44926
|
+
await this.reconcileTerminalCameras();
|
|
44927
|
+
return updated;
|
|
44928
|
+
}
|
|
44929
|
+
async updateTerminalInstanceUnlocked(input) {
|
|
44930
|
+
const instance = this.terminalInstances().find((candidate) => candidate.id === input.instanceId);
|
|
44931
|
+
if (!instance) throw new Error(`No such Terminal instance: ${input.instanceId}`);
|
|
44932
|
+
const updated = {
|
|
44933
|
+
...instance,
|
|
44934
|
+
...input.name !== void 0 ? { name: input.name.trim() } : {},
|
|
44935
|
+
...input.executable !== void 0 ? { executable: input.executable.trim() } : {},
|
|
44936
|
+
...input.args !== void 0 ? { args: [...input.args] } : {},
|
|
44937
|
+
...input.cwd !== void 0 ? { cwd: input.cwd.trim() } : {},
|
|
44938
|
+
...input.environment !== void 0 ? { environment: [...input.environment] } : {},
|
|
44939
|
+
...input.profileSettings !== void 0 ? { profileSettings: sanitizeProfileSettings(instance.profileId, input.profileSettings) } : {}
|
|
44940
|
+
};
|
|
44941
|
+
await this.updateGlobalSettings({ terminalInstances: this.config.terminalInstances.map((candidate) => candidate.id === input.instanceId ? updated : candidate) });
|
|
44942
|
+
return this.instanceInfo(updated);
|
|
44943
|
+
}
|
|
44629
44944
|
async deleteTerminalInstance(instanceId) {
|
|
44630
44945
|
await this.instanceMutationQueue.run(() => this.deleteTerminalInstanceUnlocked(instanceId));
|
|
44631
44946
|
await this.reconcileTerminalCameras();
|
|
@@ -44685,7 +45000,12 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44685
45000
|
profileId: "monitor",
|
|
44686
45001
|
profileLabel: legacy.profileLabel,
|
|
44687
45002
|
name: requestedName?.trim() || legacy.name,
|
|
44688
|
-
enabled: true
|
|
45003
|
+
enabled: true,
|
|
45004
|
+
executable: "",
|
|
45005
|
+
args: [],
|
|
45006
|
+
cwd: "",
|
|
45007
|
+
environment: [],
|
|
45008
|
+
profileSettings: {}
|
|
44689
45009
|
};
|
|
44690
45010
|
await this.updateGlobalSettings({ terminalInstances: [...this.config.terminalInstances, instance] });
|
|
44691
45011
|
return this.instanceInfo(instance);
|
|
@@ -44916,4 +45236,4 @@ var TerminalAddon = class extends BaseAddon {
|
|
|
44916
45236
|
}
|
|
44917
45237
|
};
|
|
44918
45238
|
//#endregion
|
|
44919
|
-
export { TerminalAddon, createXtermScreen as a, buildCellRuns as c, terminalRgbColor as d, createNodePtySpawner as f, createTerminalDataPlaneHandler as i, resolveCellStyle as l, buildProfiles as n, TERMINAL_DEFAULT_BG as o, warmNodePty as p, findProfile as r, TERMINAL_DEFAULT_FG as s, TerminalSessionManager as t, terminalPaletteColor as u };
|
|
45239
|
+
export { TerminalAddon, createXtermScreen$1 as a, buildCellRuns as c, terminalRgbColor as d, createNodePtySpawner as f, createTerminalDataPlaneHandler as i, resolveCellStyle as l, buildProfiles as n, TERMINAL_DEFAULT_BG as o, warmNodePty as p, findProfile as r, TERMINAL_DEFAULT_FG as s, TerminalSessionManager as t, terminalPaletteColor as u };
|