fvtt-world-cli 1.1.2 → 1.2.1

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/index.js CHANGED
@@ -10,7 +10,7 @@ import { readFileSync as readFileSync2 } from "node:fs";
10
10
  import { createHash as createHash2, randomBytes as randomBytes2, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
11
11
 
12
12
  // ../protocol/src/constants.js
13
- var PROTOCOL_VERSION = "1.1.2";
13
+ var PROTOCOL_VERSION = "1.2.1";
14
14
  var PROTOCOL_COMPONENTS = Object.freeze({
15
15
  MODULE: "module",
16
16
  CLI_DAEMON: "cli-daemon",
@@ -174,6 +174,7 @@ var ERROR_CODES = Object.freeze({
174
174
  TILE_NOT_FOUND: "TILE_NOT_FOUND",
175
175
  SOUND_NOT_FOUND: "SOUND_NOT_FOUND",
176
176
  WALL_NOT_FOUND: "WALL_NOT_FOUND",
177
+ LEVEL_NOT_FOUND: "LEVEL_NOT_FOUND",
177
178
  NOTE_NOT_FOUND: "NOTE_NOT_FOUND",
178
179
  DRAWING_NOT_FOUND: "DRAWING_NOT_FOUND",
179
180
  LIGHT_NOT_FOUND: "LIGHT_NOT_FOUND",
@@ -299,7 +300,7 @@ var includeProperty = {
299
300
  var actorIncludeProperty = {
300
301
  include: {
301
302
  type: "array",
302
- items: { type: "string", enum: ["flags", "effects", "items.flags", "items.effects", "prepared"] }
303
+ items: { type: "string", enum: ["flags", "effects", "items", "items.flags", "items.effects", "prepared"] }
303
304
  }
304
305
  };
305
306
  var batchIdsProperty = {
@@ -311,7 +312,10 @@ var batchIdsProperty = {
311
312
  }
312
313
  };
313
314
  var tokenIncludeProperty = {
314
- include: { type: "array", items: { type: "string", enum: ["prepared"] } }
315
+ include: { type: "array", items: { type: "string", enum: ["prepared", "delta"] } }
316
+ };
317
+ var tokenListIncludeProperty = {
318
+ include: { type: "array", items: { type: "string", enum: ["delta"] } }
315
319
  };
316
320
  var compendiumIncludeProperty = {
317
321
  include: { type: "array", items: { type: "string", enum: ["effects"] } }
@@ -1756,6 +1760,16 @@ var compendiumCommands = {
1756
1760
  ...compendiumIncludeProperty
1757
1761
  },
1758
1762
  additionalProperties: false
1763
+ }),
1764
+ "compendium.get-many": cmd({
1765
+ type: "object",
1766
+ required: ["pack", "ids"],
1767
+ properties: {
1768
+ pack: { type: "string", minLength: 1 },
1769
+ ...batchIdsProperty,
1770
+ ...compendiumIncludeProperty
1771
+ },
1772
+ additionalProperties: false
1759
1773
  })
1760
1774
  };
1761
1775
 
@@ -3153,6 +3167,68 @@ var executableBehaviorPatchSchema = {
3153
3167
  additionalProperties: true,
3154
3168
  minProperties: 1
3155
3169
  };
3170
+ var nullableNumberSchema = { type: ["number", "null"] };
3171
+ var levelImageProperties = {
3172
+ src: nullableStringSchema,
3173
+ tint: { type: "string", minLength: 1 },
3174
+ alphaThreshold: { type: "number" }
3175
+ };
3176
+ var levelCreateSchema = {
3177
+ type: "object",
3178
+ required: ["name"],
3179
+ properties: {
3180
+ name: { type: "string", minLength: 1 },
3181
+ elevation: {
3182
+ type: "object",
3183
+ required: [],
3184
+ properties: { bottom: nullableNumberSchema, top: nullableNumberSchema },
3185
+ additionalProperties: false
3186
+ },
3187
+ background: {
3188
+ type: "object",
3189
+ required: [],
3190
+ properties: { color: { type: "string", minLength: 1 }, ...levelImageProperties },
3191
+ additionalProperties: false
3192
+ },
3193
+ foreground: {
3194
+ type: "object",
3195
+ required: [],
3196
+ properties: levelImageProperties,
3197
+ additionalProperties: false
3198
+ },
3199
+ fog: {
3200
+ type: "object",
3201
+ required: [],
3202
+ properties: { src: nullableStringSchema },
3203
+ additionalProperties: false
3204
+ },
3205
+ textures: {
3206
+ type: "object",
3207
+ required: [],
3208
+ properties: {
3209
+ anchorX: { type: "number" },
3210
+ anchorY: { type: "number" },
3211
+ offsetX: { type: "integer" },
3212
+ offsetY: { type: "integer" },
3213
+ fit: { type: "string", minLength: 1 },
3214
+ scaleX: { type: "number" },
3215
+ scaleY: { type: "number" },
3216
+ rotation: { type: "number" }
3217
+ },
3218
+ additionalProperties: false
3219
+ },
3220
+ visibility: {
3221
+ type: "object",
3222
+ required: [],
3223
+ properties: { levels: { type: "array", items: { type: "string", minLength: 1 } } },
3224
+ additionalProperties: false
3225
+ },
3226
+ sort: { type: "integer" },
3227
+ flags: freeformObjectSchema
3228
+ },
3229
+ additionalProperties: false
3230
+ };
3231
+ var levelPatchSchema = patchFrom(levelCreateSchema);
3156
3232
  var sceneEmbeddedCommands = {
3157
3233
  "scene.token.list": cmd({
3158
3234
  type: "object",
@@ -3160,7 +3236,8 @@ var sceneEmbeddedCommands = {
3160
3236
  properties: {
3161
3237
  sceneId: { type: "string", minLength: 1 },
3162
3238
  ...nameFilterProperty,
3163
- ...paginationProperties
3239
+ ...paginationProperties,
3240
+ ...tokenListIncludeProperty
3164
3241
  },
3165
3242
  additionalProperties: false
3166
3243
  }),
@@ -3230,6 +3307,19 @@ var sceneEmbeddedCommands = {
3230
3307
  },
3231
3308
  { mutation: true }
3232
3309
  ),
3310
+ "scene.token.restore-delta": cmd(
3311
+ {
3312
+ type: "object",
3313
+ required: ["sceneId", "tokenId"],
3314
+ properties: {
3315
+ sceneId: { type: "string", minLength: 1 },
3316
+ tokenId: { type: "string", minLength: 1 },
3317
+ ...dryRunProperty
3318
+ },
3319
+ additionalProperties: false
3320
+ },
3321
+ { mutation: true }
3322
+ ),
3233
3323
  ...batchWriteCommands("scene.token", {
3234
3324
  scopeProperties: sceneScopeProperties,
3235
3325
  createSchema: tokenCreateSchema,
@@ -3744,6 +3834,85 @@ var sceneEmbeddedCommands = {
3744
3834
  createSchema: wallCreateSchema,
3745
3835
  patchSchema: wallPatchSchema
3746
3836
  }),
3837
+ "scene.level.list": cmd({
3838
+ type: "object",
3839
+ required: ["sceneId"],
3840
+ properties: {
3841
+ sceneId: { type: "string", minLength: 1 },
3842
+ ...paginationProperties
3843
+ },
3844
+ additionalProperties: false
3845
+ }),
3846
+ "scene.level.get": cmd({
3847
+ type: "object",
3848
+ required: ["sceneId", "levelId"],
3849
+ properties: {
3850
+ sceneId: { type: "string", minLength: 1 },
3851
+ levelId: { type: "string", minLength: 1 }
3852
+ },
3853
+ additionalProperties: false
3854
+ }),
3855
+ "scene.level.create": cmd(
3856
+ {
3857
+ type: "object",
3858
+ required: ["sceneId", "data"],
3859
+ properties: {
3860
+ sceneId: { type: "string", minLength: 1 },
3861
+ data: levelCreateSchema,
3862
+ ...dryRunProperty,
3863
+ ...idempotencyKeyProperty
3864
+ },
3865
+ additionalProperties: false
3866
+ },
3867
+ { mutation: true }
3868
+ ),
3869
+ "scene.level.update": cmd(
3870
+ {
3871
+ type: "object",
3872
+ required: ["sceneId", "levelId", "patch"],
3873
+ properties: {
3874
+ sceneId: { type: "string", minLength: 1 },
3875
+ levelId: { type: "string", minLength: 1 },
3876
+ patch: levelPatchSchema,
3877
+ ...dryRunProperty
3878
+ },
3879
+ additionalProperties: false
3880
+ },
3881
+ { mutation: true }
3882
+ ),
3883
+ "scene.level.delete": cmd(
3884
+ {
3885
+ type: "object",
3886
+ required: ["sceneId", "levelId"],
3887
+ properties: {
3888
+ sceneId: { type: "string", minLength: 1 },
3889
+ levelId: { type: "string", minLength: 1 },
3890
+ ...dryRunProperty
3891
+ },
3892
+ additionalProperties: false
3893
+ },
3894
+ { mutation: true }
3895
+ ),
3896
+ "scene.level.clone": cmd(
3897
+ {
3898
+ type: "object",
3899
+ required: ["sceneId", "levelId"],
3900
+ properties: {
3901
+ sceneId: { type: "string", minLength: 1 },
3902
+ levelId: { type: "string", minLength: 1 },
3903
+ patch: levelPatchSchema,
3904
+ ...dryRunProperty,
3905
+ ...idempotencyKeyProperty
3906
+ },
3907
+ additionalProperties: false
3908
+ },
3909
+ { mutation: true }
3910
+ ),
3911
+ ...batchWriteCommands("scene.level", {
3912
+ scopeProperties: sceneScopeProperties,
3913
+ createSchema: levelCreateSchema,
3914
+ patchSchema: levelPatchSchema
3915
+ }),
3747
3916
  "scene.note.list": cmd({
3748
3917
  type: "object",
3749
3918
  required: ["sceneId"],
@@ -4288,6 +4457,10 @@ var sceneBackgroundSchema = {
4288
4457
  scaleX: { type: "number" },
4289
4458
  scaleY: { type: "number" },
4290
4459
  rotation: { type: "number" },
4460
+ anchorX: { type: "number" },
4461
+ anchorY: { type: "number" },
4462
+ fit: { type: "string", minLength: 1 },
4463
+ alphaThreshold: { type: "number" },
4291
4464
  tint: { type: "string", minLength: 1 }
4292
4465
  },
4293
4466
  additionalProperties: false,
@@ -4299,15 +4472,12 @@ var sceneGridSchema = {
4299
4472
  properties: {
4300
4473
  type: { type: "number" },
4301
4474
  size: { type: "number" },
4302
- sizeX: { type: "number" },
4303
- sizeY: { type: "number" },
4304
4475
  distance: { type: "number" },
4305
4476
  units: { type: "string" },
4306
4477
  style: { type: "string" },
4307
4478
  thickness: { type: "number" },
4308
4479
  color: { type: "string", minLength: 1 },
4309
- alpha: { type: "number" },
4310
- diagonals: { type: "number" }
4480
+ alpha: { type: "number" }
4311
4481
  },
4312
4482
  additionalProperties: false,
4313
4483
  minProperties: 1
@@ -4317,6 +4487,7 @@ var sceneCreateSchema = {
4317
4487
  required: ["name"],
4318
4488
  properties: {
4319
4489
  name: { type: "string", minLength: 1 },
4490
+ folder: nullableStringSchema,
4320
4491
  active: { type: "boolean" },
4321
4492
  navigation: { type: "boolean" },
4322
4493
  navOrder: { type: "number" },
@@ -4333,7 +4504,7 @@ var sceneCreateSchema = {
4333
4504
  navName: nullableStringSchema,
4334
4505
  thumb: nullableStringSchema,
4335
4506
  sort: { type: "number" },
4336
- initialLevel: nullableStringSchema,
4507
+ levels: { type: "array", minItems: 1, items: levelCreateSchema },
4337
4508
  playlist: nullableStringSchema,
4338
4509
  playlistSound: nullableStringSchema,
4339
4510
  journal: nullableStringSchema,
@@ -4348,7 +4519,10 @@ var sceneCreateSchema = {
4348
4519
  },
4349
4520
  additionalProperties: false
4350
4521
  };
4351
- var scenePatchSchema = patchFrom(sceneCreateSchema);
4522
+ var scenePatchSchema = patchFrom(sceneCreateSchema, {
4523
+ omit: ["levels"],
4524
+ prepend: { initialLevel: nullableStringSchema }
4525
+ });
4352
4526
  var sceneCommands = {
4353
4527
  "scene.list": cmd(nameFilteredListSchema),
4354
4528
  "scene.get": cmd(sceneIdSchema),
@@ -4561,7 +4735,14 @@ var settingCommands = {
4561
4735
  // ../protocol/src/schemas/system.js
4562
4736
  var systemCommands = {
4563
4737
  "system.ping": cmd(emptyObjectSchema),
4564
- "system.info": cmd(emptyObjectSchema),
4738
+ "system.info": cmd({
4739
+ type: "object",
4740
+ required: [],
4741
+ properties: {
4742
+ include: { type: "array", items: { type: "string", enum: ["modules"] } }
4743
+ },
4744
+ additionalProperties: false
4745
+ }),
4565
4746
  "system.reload": cmd(emptyObjectSchema)
4566
4747
  };
4567
4748
 
@@ -5202,6 +5383,7 @@ var DEFAULT_COMMAND_PROFILE = deepFreeze({
5202
5383
  "scene.token.update": "allow",
5203
5384
  "scene.token.delete": "approve",
5204
5385
  "scene.token.clone": "allow",
5386
+ "scene.token.restore-delta": "approve",
5205
5387
  "scene.token.create-many": "allow",
5206
5388
  "scene.token.update-many": "allow",
5207
5389
  "scene.token.delete-many": "approve",
@@ -5257,6 +5439,15 @@ var DEFAULT_COMMAND_PROFILE = deepFreeze({
5257
5439
  "scene.wall.create-many": "allow",
5258
5440
  "scene.wall.update-many": "allow",
5259
5441
  "scene.wall.delete-many": "approve",
5442
+ "scene.level.list": "allow",
5443
+ "scene.level.get": "allow",
5444
+ "scene.level.create": "allow",
5445
+ "scene.level.update": "allow",
5446
+ "scene.level.delete": "approve",
5447
+ "scene.level.clone": "allow",
5448
+ "scene.level.create-many": "allow",
5449
+ "scene.level.update-many": "allow",
5450
+ "scene.level.delete-many": "approve",
5260
5451
  "scene.note.list": "allow",
5261
5452
  "scene.note.get": "allow",
5262
5453
  "scene.note.create": "allow",
@@ -5490,6 +5681,7 @@ var DEFAULT_COMMAND_PROFILE = deepFreeze({
5490
5681
  "compendium.list": "allow",
5491
5682
  "compendium.index": "allow",
5492
5683
  "compendium.get": "allow",
5684
+ "compendium.get-many": "allow",
5493
5685
  "folder.list": "allow",
5494
5686
  "folder.get": "allow",
5495
5687
  "folder.create": "allow",
@@ -5519,7 +5711,12 @@ var DEFAULT_COMMAND_PROFILE = deepFreeze({
5519
5711
 
5520
5712
  // ../protocol/src/command-risk.js
5521
5713
  var DESTRUCTIVE_VERBS = Object.freeze(["delete", "delete-many"]);
5522
- var DESTRUCTIVE_COMMANDS = Object.freeze(["chat.flush", "file.move", "scene.fog.reset"]);
5714
+ var DESTRUCTIVE_COMMANDS = Object.freeze([
5715
+ "chat.flush",
5716
+ "file.move",
5717
+ "scene.fog.reset",
5718
+ "scene.token.restore-delta"
5719
+ ]);
5523
5720
  var APPROVE_EXTRA_COMMANDS = Object.freeze(["system.reload", "user.create"]);
5524
5721
  var DENIED_BY_DEFAULT_COMMANDS = Object.freeze([
5525
5722
  "macro.execute",
@@ -6119,11 +6316,22 @@ function createCliConfigStore(configPath = getDefaultCliConfigPath()) {
6119
6316
  }
6120
6317
  };
6121
6318
  }
6122
- function mergePersistedCliConfig(existingConfig, updates) {
6123
- return PersistedCliConfigSchema.parse({
6124
- ...existingConfig ?? createEmptyConfig(),
6125
- ...updates
6126
- });
6319
+ var DAEMON_OWNED_CONFIG_KEYS = ["version", "daemonUrl", "deviceCredential", "pairings"];
6320
+ function withDaemonOwnedKeys(config, owner) {
6321
+ const merged = { ...config };
6322
+ for (const key of DAEMON_OWNED_CONFIG_KEYS) {
6323
+ if (owner[key] === void 0) delete merged[key];
6324
+ else merged[key] = owner[key];
6325
+ }
6326
+ return merged;
6327
+ }
6328
+ function writeCliConfigUpdate(configStore, updates) {
6329
+ configStore.writeConfig(
6330
+ PersistedCliConfigSchema.parse({
6331
+ ...configStore.readConfig() ?? createEmptyConfig(),
6332
+ ...updates
6333
+ })
6334
+ );
6127
6335
  }
6128
6336
  function resolveRemoteCommandConfig({
6129
6337
  flagDaemonUrl,
@@ -6169,8 +6377,8 @@ function readPendingApprovalDetails(envelope) {
6169
6377
  var DaemonTransportError = class extends Error {
6170
6378
  code;
6171
6379
  details;
6172
- constructor(code, message, details) {
6173
- super(message);
6380
+ constructor(code, message, details, options) {
6381
+ super(message, options);
6174
6382
  this.name = "DaemonTransportError";
6175
6383
  this.code = code;
6176
6384
  this.details = details;
@@ -6615,7 +6823,7 @@ var BridgeSessionStore = class {
6615
6823
  ok: false,
6616
6824
  error: createProtocolError({
6617
6825
  code: ERROR_CODES.UNKNOWN_COMMAND,
6618
- message: `Bridge session does not advertise support for ${request.command}; run system.info to see the connected bridge's supported command inventory (the module may be older than this CLI)`,
6826
+ message: `Bridge session does not advertise support for ${request.command}; details.supportedCommands lists the commands the connected bridge advertised, and \`fvtt-world-cli auth status\` reports them without the internal approval and policy commands; the Foundry module may be older than this CLI, or the GM page may need a reload`,
6619
6827
  details: {
6620
6828
  command: request.command,
6621
6829
  supportedCommands: this.activeSession.commands
@@ -7161,11 +7369,9 @@ var BridgeDaemon = class {
7161
7369
  }
7162
7370
  persistConfig() {
7163
7371
  if (!this.configStore) return;
7164
- const persisted = this.configStore.readConfig();
7165
- this.config = PersistedCliConfigSchema.parse({
7166
- ...this.config,
7167
- ...persisted?.uploadLimitBytes === void 0 ? {} : { uploadLimitBytes: persisted.uploadLimitBytes }
7168
- });
7372
+ this.config = PersistedCliConfigSchema.parse(
7373
+ withDaemonOwnedKeys(this.configStore.readConfig() ?? this.config, this.config)
7374
+ );
7169
7375
  this.configStore.writeConfig(this.config);
7170
7376
  }
7171
7377
  handlePairingRequest(socket, state, message) {
@@ -7972,23 +8178,35 @@ async function connectDaemonClient({
7972
8178
  socket.send(JSON.stringify(createClientHello({ credential: deviceCredential ?? "" })));
7973
8179
  });
7974
8180
  socket.once("message", (data) => {
7975
- const parsed = parseBridgeMessage(normalizeIncomingData(data));
7976
- const skew = parsed.ok ? protocolVersionSkewError(parsed.value) : null;
7977
- if (skew) {
8181
+ const decoded = decodeTransportFrame(data);
8182
+ if (!decoded.ok) {
7978
8183
  clearTimeout(timer);
7979
- reject(skew);
8184
+ reject(decoded.error);
7980
8185
  socket.close();
7981
8186
  return;
7982
8187
  }
7983
- const validation = parsed.ok ? validateTransportMessage(parsed.value) : { ok: false };
7984
- const message = parsed.ok && validation.ok ? parsed.value : null;
7985
- if (!message || message.type !== MESSAGE_TYPES.CLIENT_HELLO_ACK || !message.ok) {
8188
+ const message = decoded.value;
8189
+ if (message.type !== MESSAGE_TYPES.CLIENT_HELLO_ACK) {
7986
8190
  clearTimeout(timer);
7987
8191
  reject(
7988
8192
  new DaemonTransportError(
7989
- message?.error?.code ?? ERROR_CODES.UNAUTHORIZED,
7990
- message?.error?.message ?? "Daemon rejected client authentication",
7991
- message?.error?.details
8193
+ ERROR_CODES.INVALID_MESSAGE,
8194
+ "Daemon returned an unexpected message type",
8195
+ {
8196
+ reason: "unexpected_type"
8197
+ }
8198
+ )
8199
+ );
8200
+ socket.close();
8201
+ return;
8202
+ }
8203
+ if (!message.ok) {
8204
+ clearTimeout(timer);
8205
+ reject(
8206
+ new DaemonTransportError(
8207
+ message.error?.code ?? ERROR_CODES.UNAUTHORIZED,
8208
+ message.error?.message ?? "Daemon rejected client authentication",
8209
+ message.error?.details
7992
8210
  )
7993
8211
  );
7994
8212
  socket.close();
@@ -8003,7 +8221,8 @@ async function connectDaemonClient({
8003
8221
  new DaemonTransportError(
8004
8222
  ERROR_CODES.DAEMON_UNAVAILABLE,
8005
8223
  error instanceof Error ? error.message : String(error),
8006
- { reason: "connect_error" }
8224
+ { reason: "connect_error" },
8225
+ { cause: error }
8007
8226
  )
8008
8227
  );
8009
8228
  });
@@ -8523,23 +8742,21 @@ function parseCsvList(value, label) {
8523
8742
  }
8524
8743
  return items;
8525
8744
  }
8526
- var INCLUDE_ALLOWED = ["flags", "effects"];
8527
- function parseIncludeFields(value) {
8745
+ function parseAllowedIncludeFields(value, allowed) {
8528
8746
  const fields = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
8529
8747
  if (fields.length === 0) {
8530
- throw new InvalidArgumentError(
8531
- `--include must name at least one field (allowed: ${INCLUDE_ALLOWED.join(", ")})`
8532
- );
8748
+ throw new InvalidArgumentError(`--include must name at least one field (allowed: ${allowed.join(", ")})`);
8533
8749
  }
8534
8750
  for (const field of fields) {
8535
- if (!INCLUDE_ALLOWED.includes(field)) {
8536
- throw new InvalidArgumentError(
8537
- `--include only supports ${INCLUDE_ALLOWED.join(", ")}, received ${field}`
8538
- );
8751
+ if (!allowed.includes(field)) {
8752
+ throw new InvalidArgumentError(`--include only supports ${allowed.join(", ")}, received ${field}`);
8539
8753
  }
8540
8754
  }
8541
8755
  return fields;
8542
8756
  }
8757
+ function parseIncludeFields(value) {
8758
+ return parseAllowedIncludeFields(value, ["flags", "effects"]);
8759
+ }
8543
8760
  var OWNERSHIP_LEVELS = [-1, 0, 1, 2, 3];
8544
8761
  var INTEGER_PATTERN = /^-?\d+$/;
8545
8762
  function parseOwnershipLevel(value) {
@@ -8639,56 +8856,27 @@ function parseWhisperIds(value) {
8639
8856
  }
8640
8857
  return ids;
8641
8858
  }
8642
- var ACTOR_INCLUDE_ALLOWED = ["flags", "effects", "items.flags", "items.effects", "prepared"];
8643
8859
  function parseActorIncludeFields(value) {
8644
- const fields = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
8645
- if (fields.length === 0) {
8646
- throw new InvalidArgumentError(
8647
- `--include must name at least one field (allowed: ${ACTOR_INCLUDE_ALLOWED.join(", ")})`
8648
- );
8649
- }
8650
- for (const field of fields) {
8651
- if (!ACTOR_INCLUDE_ALLOWED.includes(field)) {
8652
- throw new InvalidArgumentError(
8653
- `--include only supports ${ACTOR_INCLUDE_ALLOWED.join(", ")}, received ${field}`
8654
- );
8655
- }
8656
- }
8657
- return fields;
8860
+ return parseAllowedIncludeFields(value, [
8861
+ "flags",
8862
+ "effects",
8863
+ "items",
8864
+ "items.flags",
8865
+ "items.effects",
8866
+ "prepared"
8867
+ ]);
8658
8868
  }
8659
- var TOKEN_INCLUDE_ALLOWED = ["prepared"];
8660
8869
  function parseTokenIncludeFields(value) {
8661
- const fields = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
8662
- if (fields.length === 0) {
8663
- throw new InvalidArgumentError(
8664
- `--include must name at least one field (allowed: ${TOKEN_INCLUDE_ALLOWED.join(", ")})`
8665
- );
8666
- }
8667
- for (const field of fields) {
8668
- if (!TOKEN_INCLUDE_ALLOWED.includes(field)) {
8669
- throw new InvalidArgumentError(
8670
- `--include only supports ${TOKEN_INCLUDE_ALLOWED.join(", ")}, received ${field}`
8671
- );
8672
- }
8673
- }
8674
- return fields;
8870
+ return parseAllowedIncludeFields(value, ["prepared", "delta"]);
8871
+ }
8872
+ function parseTokenListIncludeFields(value) {
8873
+ return parseAllowedIncludeFields(value, ["delta"]);
8874
+ }
8875
+ function parseSystemInfoIncludeFields(value) {
8876
+ return parseAllowedIncludeFields(value, ["modules"]);
8675
8877
  }
8676
- var COMPENDIUM_INCLUDE_ALLOWED = ["effects"];
8677
8878
  function parseCompendiumIncludeFields(value) {
8678
- const fields = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
8679
- if (fields.length === 0) {
8680
- throw new InvalidArgumentError(
8681
- `--include must name at least one field (allowed: ${COMPENDIUM_INCLUDE_ALLOWED.join(", ")})`
8682
- );
8683
- }
8684
- for (const field of fields) {
8685
- if (!COMPENDIUM_INCLUDE_ALLOWED.includes(field)) {
8686
- throw new InvalidArgumentError(
8687
- `--include only supports ${COMPENDIUM_INCLUDE_ALLOWED.join(", ")}, received ${field}`
8688
- );
8689
- }
8690
- }
8691
- return fields;
8879
+ return parseAllowedIncludeFields(value, ["effects"]);
8692
8880
  }
8693
8881
  function parseCompendiumFieldsList(value) {
8694
8882
  return value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
@@ -8786,44 +8974,10 @@ function createItemUpdateParams(options) {
8786
8974
  ...options.include ? { include: options.include } : {}
8787
8975
  };
8788
8976
  }
8789
- function createSceneUpdateParams(options) {
8790
- return {
8791
- sceneId: options.sceneId,
8792
- patch: assertNonEmptyPatch({
8793
- ...stringField("name", options.name),
8794
- ...booleanField("active", options.active),
8795
- ...booleanField("navigation", options.navigation),
8796
- ...numberField("navOrder", options.navOrder),
8797
- ...numberField("width", options.width),
8798
- ...numberField("height", options.height),
8799
- ...jsonObjectField("grid", options.gridJson, "--grid-json"),
8800
- ...jsonObjectField("background", options.backgroundJson, "--background-json"),
8801
- ...booleanField("tokenVision", options.tokenVision),
8802
- ...truthyStringField("weather", options.weather),
8803
- ...numberField("padding", options.padding),
8804
- ...numberField("shiftX", options.shiftX),
8805
- ...numberField("shiftY", options.shiftY),
8806
- ...truthyStringField("navName", options.navName),
8807
- ...truthyStringField("thumb", options.thumb),
8808
- ...truthyStringField("foreground", options.foreground),
8809
- ...numberField("foregroundElevation", options.foregroundElevation),
8810
- ...numberField("sort", options.sort),
8811
- ...truthyStringField("initialLevel", options.initialLevel),
8812
- ...truthyStringField("playlist", options.playlist),
8813
- ...truthyStringField("playlistSound", options.playlistSound),
8814
- ...truthyStringField("journal", options.journal),
8815
- ...truthyStringField("journalEntryPage", options.journalEntryPage),
8816
- ...jsonObjectField("environment", options.environmentJson, "--environment-json"),
8817
- ...jsonObjectField("fog", options.fogJson, "--fog-json"),
8818
- ...jsonObjectField("initial", options.initialJson, "--initial-json"),
8819
- ...jsonObjectField("transition", options.transitionJson, "--transition-json"),
8820
- ...optionalJsonObject(options.patchJson, "--patch-json") ?? {}
8821
- })
8822
- };
8823
- }
8824
8977
  function buildScenePatch(options) {
8825
8978
  return {
8826
8979
  ...stringField("name", options.name),
8980
+ ...folderField(options),
8827
8981
  ...booleanField("active", options.active),
8828
8982
  ...booleanField("navigation", options.navigation),
8829
8983
  ...numberField("navOrder", options.navOrder),
@@ -8852,6 +9006,15 @@ function buildScenePatch(options) {
8852
9006
  ...jsonObjectField("transition", options.transitionJson, "--transition-json")
8853
9007
  };
8854
9008
  }
9009
+ function createSceneUpdateParams(options) {
9010
+ return {
9011
+ sceneId: options.sceneId,
9012
+ patch: assertNonEmptyPatch({
9013
+ ...buildScenePatch(options),
9014
+ ...optionalJsonObject(options.patchJson, "--patch-json") ?? {}
9015
+ })
9016
+ };
9017
+ }
8855
9018
  function createSceneCreateParams(options) {
8856
9019
  return {
8857
9020
  data: {
@@ -9657,6 +9820,23 @@ function createSceneWallCloneParams(options) {
9657
9820
  ...optionalPatch(optionalJsonObject(options.patchJson, "--patch-json") ?? {})
9658
9821
  };
9659
9822
  }
9823
+ function createSceneLevelCreateParams(options) {
9824
+ return { sceneId: options.sceneId, data: optionalJsonObject(options.dataJson, "--data-json") ?? {} };
9825
+ }
9826
+ function createSceneLevelUpdateParams(options) {
9827
+ return {
9828
+ sceneId: options.sceneId,
9829
+ levelId: options.levelId,
9830
+ patch: assertNonEmptyPatch(optionalJsonObject(options.patchJson, "--patch-json") ?? {})
9831
+ };
9832
+ }
9833
+ function createSceneLevelCloneParams(options) {
9834
+ return {
9835
+ sceneId: options.sceneId,
9836
+ levelId: options.levelId,
9837
+ ...optionalPatch(optionalJsonObject(options.patchJson, "--patch-json") ?? {})
9838
+ };
9839
+ }
9660
9840
  function createSceneNoteCreateParams(options) {
9661
9841
  return { sceneId: options.sceneId, data: optionalJsonObject(options.dataJson, "--data-json") ?? {} };
9662
9842
  }
@@ -10223,8 +10403,11 @@ function renderBroadcastLines(result) {
10223
10403
  `dispatched: ${Boolean(result?.dispatched)} \u2014 a broadcast writes nothing, so there is no state to confirm afterwards`
10224
10404
  ];
10225
10405
  }
10226
- function renderCompendiumSourceLines(document) {
10227
- return document?.compendiumSource ? [`compendiumSource: ${document.compendiumSource}`] : [];
10406
+ function renderProvenanceLines(document) {
10407
+ return [
10408
+ ...document?.compendiumSource ? [`compendiumSource: ${document.compendiumSource}`] : [],
10409
+ ...document?.duplicateSource ? [`duplicateSource: ${document.duplicateSource}`] : []
10410
+ ];
10228
10411
  }
10229
10412
  function renderOwnershipLines(ownership) {
10230
10413
  if (!ownership || typeof ownership !== "object") {
@@ -10336,7 +10519,7 @@ function renderItemDetails(item, prefixLines = []) {
10336
10519
  if (item && Object.hasOwn(item, "effects")) {
10337
10520
  lines.push(`effects: ${JSON.stringify(item.effects ?? [], null, 2)}`);
10338
10521
  }
10339
- lines.push(...renderCompendiumSourceLines(item));
10522
+ lines.push(...renderProvenanceLines(item));
10340
10523
  if (item && Object.hasOwn(item, "ownership")) {
10341
10524
  lines.push(...renderOwnershipLines(item.ownership));
10342
10525
  }
@@ -10362,14 +10545,14 @@ function renderActorDetails(actor) {
10362
10545
  if (actor && Object.hasOwn(actor, "effects")) {
10363
10546
  lines.push(`effects: ${JSON.stringify(actor.effects ?? [], null, 2)}`);
10364
10547
  }
10365
- lines.push(...renderCompendiumSourceLines(actor));
10548
+ lines.push(...renderProvenanceLines(actor));
10366
10549
  if (actor && Object.hasOwn(actor, "ownership")) {
10367
10550
  lines.push(...renderOwnershipLines(actor.ownership));
10368
10551
  }
10369
10552
  if (actor && Object.hasOwn(actor, "prepared")) {
10370
10553
  lines.push(`prepared: ${Object.keys(actor.prepared ?? {}).join(", ")} (use --json for values)`);
10371
10554
  }
10372
- lines.push(`items: ${items.length}`);
10555
+ lines.push(`items: ${actor?.itemCount ?? items.length}`);
10373
10556
  items.forEach((item) => {
10374
10557
  lines.push(`item: ${renderItemSummaryLine(item)}`);
10375
10558
  });
@@ -10408,7 +10591,7 @@ function renderCardsDetails(cards) {
10408
10591
  `cards: ${rows.length}`,
10409
10592
  ...rows.map((card) => ` ${renderCardLine(card)}`)
10410
10593
  ];
10411
- lines.push(...renderCompendiumSourceLines(cards));
10594
+ lines.push(...renderProvenanceLines(cards));
10412
10595
  if (cards && Object.hasOwn(cards, "ownership")) {
10413
10596
  lines.push(...renderOwnershipLines(cards.ownership));
10414
10597
  }
@@ -10947,7 +11130,7 @@ function renderJournalDetails(journal) {
10947
11130
  `sort: ${journal?.sort ?? 0}`,
10948
11131
  `pages: ${pages.length}`
10949
11132
  ];
10950
- lines.push(...renderCompendiumSourceLines(journal));
11133
+ lines.push(...renderProvenanceLines(journal));
10951
11134
  if (journal && Object.hasOwn(journal, "ownership")) {
10952
11135
  lines.push(...renderOwnershipLines(journal.ownership));
10953
11136
  }
@@ -11063,7 +11246,7 @@ function renderMacroDetails(macro) {
11063
11246
  `flags: ${JSON.stringify(macro?.flags ?? {}, null, 2)}`,
11064
11247
  `command: ${macro?.command ?? ""}`
11065
11248
  ];
11066
- lines.push(...renderCompendiumSourceLines(macro));
11249
+ lines.push(...renderProvenanceLines(macro));
11067
11250
  if (macro && Object.hasOwn(macro, "ownership")) {
11068
11251
  lines.push(...renderOwnershipLines(macro.ownership));
11069
11252
  }
@@ -11086,7 +11269,7 @@ function renderPlaylistDetails(playlist) {
11086
11269
  `flags: ${JSON.stringify(playlist?.flags ?? {}, null, 2)}`,
11087
11270
  `sounds: ${playlist?.sounds?.length ?? 0}`
11088
11271
  ];
11089
- lines.push(...renderCompendiumSourceLines(playlist));
11272
+ lines.push(...renderProvenanceLines(playlist));
11090
11273
  if (playlist && Object.hasOwn(playlist, "ownership")) {
11091
11274
  lines.push(...renderOwnershipLines(playlist.ownership));
11092
11275
  }
@@ -11128,17 +11311,24 @@ function renderSceneDetails(scene) {
11128
11311
  const lines = [
11129
11312
  `id: ${scene?.id}`,
11130
11313
  `name: ${scene?.name}`,
11314
+ `folder: ${scene?.folder ?? ""}`,
11131
11315
  `active: ${String(Boolean(scene?.active))}`,
11132
11316
  `navigation: ${String(Boolean(scene?.navigation))}`,
11133
11317
  `nav order: ${scene?.navOrder ?? 0}`,
11134
11318
  `size: ${scene?.width}x${scene?.height}`,
11135
11319
  `grid: ${JSON.stringify(scene?.grid ?? null)}`,
11136
- `background: ${JSON.stringify(scene?.background ?? null)}`,
11320
+ ...scene && Object.hasOwn(scene, "background") ? [`background: ${JSON.stringify(scene.background ?? null)}`] : [],
11137
11321
  `token vision: ${String(Boolean(scene?.tokenVision))}`,
11138
11322
  `weather: ${scene?.weather ?? ""}`,
11139
11323
  `playlist: ${scene?.playlist ?? ""}`
11140
11324
  ];
11141
- lines.push(...renderCompendiumSourceLines(scene));
11325
+ if (scene && Object.hasOwn(scene, "initialLevel")) {
11326
+ lines.push(`initial level: ${scene.initialLevel ?? "(first level)"}`);
11327
+ }
11328
+ for (const level of Array.isArray(scene?.levels) ? scene.levels : []) {
11329
+ lines.push(`level: ${renderLevelRow(level)}`);
11330
+ }
11331
+ lines.push(...renderProvenanceLines(scene));
11142
11332
  if (scene && Object.hasOwn(scene, "ownership")) {
11143
11333
  lines.push(...renderOwnershipLines(scene.ownership));
11144
11334
  }
@@ -11149,6 +11339,20 @@ function renderSceneDetails(scene) {
11149
11339
  }
11150
11340
  return lines.join("\n");
11151
11341
  }
11342
+ function levelMembership(placeable) {
11343
+ if (placeable && Object.hasOwn(placeable, "level")) return ["level", String(placeable.level)];
11344
+ if (placeable && Object.hasOwn(placeable, "levels"))
11345
+ return ["levels", placeable.levels.join(",") || "(all)"];
11346
+ return null;
11347
+ }
11348
+ function levelMembershipLines(placeable) {
11349
+ const membership = levelMembership(placeable);
11350
+ return membership ? [`${membership[0]}: ${membership[1]}`] : [];
11351
+ }
11352
+ function levelMembershipCell(placeable) {
11353
+ const membership = levelMembership(placeable);
11354
+ return membership ? ` ${membership[0]}=${membership[1]}` : "";
11355
+ }
11152
11356
  function renderTokenDetails(sceneId, token) {
11153
11357
  const lines = [
11154
11358
  `scene: ${sceneId}`,
@@ -11158,16 +11362,35 @@ function renderTokenDetails(sceneId, token) {
11158
11362
  `actorLink: ${String(Boolean(token?.actorLink))}`,
11159
11363
  `position: (${token?.x ?? 0}, ${token?.y ?? 0})`,
11160
11364
  `elevation: ${token?.elevation ?? 0}`,
11365
+ ...levelMembershipLines(token),
11161
11366
  `rotation: ${token?.rotation ?? 0}`,
11162
11367
  `hidden: ${String(Boolean(token?.hidden))}`,
11163
11368
  `disposition: ${token?.disposition ?? ""}`,
11164
11369
  `texture: ${JSON.stringify(token?.texture ?? null)}`
11165
11370
  ];
11371
+ if (token && Object.hasOwn(token, "delta")) {
11372
+ lines.push(`delta: ${token.delta === null ? "none" : "stored (use --json for values)"}`);
11373
+ }
11166
11374
  if (token && Object.hasOwn(token, "prepared")) {
11167
11375
  lines.push(`prepared: ${Object.keys(token.prepared ?? {}).join(", ")} (use --json for values)`);
11168
11376
  }
11169
11377
  return lines.join("\n");
11170
11378
  }
11379
+ function tokenDeltaSummaryCell(token) {
11380
+ if (!token || !Object.hasOwn(token, "deltaSummary")) return "";
11381
+ const summary = token.deltaSummary;
11382
+ if (summary === null) return " overrides=none";
11383
+ return ` overrides=${(summary.overriddenKeys ?? []).join(",")} (item entries ${summary.itemEntries}, effect entries ${summary.effectEntries})`;
11384
+ }
11385
+ function renderTokenDeltaRestore(result) {
11386
+ const discarded = result.discarded;
11387
+ const verb = result.dryRun ? "[dry-run] would discard" : "Discarded";
11388
+ return [
11389
+ `scene: ${result.sceneId}`,
11390
+ `token: ${result.tokenId}`,
11391
+ result.changed ? `${verb} token overrides: ${(discarded?.overriddenKeys ?? []).join(", ")} (item entries ${discarded?.itemEntries ?? 0}, effect entries ${discarded?.effectEntries ?? 0})` : "No token-level overrides; nothing to restore."
11392
+ ].join("\n");
11393
+ }
11171
11394
  function tokenItemPrefix(result) {
11172
11395
  const lines = [
11173
11396
  `scene: ${result.sceneId}`,
@@ -11206,6 +11429,7 @@ function renderTileDetails(sceneId, tile) {
11206
11429
  `size: ${tile?.width}x${tile?.height}`,
11207
11430
  `rotation: ${tile?.rotation ?? 0}`,
11208
11431
  `elevation: ${tile?.elevation ?? 0}`,
11432
+ ...levelMembershipLines(tile),
11209
11433
  `sort: ${tile?.sort ?? 0}`,
11210
11434
  `hidden: ${String(Boolean(tile?.hidden))}`,
11211
11435
  `locked: ${String(Boolean(tile?.locked))}`,
@@ -11219,6 +11443,7 @@ function renderSoundDetails(sceneId, sound) {
11219
11443
  `path: ${sound?.path ?? ""}`,
11220
11444
  `position: (${sound?.x ?? 0}, ${sound?.y ?? 0})`,
11221
11445
  `radius: ${sound?.radius ?? 0}`,
11446
+ ...levelMembershipLines(sound),
11222
11447
  `volume: ${sound?.volume ?? ""}`,
11223
11448
  `walls: ${String(Boolean(sound?.walls))}`,
11224
11449
  `easing: ${String(Boolean(sound?.easing))}`,
@@ -11226,11 +11451,30 @@ function renderSoundDetails(sceneId, sound) {
11226
11451
  `hidden: ${String(Boolean(sound?.hidden))}`
11227
11452
  ].join("\n");
11228
11453
  }
11454
+ function renderLevelRow(level) {
11455
+ const elevation = level?.elevation ?? {};
11456
+ return `${level?.id} ${level?.name ?? ""} elevation=${elevation.bottom ?? "-inf"}..${elevation.top ?? "+inf"} sort=${level?.sort ?? 0}`;
11457
+ }
11458
+ function renderLevelDetails(sceneId, level) {
11459
+ return [
11460
+ `scene: ${sceneId}`,
11461
+ `id: ${level?.id}`,
11462
+ `name: ${level?.name ?? ""}`,
11463
+ `elevation: ${JSON.stringify(level?.elevation ?? null)}`,
11464
+ `sort: ${level?.sort ?? 0}`,
11465
+ `background: ${JSON.stringify(level?.background ?? null)}`,
11466
+ `foreground: ${JSON.stringify(level?.foreground ?? null)}`,
11467
+ `fog: ${JSON.stringify(level?.fog ?? null)}`,
11468
+ `textures: ${JSON.stringify(level?.textures ?? null)}`,
11469
+ `visibility: ${JSON.stringify(level?.visibility ?? null)}`
11470
+ ].join("\n");
11471
+ }
11229
11472
  function renderWallDetails(sceneId, wall) {
11230
11473
  return [
11231
11474
  `scene: ${sceneId}`,
11232
11475
  `id: ${wall?.id}`,
11233
11476
  `c: ${JSON.stringify(wall?.c ?? null)}`,
11477
+ ...levelMembershipLines(wall),
11234
11478
  `door: ${wall?.door ?? 0}`,
11235
11479
  `ds: ${wall?.ds ?? 0}`,
11236
11480
  `doorSound: ${wall?.doorSound ?? ""}`,
@@ -11253,6 +11497,7 @@ function renderNoteDetails(sceneId, note) {
11253
11497
  `texture: ${JSON.stringify(note?.texture ?? null)}`,
11254
11498
  `iconSize: ${note?.iconSize ?? ""}`,
11255
11499
  `elevation: ${note?.elevation ?? 0}`,
11500
+ ...levelMembershipLines(note),
11256
11501
  `sort: ${note?.sort ?? 0}`,
11257
11502
  `global: ${String(Boolean(note?.global))}`
11258
11503
  ].join("\n");
@@ -11268,6 +11513,7 @@ function renderDrawingDetails(sceneId, drawing) {
11268
11513
  `shape: ${JSON.stringify(drawing?.shape ?? null)}`,
11269
11514
  `rotation: ${drawing?.rotation ?? 0}`,
11270
11515
  `elevation: ${drawing?.elevation ?? 0}`,
11516
+ ...levelMembershipLines(drawing),
11271
11517
  `sort: ${drawing?.sort ?? 0}`,
11272
11518
  `fillColor: ${drawing?.fillColor ?? ""}`,
11273
11519
  `strokeColor: ${drawing?.strokeColor ?? ""}`,
@@ -11282,6 +11528,7 @@ function renderLightDetails(sceneId, light) {
11282
11528
  `name: ${light?.name ?? ""}`,
11283
11529
  `position: (${light?.x ?? 0}, ${light?.y ?? 0})`,
11284
11530
  `elevation: ${light?.elevation ?? 0}`,
11531
+ ...levelMembershipLines(light),
11285
11532
  `rotation: ${light?.rotation ?? 0}`,
11286
11533
  `walls: ${String(Boolean(light?.walls))}`,
11287
11534
  `vision: ${String(Boolean(light?.vision))}`,
@@ -11312,6 +11559,7 @@ function renderRegionDetails(sceneId, region) {
11312
11559
  `color: ${region?.color ?? ""}`,
11313
11560
  `visibility: ${region?.visibility ?? ""}`,
11314
11561
  `elevation: ${JSON.stringify(region?.elevation ?? null)}`,
11562
+ ...levelMembershipLines(region),
11315
11563
  `shapes: ${JSON.stringify(region?.shapes ?? [])}`,
11316
11564
  `behaviors: ${JSON.stringify(region?.behaviors ?? [])}`,
11317
11565
  `locked: ${String(Boolean(region?.locked))}`
@@ -11427,7 +11675,7 @@ function renderTableDetails(table) {
11427
11675
  `results: ${results.length}`,
11428
11676
  ...results.map((result) => ` ${renderTableResultLine(result)}`)
11429
11677
  ];
11430
- lines.push(...renderCompendiumSourceLines(table));
11678
+ lines.push(...renderProvenanceLines(table));
11431
11679
  if (table && Object.hasOwn(table, "ownership")) {
11432
11680
  lines.push(...renderOwnershipLines(table.ownership));
11433
11681
  }
@@ -11614,10 +11862,12 @@ var RENDERERS = registerRenderers([
11614
11862
  `world: ${result.world?.title ?? "Unknown World"} [${result.world?.id ?? "unknown-world"}]`,
11615
11863
  `user: ${result.user?.name ?? "Unknown User"} [${result.user?.id ?? "unknown-user"}] GM=${String(Boolean(result.user?.isGM))}`,
11616
11864
  `bridge: ${result.bridge?.status ?? "unknown"}`,
11617
- `modules: ${(result.modules ?? []).length}`,
11865
+ `modules: ${result.moduleCount ?? "unknown"} installed, ${result.activeModuleCount ?? "unknown"} active`,
11866
+ ...(result.modules ?? []).map(
11867
+ (module) => ` ${module.id} ${module.version ?? "unknown"} ${module.active ? "active" : "inactive"}`
11868
+ ),
11618
11869
  `limits.uploadBytes: ${result.limits?.uploadBytes ?? "unknown"} (source: ${result.limits?.uploadSource ?? "unknown"})`,
11619
- `limits.wsMaxPayloadBytes: ${result.limits?.wsMaxPayloadBytes ?? "unknown"}`,
11620
- `commands: ${(result.commands ?? []).join(", ")}`
11870
+ `limits.wsMaxPayloadBytes: ${result.limits?.wsMaxPayloadBytes ?? "unknown"}`
11621
11871
  ].join("\n")
11622
11872
  ),
11623
11873
  detailRenderer(
@@ -12215,6 +12465,17 @@ var RENDERERS = registerRenderers([
12215
12465
  `document: ${JSON.stringify(result.document ?? null, null, 2)}`
12216
12466
  ].join("\n")
12217
12467
  ),
12468
+ customRenderer("compendium.get-many", (result) => {
12469
+ const entries = result.entries ?? [];
12470
+ return [
12471
+ `pack: ${result.pack}`,
12472
+ `Entries (${entries.length})`,
12473
+ ...entries.map(
12474
+ (entry) => `${entry.entryId} ${entry.documentName ?? ""} ${entry.document?.name ?? ""}${Array.isArray(entry.effects) ? ` effects=${entry.effects.length}` : ""}`
12475
+ ),
12476
+ "(use --json for the documents)"
12477
+ ].join("\n");
12478
+ }),
12218
12479
  listRenderer("folder.list", {
12219
12480
  key: "folders",
12220
12481
  empty: "No folders found.",
@@ -12348,13 +12609,14 @@ var RENDERERS = registerRenderers([
12348
12609
  empty: "No tokens found.",
12349
12610
  heading: "Tokens",
12350
12611
  prefix: scenePrefix,
12351
- row: (token) => `${token.id} ${token.name} actor=${token.actorId ?? "-"} linked=${String(Boolean(token.actorLink))} (${token.x},${token.y})`
12612
+ row: (token) => `${token.id} ${token.name} actor=${token.actorId ?? "-"} linked=${String(Boolean(token.actorLink))} (${token.x},${token.y})${levelMembershipCell(token)}${tokenDeltaSummaryCell(token)}`
12352
12613
  }),
12353
12614
  detailRenderer(
12354
12615
  ["scene.token.get", "scene.token.create", "scene.token.update", "scene.token.clone"],
12355
12616
  (result) => renderTokenDetails(result.sceneId, result.token)
12356
12617
  ),
12357
12618
  deleteRenderer("scene.token.delete", "token", { suffix: sceneSuffix }),
12619
+ detailRenderer("scene.token.restore-delta", (result) => renderTokenDeltaRestore(result)),
12358
12620
  listRenderer("scene.token.item.list", {
12359
12621
  key: "items",
12360
12622
  empty: "No items found.",
@@ -12372,7 +12634,7 @@ var RENDERERS = registerRenderers([
12372
12634
  empty: "No tiles found.",
12373
12635
  heading: "Tiles",
12374
12636
  prefix: scenePrefix,
12375
- row: (tile) => `${tile.id} (${tile.x},${tile.y}) ${tile.width}x${tile.height} hidden=${String(Boolean(tile.hidden))}`
12637
+ row: (tile) => `${tile.id} (${tile.x},${tile.y}) ${tile.width}x${tile.height} hidden=${String(Boolean(tile.hidden))}${levelMembershipCell(tile)}`
12376
12638
  }),
12377
12639
  detailRenderer(
12378
12640
  ["scene.tile.get", "scene.tile.create", "scene.tile.update", "scene.tile.clone"],
@@ -12384,7 +12646,7 @@ var RENDERERS = registerRenderers([
12384
12646
  empty: "No sounds found.",
12385
12647
  heading: "Sounds",
12386
12648
  prefix: scenePrefix,
12387
- row: (sound) => `${sound.id} ${sound.path ?? ""} (${sound.x},${sound.y}) r=${sound.radius} hidden=${String(Boolean(sound.hidden))}`
12649
+ row: (sound) => `${sound.id} ${sound.path ?? ""} (${sound.x},${sound.y}) r=${sound.radius} hidden=${String(Boolean(sound.hidden))}${levelMembershipCell(sound)}`
12388
12650
  }),
12389
12651
  detailRenderer(
12390
12652
  ["scene.sound.get", "scene.sound.create", "scene.sound.update", "scene.sound.clone"],
@@ -12396,20 +12658,32 @@ var RENDERERS = registerRenderers([
12396
12658
  empty: "No walls found.",
12397
12659
  heading: "Walls",
12398
12660
  prefix: scenePrefix,
12399
- row: (wall) => `${wall.id} ${wall.door ?? 0}/${wall.ds ?? 0}/${wall.doorSound ?? ""} c=[${(wall.c ?? []).join(",")}]`
12661
+ row: (wall) => `${wall.id} ${wall.door ?? 0}/${wall.ds ?? 0}/${wall.doorSound ?? ""} c=[${(wall.c ?? []).join(",")}]${levelMembershipCell(wall)}`
12400
12662
  }),
12401
12663
  detailRenderer(
12402
12664
  ["scene.wall.get", "scene.wall.create", "scene.wall.update", "scene.wall.clone"],
12403
12665
  (result) => renderWallDetails(result.sceneId, result.wall)
12404
12666
  ),
12405
12667
  deleteRenderer("scene.wall.delete", "wall", { suffix: sceneSuffix }),
12668
+ listRenderer("scene.level.list", {
12669
+ key: "levels",
12670
+ empty: "No levels found.",
12671
+ heading: "Levels",
12672
+ prefix: scenePrefix,
12673
+ row: (level) => renderLevelRow(level)
12674
+ }),
12675
+ detailRenderer(
12676
+ ["scene.level.get", "scene.level.create", "scene.level.update", "scene.level.clone"],
12677
+ (result) => renderLevelDetails(result.sceneId, result.level)
12678
+ ),
12679
+ deleteRenderer("scene.level.delete", "level", { suffix: sceneSuffix }),
12406
12680
  detailRenderer(BATCH_WRITE_COMMANDS, (result, command) => renderBatchWriteResult(command, result)),
12407
12681
  listRenderer("scene.note.list", {
12408
12682
  key: "notes",
12409
12683
  empty: "No notes found.",
12410
12684
  heading: "Notes",
12411
12685
  prefix: scenePrefix,
12412
- row: (note) => `${note.id} ${note.text ?? ""} (${note.x},${note.y}) ${note.texture?.src ?? ""} ${note.iconSize ?? ""}`
12686
+ row: (note) => `${note.id} ${note.text ?? ""} (${note.x},${note.y}) ${note.texture?.src ?? ""} ${note.iconSize ?? ""}${levelMembershipCell(note)}`
12413
12687
  }),
12414
12688
  detailRenderer(
12415
12689
  ["scene.note.get", "scene.note.create", "scene.note.update", "scene.note.clone"],
@@ -12421,7 +12695,7 @@ var RENDERERS = registerRenderers([
12421
12695
  empty: "No drawings found.",
12422
12696
  heading: "Drawings",
12423
12697
  prefix: scenePrefix,
12424
- row: (drawing) => `${drawing.id} ${drawing.text ?? ""} (${drawing.x},${drawing.y}) ${drawing.shape?.type ?? ""} ${String(Boolean(drawing.hidden))} ${drawing.name ?? "(no name)"}`
12698
+ row: (drawing) => `${drawing.id} ${drawing.text ?? ""} (${drawing.x},${drawing.y}) ${drawing.shape?.type ?? ""} ${String(Boolean(drawing.hidden))} ${drawing.name ?? "(no name)"}${levelMembershipCell(drawing)}`
12425
12699
  }),
12426
12700
  detailRenderer(
12427
12701
  ["scene.drawing.get", "scene.drawing.create", "scene.drawing.update", "scene.drawing.clone"],
@@ -12433,7 +12707,7 @@ var RENDERERS = registerRenderers([
12433
12707
  empty: "No lights found.",
12434
12708
  heading: "Lights",
12435
12709
  prefix: scenePrefix,
12436
- row: (light) => `${light.id} (${light.x},${light.y}) ${light.config?.dim ?? ""}/${light.config?.bright ?? ""} ${String(Boolean(light.hidden))} ${light.name ?? "(no name)"}`
12710
+ row: (light) => `${light.id} (${light.x},${light.y}) ${light.config?.dim ?? ""}/${light.config?.bright ?? ""} ${String(Boolean(light.hidden))} ${light.name ?? "(no name)"}${levelMembershipCell(light)}`
12437
12711
  }),
12438
12712
  detailRenderer(
12439
12713
  ["scene.light.get", "scene.light.create", "scene.light.update", "scene.light.clone"],
@@ -12457,7 +12731,7 @@ var RENDERERS = registerRenderers([
12457
12731
  empty: "No regions found.",
12458
12732
  heading: "Regions",
12459
12733
  prefix: scenePrefix,
12460
- row: (region) => `${region.id} ${region.name ?? ""} ${region.visibility ?? ""} shapes=${region.shapesCount ?? 0} behaviors=${region.behaviorsCount ?? 0}`
12734
+ row: (region) => `${region.id} ${region.name ?? ""} ${region.visibility ?? ""} shapes=${region.shapesCount ?? 0} behaviors=${region.behaviorsCount ?? 0}${levelMembershipCell(region)}`
12461
12735
  }),
12462
12736
  detailRenderer(
12463
12737
  ["scene.region.get", "scene.region.create", "scene.region.update", "scene.region.clone"],
@@ -12856,11 +13130,17 @@ function addReservedIncludeOption(command, presence) {
12856
13130
  function addActorIncludeOption(command) {
12857
13131
  return command.option(
12858
13132
  "--include <fields>",
12859
- "Comma-separated extra fields (items.flags, items.effects, prepared add output; flags/effects are always present, so those two have no effect)",
13133
+ "Comma-separated extra fields (items adds the owned items, which items.flags and items.effects also imply; prepared adds derived data; flags/effects are always present, so those two have no effect)",
12860
13134
  parseActorIncludeFields
12861
13135
  );
12862
13136
  }
13137
+ var INITIAL_LEVEL_FIELD = {
13138
+ flag: "--initial-level <initialLevel>",
13139
+ help: "Initial level id (Foundry v14)"
13140
+ };
12863
13141
  var SCENE_FIELDS = [
13142
+ FOLDER_ID_FIELD,
13143
+ CLEAR_FOLDER_FIELD,
12864
13144
  { flag: "--active <active>", help: "Scene active state", parser: parseBoolean },
12865
13145
  { flag: "--navigation <navigation>", help: "Scene navigation visibility", parser: parseBoolean },
12866
13146
  { flag: "--nav-order <navOrder>", help: "Scene navigation order", parser: parseNumber },
@@ -12873,14 +13153,14 @@ var SCENE_FIELDS = [
12873
13153
  { flag: "--shift-y <shiftY>", help: "Background Y shift", parser: parseNumber },
12874
13154
  { flag: "--nav-name <navName>", help: "Navigation label" },
12875
13155
  { flag: "--thumb <thumb>", help: "Thumbnail image path" },
12876
- { flag: "--foreground <foreground>", help: "Foreground image path" },
13156
+ { flag: "--foreground <foreground>", help: "Foreground image path (Foundry v13)" },
12877
13157
  {
12878
13158
  flag: "--foreground-elevation <foregroundElevation>",
12879
- help: "Foreground image elevation",
13159
+ help: "Foreground image elevation (Foundry v13)",
12880
13160
  parser: parseNumber
12881
13161
  },
12882
13162
  { flag: "--sort <sort>", help: "Sort order", parser: parseNumber },
12883
- { flag: "--initial-level <initialLevel>", help: "Initial elevation level id" },
13163
+ INITIAL_LEVEL_FIELD,
12884
13164
  { flag: "--playlist <playlistId>", help: "Linked playlist id" },
12885
13165
  { flag: "--playlist-sound <playlistSoundId>", help: "Linked playlist sound id" },
12886
13166
  { flag: "--journal <journalId>", help: "Linked journal id" },
@@ -12900,14 +13180,15 @@ var SCENE_FIELDS = [
12900
13180
  {
12901
13181
  flag: "--background-json <json>",
12902
13182
  help: {
12903
- create: "Scene background as JSON object",
12904
- update: "Scene background patch as JSON object",
12905
- clone: "Scene background override as JSON object"
13183
+ create: "Scene background as JSON object (Foundry v13)",
13184
+ update: "Scene background patch as JSON object (Foundry v13)",
13185
+ clone: "Scene background override as JSON object (Foundry v13)"
12906
13186
  }
12907
13187
  }
12908
13188
  ];
12909
13189
  function addSceneFieldOptions(command, verb) {
12910
- return addFieldOptions(command, verb, SCENE_FIELDS);
13190
+ const specs = verb === "create" ? SCENE_FIELDS.filter((spec) => spec !== INITIAL_LEVEL_FIELD) : SCENE_FIELDS;
13191
+ return addFieldOptions(command, verb, specs);
12911
13192
  }
12912
13193
  var TOKEN_NAME_FIELD = {
12913
13194
  flag: "--name <name>",
@@ -14351,7 +14632,9 @@ function createDaemonControlRunner(dependencies) {
14351
14632
  `);
14352
14633
  else if (response.ok) write(dependencies.stdout, `${JSON.stringify(response.result, null, 2)}
14353
14634
  `);
14354
- else
14635
+ else write(dependencies.stderr, `${renderProtocolError(response.error)}
14636
+ `);
14637
+ if (!response.ok)
14355
14638
  throw new CommanderError4(
14356
14639
  exitCodeForErrorCode(response.error?.code),
14357
14640
  "fvtt-world-cli.remoteError",
@@ -14684,11 +14967,9 @@ function recordSkillInstalls(dependencies, roots, { remove = false } = {}) {
14684
14967
  else current.add(root);
14685
14968
  }
14686
14969
  const skillInstalls = [...current].sort();
14687
- dependencies.configStore.writeConfig(
14688
- mergePersistedCliConfig(
14689
- existing,
14690
- skillInstalls.length > 0 ? { skillInstalls } : { skillInstalls: void 0 }
14691
- )
14970
+ writeCliConfigUpdate(
14971
+ dependencies.configStore,
14972
+ skillInstalls.length > 0 ? { skillInstalls } : { skillInstalls: void 0 }
14692
14973
  );
14693
14974
  } catch (error) {
14694
14975
  const message = error instanceof Error ? error.message : String(error);
@@ -15473,11 +15754,18 @@ function registerCombat({ program, dependencies }) {
15473
15754
  }
15474
15755
 
15475
15756
  // src/commands/compendium.ts
15757
+ function addCompendiumIncludeOption(command) {
15758
+ return command.option(
15759
+ "--include <fields>",
15760
+ "Comma-separated extra fields to include (allowed: effects)",
15761
+ parseCompendiumIncludeFields
15762
+ );
15763
+ }
15476
15764
  function registerCompendium({ program, dependencies }) {
15477
15765
  const compendium = program.command("compendium").description("Foundry compendium pack commands (read)");
15478
15766
  compendium.addHelpText(
15479
15767
  "after",
15480
- "\nResult key (--json): .result.packs[] (list), .result.entries[] (index), .result.document (get \u2014 Foundry's raw source object)."
15768
+ "\nResult key (--json): .result.packs[] (list), .result.entries[] (index), .result.document (get \u2014 Foundry's raw source object plus id, compendiumSource and duplicateSource), .result.entries[] (get-many \u2014 one get result per requested id, in request order)."
15481
15769
  );
15482
15770
  addPaginationOptions(compendium.command("list")).action(async function listCompendiums(options) {
15483
15771
  await executeRemoteCommand({
@@ -15507,10 +15795,8 @@ function registerCompendium({ program, dependencies }) {
15507
15795
  dependencies
15508
15796
  });
15509
15797
  });
15510
- compendium.command("get").requiredOption("--pack <pack>", "Compendium pack id").requiredOption("--entry-id <entryId>", "Compendium entry id").option(
15511
- "--include <fields>",
15512
- "Comma-separated extra fields to include (allowed: effects)",
15513
- parseCompendiumIncludeFields
15798
+ addCompendiumIncludeOption(
15799
+ compendium.command("get").requiredOption("--pack <pack>", "Compendium pack id").requiredOption("--entry-id <entryId>", "Compendium entry id")
15514
15800
  ).action(async function getCompendiumEntry(options) {
15515
15801
  await executeRemoteCommand({
15516
15802
  commandName: "compendium.get",
@@ -15523,6 +15809,20 @@ function registerCompendium({ program, dependencies }) {
15523
15809
  dependencies
15524
15810
  });
15525
15811
  });
15812
+ addCompendiumIncludeOption(
15813
+ compendium.command("get-many").description("Read several entries of one compendium pack in a single call").requiredOption("--pack <pack>", "Compendium pack id").requiredOption("--ids <list>", "Comma-separated entry ids (atomic: all must exist)", parseIdList)
15814
+ ).action(async function getManyCompendiumEntries(options) {
15815
+ await executeRemoteCommand({
15816
+ commandName: "compendium.get-many",
15817
+ params: {
15818
+ pack: options.pack,
15819
+ ids: options.ids,
15820
+ ...options.include ? { include: options.include } : {}
15821
+ },
15822
+ command: this,
15823
+ dependencies
15824
+ });
15825
+ });
15526
15826
  }
15527
15827
 
15528
15828
  // src/commands/config.ts
@@ -15547,12 +15847,7 @@ function registerConfig({ program, dependencies }) {
15547
15847
  });
15548
15848
  config.command("set-upload-limit").description("Persist the file.upload size limit (raw bytes, pre-base64) for the daemon and CLI").argument("<size>", "Upload size limit as bytes or a size like 100MiB (max 512MiB)").action(function setUploadLimit(size) {
15549
15849
  const uploadLimitBytes = parseUploadLimitBytes(size);
15550
- const persistedConfig = getStoredConfig(dependencies);
15551
- const nextConfig = mergePersistedCliConfig(persistedConfig, {
15552
- daemonUrl: persistedConfig?.daemonUrl ?? DEFAULT_DAEMON_URL,
15553
- uploadLimitBytes
15554
- });
15555
- dependencies.configStore.writeConfig(nextConfig);
15850
+ writeCliConfigUpdate(dependencies.configStore, { uploadLimitBytes });
15556
15851
  const payload = {
15557
15852
  configPath: dependencies.configStore.getConfigPath(),
15558
15853
  uploadLimitBytes,
@@ -16680,6 +16975,12 @@ function registerPlaylist({ program, dependencies }) {
16680
16975
 
16681
16976
  // src/commands/scene.ts
16682
16977
  import { Option as Option11 } from "commander";
16978
+ function addSceneLevelScopeOption(command) {
16979
+ return command.requiredOption("--scene-id <sceneId>", "Scene id");
16980
+ }
16981
+ function addSceneLevelTargetOptions(command, levelDescription = "Level id") {
16982
+ return addSceneLevelScopeOption(command).requiredOption("--level-id <levelId>", levelDescription);
16983
+ }
16683
16984
  function registerScene({ program, dependencies }) {
16684
16985
  const { registerOwnershipSet, registerCompendiumImport, registerBatchWriteCommands } = createSharedRegistrars(dependencies);
16685
16986
  const scene = program.command("scene").description("Foundry scene commands");
@@ -16816,17 +17117,26 @@ function registerScene({ program, dependencies }) {
16816
17117
  const sceneToken = scene.command("token").description("Scene-embedded token commands");
16817
17118
  addNameFilterOption(
16818
17119
  addPaginationOptions(sceneToken.command("list").requiredOption("--scene-id <sceneId>", "Scene id"))
17120
+ ).option(
17121
+ "--include <fields>",
17122
+ "Comma-separated extra fields to include (allowed: delta \u2014 a derived per-token summary of the token-level overrides, null when there are none)",
17123
+ parseTokenListIncludeFields
16819
17124
  ).action(async function listSceneTokens(options) {
16820
17125
  await executeRemoteCommand({
16821
17126
  commandName: "scene.token.list",
16822
- params: { sceneId: options.sceneId, ...nameFilterParams(options), ...paginationParams(options) },
17127
+ params: {
17128
+ sceneId: options.sceneId,
17129
+ ...nameFilterParams(options),
17130
+ ...paginationParams(options),
17131
+ ...options.include ? { include: options.include } : {}
17132
+ },
16823
17133
  command: this,
16824
17134
  dependencies
16825
17135
  });
16826
17136
  });
16827
17137
  sceneToken.command("get").requiredOption("--scene-id <sceneId>", "Scene id").requiredOption("--token-id <tokenId>", "Token id").option(
16828
17138
  "--include <fields>",
16829
- "Comma-separated extra fields to include (allowed: prepared)",
17139
+ "Comma-separated extra fields to include (allowed: prepared, delta \u2014 the stored ActorDelta source, null for a linked token or when none is stored)",
16830
17140
  parseTokenIncludeFields
16831
17141
  ).action(async function getSceneToken(options) {
16832
17142
  await executeRemoteCommand({
@@ -16881,6 +17191,16 @@ function registerScene({ program, dependencies }) {
16881
17191
  dependencies
16882
17192
  });
16883
17193
  });
17194
+ sceneToken.command("restore-delta").description(
17195
+ "Discard every token-level override of an unlinked token (items, effects, system data, name, \u2026) so it follows its world actor again"
17196
+ ).requiredOption("--scene-id <sceneId>", "Scene id").requiredOption("--token-id <tokenId>", "Unlinked token id").action(async function restoreSceneTokenDelta(options) {
17197
+ await executeRemoteCommand({
17198
+ commandName: "scene.token.restore-delta",
17199
+ params: { sceneId: options.sceneId, tokenId: options.tokenId },
17200
+ command: this,
17201
+ dependencies
17202
+ });
17203
+ });
16884
17204
  registerBatchWriteCommands(sceneToken, {
16885
17205
  prefix: "scene.token",
16886
17206
  noun: "token",
@@ -17255,6 +17575,58 @@ function registerScene({ program, dependencies }) {
17255
17575
  });
17256
17576
  });
17257
17577
  registerBatchWriteCommands(sceneWall, { prefix: "scene.wall", noun: "wall" });
17578
+ const sceneLevel = scene.command("level").description("Scene level commands (Foundry v14)");
17579
+ addPaginationOptions(addSceneLevelScopeOption(sceneLevel.command("list"))).action(
17580
+ async function listSceneLevels(options) {
17581
+ await executeRemoteCommand({
17582
+ commandName: "scene.level.list",
17583
+ params: { sceneId: options.sceneId, ...paginationParams(options) },
17584
+ command: this,
17585
+ dependencies
17586
+ });
17587
+ }
17588
+ );
17589
+ addSceneLevelTargetOptions(sceneLevel.command("get")).action(async function getSceneLevel(options) {
17590
+ await executeRemoteCommand({
17591
+ commandName: "scene.level.get",
17592
+ params: { sceneId: options.sceneId, levelId: options.levelId },
17593
+ command: this,
17594
+ dependencies
17595
+ });
17596
+ });
17597
+ addSceneLevelScopeOption(addIdempotencyKeyOption(sceneLevel.command("create"))).option("--data-json <json>", "Level data as a JSON object (name is required; e.g. elevation/background)").action(async function createSceneLevel(options) {
17598
+ await executeRemoteCommand({
17599
+ commandName: "scene.level.create",
17600
+ params: createSceneLevelCreateParams(options),
17601
+ command: this,
17602
+ dependencies
17603
+ });
17604
+ });
17605
+ addSceneLevelTargetOptions(sceneLevel.command("update")).option("--patch-json <json>", "Level patch as a JSON object (e.g. background/foreground/elevation)").action(async function updateSceneLevel(options) {
17606
+ await executeRemoteCommand({
17607
+ commandName: "scene.level.update",
17608
+ params: createSceneLevelUpdateParams(options),
17609
+ command: this,
17610
+ dependencies
17611
+ });
17612
+ });
17613
+ addSceneLevelTargetOptions(addIdempotencyKeyOption(sceneLevel.command("clone")), "Source level id").option("--patch-json <json>", "Override fields for the clone as a JSON object").action(async function cloneSceneLevel(options) {
17614
+ await executeRemoteCommand({
17615
+ commandName: "scene.level.clone",
17616
+ params: createSceneLevelCloneParams(options),
17617
+ command: this,
17618
+ dependencies
17619
+ });
17620
+ });
17621
+ addSceneLevelTargetOptions(sceneLevel.command("delete")).action(async function deleteSceneLevel(options) {
17622
+ await executeRemoteCommand({
17623
+ commandName: "scene.level.delete",
17624
+ params: { sceneId: options.sceneId, levelId: options.levelId },
17625
+ command: this,
17626
+ dependencies
17627
+ });
17628
+ });
17629
+ registerBatchWriteCommands(sceneLevel, { prefix: "scene.level", noun: "level" });
17258
17630
  const sceneNote = scene.command("note").description("Scene-embedded note (map pin) commands");
17259
17631
  addPaginationOptions(sceneNote.command("list").requiredOption("--scene-id <sceneId>", "Scene id")).action(
17260
17632
  async function listSceneNotes(options) {
@@ -18009,7 +18381,7 @@ function registerSystem({ program, dependencies }) {
18009
18381
  const system = program.command("system").description("Foundry bridge system commands");
18010
18382
  system.addHelpText(
18011
18383
  "after",
18012
- "\nResult key (--json): .result.pong + .result.bridge (ping); .result.foundry.* / .result.system.* / .result.world.* / .result.module.* / .result.modules[] / .result.bridge.* / .result.limits.* / .result.commands[] (info)."
18384
+ "\nResult key (--json): .result.pong + .result.bridge (ping); .result.foundry.* / .result.system.* / .result.world.* / .result.module.* / .result.moduleCount / .result.activeModuleCount / .result.modules[] (with --include modules) / .result.bridge.* / .result.limits.* (info)."
18013
18385
  );
18014
18386
  system.command("ping").action(async function ping() {
18015
18387
  await executeRemoteCommand({
@@ -18019,10 +18391,14 @@ function registerSystem({ program, dependencies }) {
18019
18391
  dependencies
18020
18392
  });
18021
18393
  });
18022
- system.command("info").action(async function info() {
18394
+ system.command("info").option(
18395
+ "--include <fields>",
18396
+ "Comma-separated extra fields (modules adds the installed module list)",
18397
+ parseSystemInfoIncludeFields
18398
+ ).action(async function info(options) {
18023
18399
  await executeRemoteCommand({
18024
18400
  commandName: "system.info",
18025
- params: {},
18401
+ params: options.include ? { include: options.include } : {},
18026
18402
  command: this,
18027
18403
  dependencies
18028
18404
  });