@lotics/cli 0.111.0 → 0.113.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/cli.js CHANGED
@@ -33334,8 +33334,8 @@ var require_utils2 = __commonJS({
33334
33334
  var { Address } = require_helpers();
33335
33335
  var { Prefix, Postfix, Infix, Operators } = require_operators();
33336
33336
  var Collection = require_collection();
33337
- var MAX_ROW = 1048576;
33338
- var MAX_COLUMN = 16384;
33337
+ var MAX_ROW2 = 1048576;
33338
+ var MAX_COLUMN2 = 16384;
33339
33339
  var { NotAllInputParsedException } = require_api();
33340
33340
  var Utils = class {
33341
33341
  constructor(context) {
@@ -33564,7 +33564,7 @@ var require_utils2 = __commonJS({
33564
33564
  // * @return {{ref: {from: {col: number, row: number}, to: {col: number, row: number}}}}
33565
33565
  */
33566
33566
  applyRange(refs) {
33567
- let res, maxRow = -1, maxCol = -1, minRow = MAX_ROW + 1, minCol = MAX_COLUMN + 1;
33567
+ let res, maxRow = -1, maxCol = -1, minRow = MAX_ROW2 + 1, minCol = MAX_COLUMN2 + 1;
33568
33568
  refs.forEach((ref2) => {
33569
33569
  if (this.isFormulaError(ref2))
33570
33570
  return ref2;
@@ -33574,11 +33574,11 @@ var require_utils2 = __commonJS({
33574
33574
  ref2 = ref2.ref;
33575
33575
  if (ref2.row === void 0) {
33576
33576
  minRow = 1;
33577
- maxRow = MAX_ROW;
33577
+ maxRow = MAX_ROW2;
33578
33578
  }
33579
33579
  if (ref2.col === void 0) {
33580
33580
  minCol = 1;
33581
- maxCol = MAX_COLUMN;
33581
+ maxCol = MAX_COLUMN2;
33582
33582
  }
33583
33583
  if (ref2.row > maxRow)
33584
33584
  maxRow = ref2.row;
@@ -34014,8 +34014,8 @@ var require_utils3 = __commonJS({
34014
34014
  var { FormulaHelpers, Types, Address } = require_helpers();
34015
34015
  var { Prefix, Postfix, Infix, Operators } = require_operators();
34016
34016
  var Collection = require_collection();
34017
- var MAX_ROW = 1048576;
34018
- var MAX_COLUMN = 16384;
34017
+ var MAX_ROW2 = 1048576;
34018
+ var MAX_COLUMN2 = 16384;
34019
34019
  var Utils = class {
34020
34020
  constructor(context) {
34021
34021
  this.context = context;
@@ -34161,7 +34161,7 @@ var require_utils3 = __commonJS({
34161
34161
  // * @return {{ref: {from: {col: number, row: number}, to: {col: number, row: number}}}}
34162
34162
  */
34163
34163
  applyRange(refs) {
34164
- let res, maxRow = -1, maxCol = -1, minRow = MAX_ROW + 1, minCol = MAX_COLUMN + 1;
34164
+ let res, maxRow = -1, maxCol = -1, minRow = MAX_ROW2 + 1, minCol = MAX_COLUMN2 + 1;
34165
34165
  refs.forEach((ref2) => {
34166
34166
  if (this.isFormulaError(ref2))
34167
34167
  return ref2;
@@ -34171,11 +34171,11 @@ var require_utils3 = __commonJS({
34171
34171
  ref2 = ref2.ref;
34172
34172
  if (ref2.row === void 0) {
34173
34173
  minRow = 1;
34174
- maxRow = MAX_ROW;
34174
+ maxRow = MAX_ROW2;
34175
34175
  }
34176
34176
  if (ref2.col === void 0) {
34177
34177
  minCol = 1;
34178
- maxCol = MAX_COLUMN;
34178
+ maxCol = MAX_COLUMN2;
34179
34179
  }
34180
34180
  if (ref2.row > maxRow)
34181
34181
  maxRow = ref2.row;
@@ -44124,9 +44124,9 @@ var require_load = __commonJS({
44124
44124
  var require_lib4 = __commonJS({
44125
44125
  "../../node_modules/jszip/lib/index.js"(exports2, module2) {
44126
44126
  "use strict";
44127
- function JSZip4() {
44128
- if (!(this instanceof JSZip4)) {
44129
- return new JSZip4();
44127
+ function JSZip5() {
44128
+ if (!(this instanceof JSZip5)) {
44129
+ return new JSZip5();
44130
44130
  }
44131
44131
  if (arguments.length) {
44132
44132
  throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");
@@ -44135,7 +44135,7 @@ var require_lib4 = __commonJS({
44135
44135
  this.comment = null;
44136
44136
  this.root = "";
44137
44137
  this.clone = function() {
44138
- var newObj = new JSZip4();
44138
+ var newObj = new JSZip5();
44139
44139
  for (var i2 in this) {
44140
44140
  if (typeof this[i2] !== "function") {
44141
44141
  newObj[i2] = this[i2];
@@ -44144,16 +44144,16 @@ var require_lib4 = __commonJS({
44144
44144
  return newObj;
44145
44145
  };
44146
44146
  }
44147
- JSZip4.prototype = require_object();
44148
- JSZip4.prototype.loadAsync = require_load();
44149
- JSZip4.support = require_support();
44150
- JSZip4.defaults = require_defaults();
44151
- JSZip4.version = "3.10.1";
44152
- JSZip4.loadAsync = function(content, options) {
44153
- return new JSZip4().loadAsync(content, options);
44147
+ JSZip5.prototype = require_object();
44148
+ JSZip5.prototype.loadAsync = require_load();
44149
+ JSZip5.support = require_support();
44150
+ JSZip5.defaults = require_defaults();
44151
+ JSZip5.version = "3.10.1";
44152
+ JSZip5.loadAsync = function(content, options) {
44153
+ return new JSZip5().loadAsync(content, options);
44154
44154
  };
44155
- JSZip4.external = require_external();
44156
- module2.exports = JSZip4;
44155
+ JSZip5.external = require_external();
44156
+ module2.exports = JSZip5;
44157
44157
  }
44158
44158
  });
44159
44159
 
@@ -62234,353 +62234,6 @@ var templatePartSchema = zod_default.lazy(
62234
62234
  ])
62235
62235
  );
62236
62236
 
62237
- // ../shared/src/schemas/table_filters.ts
62238
- var tableRecordNumberFieldFilterSchema = zod_default.object({
62239
- type: zod_default.literal("number"),
62240
- field_key: zod_default.string(),
62241
- operator: zod_default.enum([
62242
- "equals",
62243
- "not_equals",
62244
- "greater_than",
62245
- "less_than",
62246
- "greater_than_or_equal_to",
62247
- "less_than_or_equal_to",
62248
- "is_empty",
62249
- "is_not_empty"
62250
- ]),
62251
- value: zod_default.number().nullable()
62252
- });
62253
- var tableRecordTextFieldFilterSchema = zod_default.object({
62254
- type: zod_default.literal("text"),
62255
- field_key: zod_default.string(),
62256
- operator: zod_default.enum([
62257
- "equals",
62258
- "not_equals",
62259
- "contains",
62260
- "does_not_contain",
62261
- "starts_with",
62262
- "ends_with",
62263
- "is_empty",
62264
- "is_not_empty",
62265
- "is_any_of",
62266
- "is_none_of"
62267
- ]),
62268
- value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
62269
- });
62270
- var dateTimePointExactSchema = zod_default.object({
62271
- type: zod_default.literal("exact"),
62272
- date: zod_default.string().nullable().describe("ISO 8601 date (YYYY-MM-DD)"),
62273
- time: zod_default.string().nullable().optional().describe("Time HH:mm")
62274
- });
62275
- var timeUnitSchema = zod_default.enum(["minutes", "hours", "days", "weeks", "months", "years"]);
62276
- var dateTimePointRelativeSchema = zod_default.object({
62277
- type: zod_default.literal("relative"),
62278
- offset: zod_default.number().describe("Negative=past, positive=future"),
62279
- unit: timeUnitSchema,
62280
- time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
62281
- });
62282
- var dateTimePointPeriodSchema = zod_default.object({
62283
- type: zod_default.literal("period"),
62284
- period: zod_default.enum(["day", "week", "month", "quarter", "year"]),
62285
- boundary: zod_default.enum(["start", "end"]),
62286
- offset: zod_default.number().optional().describe("0=current, -1=last, 1=next"),
62287
- time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
62288
- });
62289
- var dateTimePointSchema = zod_default.discriminatedUnion("type", [
62290
- dateTimePointExactSchema,
62291
- dateTimePointRelativeSchema,
62292
- dateTimePointPeriodSchema
62293
- ]);
62294
- var betweenRangeValueSchema = zod_default.object({
62295
- start: dateTimePointSchema.nullable().describe("Null=no lower bound"),
62296
- end: dateTimePointSchema.nullable().describe("Null=no upper bound")
62297
- });
62298
- var timeOnlyValueSchema = zod_default.object({
62299
- start_time: zod_default.string().nullable().describe("HH:mm"),
62300
- end_time: zod_default.string().nullable().describe("HH:mm")
62301
- });
62302
- var durationValueSchema = zod_default.object({
62303
- amount: zod_default.number(),
62304
- unit: zod_default.enum(["minutes", "hours", "days"])
62305
- });
62306
- var tableRecordDateFieldFilterBaseSchema = zod_default.object({
62307
- type: zod_default.literal("date"),
62308
- field_key: zod_default.string()
62309
- });
62310
- var tableRecordDateFieldFilterEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
62311
- operator: zod_default.literal("is_empty"),
62312
- value: zod_default.null()
62313
- });
62314
- var tableRecordDateFieldFilterNotEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
62315
- operator: zod_default.literal("is_not_empty"),
62316
- value: zod_default.null()
62317
- });
62318
- var tableRecordDateFieldFilterBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62319
- operator: zod_default.literal("before"),
62320
- value: dateTimePointSchema.nullable()
62321
- });
62322
- var tableRecordDateFieldFilterAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62323
- operator: zod_default.literal("after"),
62324
- value: dateTimePointSchema.nullable()
62325
- });
62326
- var tableRecordDateFieldFilterOnOrBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62327
- operator: zod_default.literal("on_or_before"),
62328
- value: dateTimePointSchema.nullable()
62329
- });
62330
- var tableRecordDateFieldFilterOnOrAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62331
- operator: zod_default.literal("on_or_after"),
62332
- value: dateTimePointSchema.nullable()
62333
- });
62334
- var tableRecordDateFieldFilterOnSchema = tableRecordDateFieldFilterBaseSchema.extend({
62335
- operator: zod_default.literal("on"),
62336
- value: dateTimePointSchema.nullable()
62337
- });
62338
- var tableRecordDateFieldFilterBetweenSchema = tableRecordDateFieldFilterBaseSchema.extend({
62339
- operator: zod_default.literal("between"),
62340
- value: betweenRangeValueSchema.nullable()
62341
- });
62342
- var tableRecordDateFieldFilterTimeOfDaySchema = tableRecordDateFieldFilterBaseSchema.extend({
62343
- operator: zod_default.literal("time_of_day"),
62344
- value: timeOnlyValueSchema.nullable()
62345
- });
62346
- var tableRecordDateFieldFilterOverlapsSchema = tableRecordDateFieldFilterBaseSchema.extend({
62347
- operator: zod_default.literal("overlaps"),
62348
- value: betweenRangeValueSchema.nullable()
62349
- });
62350
- var tableRecordDateFieldFilterContainsSchema = tableRecordDateFieldFilterBaseSchema.extend({
62351
- operator: zod_default.literal("contains"),
62352
- value: betweenRangeValueSchema.nullable()
62353
- });
62354
- var tableRecordDateFieldFilterWithinSchema = tableRecordDateFieldFilterBaseSchema.extend({
62355
- operator: zod_default.literal("within"),
62356
- value: betweenRangeValueSchema.nullable()
62357
- });
62358
- var tableRecordDateFieldFilterStartsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62359
- operator: zod_default.literal("starts_before"),
62360
- value: dateTimePointSchema.nullable()
62361
- });
62362
- var tableRecordDateFieldFilterStartsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62363
- operator: zod_default.literal("starts_after"),
62364
- value: dateTimePointSchema.nullable()
62365
- });
62366
- var tableRecordDateFieldFilterEndsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62367
- operator: zod_default.literal("ends_before"),
62368
- value: dateTimePointSchema.nullable()
62369
- });
62370
- var tableRecordDateFieldFilterEndsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62371
- operator: zod_default.literal("ends_after"),
62372
- value: dateTimePointSchema.nullable()
62373
- });
62374
- var tableRecordDateFieldFilterDurationEqualsSchema = tableRecordDateFieldFilterBaseSchema.extend({
62375
- operator: zod_default.literal("duration_equals"),
62376
- value: durationValueSchema.nullable()
62377
- });
62378
- var tableRecordDateFieldFilterDurationGreaterThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
62379
- operator: zod_default.literal("duration_greater_than"),
62380
- value: durationValueSchema.nullable()
62381
- });
62382
- var tableRecordDateFieldFilterDurationLessThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
62383
- operator: zod_default.literal("duration_less_than"),
62384
- value: durationValueSchema.nullable()
62385
- });
62386
- var tableRecordDateFieldFilterSchema = zod_default.discriminatedUnion("operator", [
62387
- tableRecordDateFieldFilterEmptySchema,
62388
- tableRecordDateFieldFilterNotEmptySchema,
62389
- tableRecordDateFieldFilterBeforeSchema,
62390
- tableRecordDateFieldFilterAfterSchema,
62391
- tableRecordDateFieldFilterOnOrBeforeSchema,
62392
- tableRecordDateFieldFilterOnOrAfterSchema,
62393
- tableRecordDateFieldFilterOnSchema,
62394
- tableRecordDateFieldFilterBetweenSchema,
62395
- tableRecordDateFieldFilterTimeOfDaySchema,
62396
- tableRecordDateFieldFilterOverlapsSchema,
62397
- tableRecordDateFieldFilterContainsSchema,
62398
- tableRecordDateFieldFilterWithinSchema,
62399
- tableRecordDateFieldFilterStartsBeforeSchema,
62400
- tableRecordDateFieldFilterStartsAfterSchema,
62401
- tableRecordDateFieldFilterEndsBeforeSchema,
62402
- tableRecordDateFieldFilterEndsAfterSchema,
62403
- tableRecordDateFieldFilterDurationEqualsSchema,
62404
- tableRecordDateFieldFilterDurationGreaterThanSchema,
62405
- tableRecordDateFieldFilterDurationLessThanSchema
62406
- ]);
62407
- var tableRecordBooleanFieldFilterSchema = zod_default.object({
62408
- type: zod_default.literal("boolean"),
62409
- field_key: zod_default.string(),
62410
- operator: zod_default.enum(["equals"]),
62411
- value: zod_default.boolean().nullable()
62412
- });
62413
- var tableRecordSelectFieldFilterSchema = zod_default.object({
62414
- type: zod_default.literal("select"),
62415
- field_key: zod_default.string(),
62416
- operator: zod_default.enum([
62417
- "has_any_of",
62418
- "has_none_of",
62419
- "is_empty",
62420
- "is_not_empty",
62421
- "has_all_of"
62422
- ]),
62423
- value: zod_default.array(zod_default.string()).nullable()
62424
- });
62425
- var tableRecordSelectMemberFieldFilterSchema = zod_default.object({
62426
- type: zod_default.literal("select_member"),
62427
- field_key: zod_default.string(),
62428
- operator: zod_default.enum([
62429
- "has_any_of",
62430
- "has_none_of",
62431
- "is_empty",
62432
- "is_not_empty",
62433
- "has_all_of",
62434
- "is_current_member",
62435
- "is_not_current_member"
62436
- ]),
62437
- value: zod_default.array(zod_default.string()).nullable()
62438
- });
62439
- var tableRecordSelectRecordLinkFieldFilterSchema = zod_default.object({
62440
- type: zod_default.literal("select_record_link"),
62441
- field_key: zod_default.string(),
62442
- operator: zod_default.enum([
62443
- // Membership operators — match linked record IDs. value: string[].
62444
- "has_any_of",
62445
- "has_none_of",
62446
- "has_all_of",
62447
- // Text operators — match the cached display text. value: string.
62448
- "contains",
62449
- "not_contains",
62450
- "starts_with",
62451
- "ends_with",
62452
- "is_empty",
62453
- "is_not_empty"
62454
- ]),
62455
- value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
62456
- });
62457
- var tableRecordFilesFieldFilterSchema = zod_default.object({
62458
- type: zod_default.literal("files"),
62459
- field_key: zod_default.string(),
62460
- operator: zod_default.enum(["has_filename", "has_mime_type", "has_file_count", "is_empty", "is_not_empty"]),
62461
- value: zod_default.string().nullable()
62462
- });
62463
- var tableRecordLockedFilterSchema = zod_default.object({
62464
- type: zod_default.literal("locked"),
62465
- operator: zod_default.enum(["is_locked", "is_not_locked"]),
62466
- value: zod_default.null()
62467
- });
62468
- var tableRecordCurrentMemberFilterSchema = zod_default.object({
62469
- type: zod_default.literal("current_member"),
62470
- operator: zod_default.enum(["in_any_group"]),
62471
- value: zod_default.array(zod_default.string())
62472
- });
62473
- var tableRecordRecordIdFilterSchema = zod_default.object({
62474
- type: zod_default.literal("record_id"),
62475
- operator: zod_default.enum(["is_any_of", "is_none_of"]),
62476
- value: zod_default.array(zod_default.string())
62477
- });
62478
- var tableRecordFieldFilterConditionSchema = zod_default.union([
62479
- tableRecordTextFieldFilterSchema,
62480
- tableRecordNumberFieldFilterSchema,
62481
- tableRecordDateFieldFilterSchema,
62482
- tableRecordBooleanFieldFilterSchema,
62483
- tableRecordSelectMemberFieldFilterSchema,
62484
- tableRecordSelectFieldFilterSchema,
62485
- tableRecordSelectRecordLinkFieldFilterSchema,
62486
- tableRecordFilesFieldFilterSchema
62487
- ]);
62488
- var tableRecordFiltersConditionNodeSchema = zod_default.object({
62489
- node_type: zod_default.literal("condition"),
62490
- field_key: zod_default.string().optional(),
62491
- type: zod_default.string().optional(),
62492
- operator: zod_default.string(),
62493
- value: zod_default.unknown().optional()
62494
- });
62495
- var tableRecordFiltersTraversalNodeSchema = zod_default.object({
62496
- node_type: zod_default.literal("traversal"),
62497
- path: zod_default.array(zod_default.string()),
62498
- condition: tableRecordFiltersConditionNodeSchema
62499
- });
62500
- var tableRecordFiltersGroupNodeSchema = zod_default.lazy(
62501
- () => zod_default.object({
62502
- node_type: zod_default.literal("group"),
62503
- logic: zod_default.enum(["and", "or"]),
62504
- children: zod_default.array(
62505
- zod_default.union([
62506
- tableRecordFiltersConditionNodeSchema,
62507
- tableRecordFiltersTraversalNodeSchema,
62508
- tableRecordFiltersGroupNodeSchema
62509
- ])
62510
- )
62511
- })
62512
- );
62513
- var tableRecordFiltersSchema = zod_default.union([
62514
- tableRecordFiltersConditionNodeSchema,
62515
- tableRecordFiltersTraversalNodeSchema,
62516
- tableRecordFiltersGroupNodeSchema
62517
- ]);
62518
- var optionColorSchema = zod_default.enum([
62519
- "red",
62520
- "orange",
62521
- "amber",
62522
- "yellow",
62523
- "lime",
62524
- "green",
62525
- "emerald",
62526
- "teal",
62527
- "cyan",
62528
- "sky",
62529
- "blue",
62530
- "indigo",
62531
- "violet",
62532
- "purple",
62533
- "fuchsia",
62534
- "pink",
62535
- "rose",
62536
- "slate",
62537
- "gray",
62538
- "zinc",
62539
- "neutral",
62540
- "stone"
62541
- ]);
62542
- var tableRecordColorSchema = zod_default.object({
62543
- filters: tableRecordFiltersGroupNodeSchema.nullable().describe(
62544
- "The filter conditions that determine when this color rule applies. Null means no filtering."
62545
- ),
62546
- color: optionColorSchema.describe(
62547
- "The color to apply to records matching the filters."
62548
- )
62549
- });
62550
- var tableRecordColorsSchema = zod_default.array(tableRecordColorSchema);
62551
- var tableRecordSortSchema = zod_default.array(
62552
- zod_default.object({
62553
- field_key: zod_default.string().describe("Field key to sort by"),
62554
- order: zod_default.enum(["asc", "desc"]).nullable().describe("Sort order: 'asc' for ascending, 'desc' for descending"),
62555
- blank_position: zod_default.enum(["top", "bottom"]).optional().describe("Blank position: 'top' for top, 'bottom' for bottom")
62556
- })
62557
- );
62558
- var TEXT_OPS = tableRecordTextFieldFilterSchema.shape.operator.options;
62559
- var NUMBER_OPS = tableRecordNumberFieldFilterSchema.shape.operator.options;
62560
- var DATE_OPS = tableRecordDateFieldFilterSchema.options.map((s) => s.shape.operator.value);
62561
- var BOOLEAN_OPS = tableRecordBooleanFieldFilterSchema.shape.operator.options;
62562
- var SELECT_OPS = tableRecordSelectFieldFilterSchema.shape.operator.options;
62563
- var SELECT_MEMBER_OPS = tableRecordSelectMemberFieldFilterSchema.shape.operator.options;
62564
- var SELECT_RECORD_LINK_OPS = tableRecordSelectRecordLinkFieldFilterSchema.shape.operator.options;
62565
- var FILES_OPS = tableRecordFilesFieldFilterSchema.shape.operator.options;
62566
- var LOCKED_OPS = tableRecordLockedFilterSchema.shape.operator.options;
62567
- var CURRENT_MEMBER_OPS = tableRecordCurrentMemberFilterSchema.shape.operator.options;
62568
- var RECORD_ID_OPS = tableRecordRecordIdFilterSchema.shape.operator.options;
62569
- var VALID_OPERATORS = {
62570
- text: TEXT_OPS,
62571
- number: NUMBER_OPS,
62572
- date: DATE_OPS,
62573
- boolean: BOOLEAN_OPS,
62574
- select: SELECT_OPS,
62575
- select_member: SELECT_MEMBER_OPS,
62576
- select_record_link: SELECT_RECORD_LINK_OPS,
62577
- files: FILES_OPS,
62578
- locked: LOCKED_OPS,
62579
- current_member: CURRENT_MEMBER_OPS,
62580
- record_id: RECORD_ID_OPS
62581
- };
62582
- var VALID_FILTER_TYPES = Object.keys(VALID_OPERATORS);
62583
-
62584
62237
  // ../../node_modules/date-fns/constants.js
62585
62238
  var daysInYear = 365.2425;
62586
62239
  var maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1e3;
@@ -64461,13 +64114,374 @@ for (const [operation, fieldTypes] of Object.entries(OPERATION_FIELD_TYPES)) {
64461
64114
  }
64462
64115
  var AGGREGATABLE_FIELD_TYPES = new Set(FIELD_TYPE_OPERATIONS.keys());
64463
64116
 
64117
+ // ../shared/src/schemas/table_filters.ts
64118
+ var tableRecordNumberFieldFilterSchema = zod_default.object({
64119
+ type: zod_default.literal("number"),
64120
+ field_key: zod_default.string(),
64121
+ operator: zod_default.enum([
64122
+ "equals",
64123
+ "not_equals",
64124
+ "greater_than",
64125
+ "less_than",
64126
+ "greater_than_or_equal_to",
64127
+ "less_than_or_equal_to",
64128
+ "is_empty",
64129
+ "is_not_empty"
64130
+ ]),
64131
+ value: zod_default.number().nullable()
64132
+ });
64133
+ var tableRecordTextFieldFilterSchema = zod_default.object({
64134
+ type: zod_default.literal("text"),
64135
+ field_key: zod_default.string(),
64136
+ operator: zod_default.enum([
64137
+ "equals",
64138
+ "not_equals",
64139
+ "contains",
64140
+ "does_not_contain",
64141
+ "starts_with",
64142
+ "ends_with",
64143
+ "is_empty",
64144
+ "is_not_empty",
64145
+ "is_any_of",
64146
+ "is_none_of"
64147
+ ]),
64148
+ value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
64149
+ });
64150
+ var dateTimePointExactSchema = zod_default.object({
64151
+ type: zod_default.literal("exact"),
64152
+ date: zod_default.string().nullable().describe("ISO 8601 date (YYYY-MM-DD)"),
64153
+ time: zod_default.string().nullable().optional().describe("Time HH:mm")
64154
+ });
64155
+ var timeUnitSchema = zod_default.enum(["minutes", "hours", "days", "weeks", "months", "years"]);
64156
+ var dateTimePointRelativeSchema = zod_default.object({
64157
+ type: zod_default.literal("relative"),
64158
+ offset: zod_default.number().describe("Negative=past, positive=future"),
64159
+ unit: timeUnitSchema,
64160
+ time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
64161
+ });
64162
+ var dateTimePointPeriodSchema = zod_default.object({
64163
+ type: zod_default.literal("period"),
64164
+ period: zod_default.enum(["day", "week", "month", "quarter", "year"]),
64165
+ boundary: zod_default.enum(["start", "end"]),
64166
+ offset: zod_default.number().optional().describe("0=current, -1=last, 1=next"),
64167
+ time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
64168
+ });
64169
+ var dateTimePointSchema = zod_default.discriminatedUnion("type", [
64170
+ dateTimePointExactSchema,
64171
+ dateTimePointRelativeSchema,
64172
+ dateTimePointPeriodSchema
64173
+ ]);
64174
+ var betweenRangeValueSchema = zod_default.object({
64175
+ start: dateTimePointSchema.nullable().describe("Null=no lower bound"),
64176
+ end: dateTimePointSchema.nullable().describe("Null=no upper bound")
64177
+ });
64178
+ var timeOnlyValueSchema = zod_default.object({
64179
+ start_time: zod_default.string().nullable().describe("HH:mm"),
64180
+ end_time: zod_default.string().nullable().describe("HH:mm")
64181
+ });
64182
+ var durationValueSchema = zod_default.object({
64183
+ amount: zod_default.number(),
64184
+ unit: zod_default.enum(["minutes", "hours", "days"])
64185
+ });
64186
+ var tableRecordDateFieldFilterBaseSchema = zod_default.object({
64187
+ type: zod_default.literal("date"),
64188
+ field_key: zod_default.string()
64189
+ });
64190
+ var tableRecordDateFieldFilterEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
64191
+ operator: zod_default.literal("is_empty"),
64192
+ value: zod_default.null()
64193
+ });
64194
+ var tableRecordDateFieldFilterNotEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
64195
+ operator: zod_default.literal("is_not_empty"),
64196
+ value: zod_default.null()
64197
+ });
64198
+ var tableRecordDateFieldFilterBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64199
+ operator: zod_default.literal("before"),
64200
+ value: dateTimePointSchema.nullable()
64201
+ });
64202
+ var tableRecordDateFieldFilterAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64203
+ operator: zod_default.literal("after"),
64204
+ value: dateTimePointSchema.nullable()
64205
+ });
64206
+ var tableRecordDateFieldFilterOnOrBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64207
+ operator: zod_default.literal("on_or_before"),
64208
+ value: dateTimePointSchema.nullable()
64209
+ });
64210
+ var tableRecordDateFieldFilterOnOrAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64211
+ operator: zod_default.literal("on_or_after"),
64212
+ value: dateTimePointSchema.nullable()
64213
+ });
64214
+ var tableRecordDateFieldFilterOnSchema = tableRecordDateFieldFilterBaseSchema.extend({
64215
+ operator: zod_default.literal("on"),
64216
+ value: dateTimePointSchema.nullable()
64217
+ });
64218
+ var tableRecordDateFieldFilterBetweenSchema = tableRecordDateFieldFilterBaseSchema.extend({
64219
+ operator: zod_default.literal("between"),
64220
+ value: betweenRangeValueSchema.nullable()
64221
+ });
64222
+ var tableRecordDateFieldFilterTimeOfDaySchema = tableRecordDateFieldFilterBaseSchema.extend({
64223
+ operator: zod_default.literal("time_of_day"),
64224
+ value: timeOnlyValueSchema.nullable()
64225
+ });
64226
+ var tableRecordDateFieldFilterOverlapsSchema = tableRecordDateFieldFilterBaseSchema.extend({
64227
+ operator: zod_default.literal("overlaps"),
64228
+ value: betweenRangeValueSchema.nullable()
64229
+ });
64230
+ var tableRecordDateFieldFilterContainsSchema = tableRecordDateFieldFilterBaseSchema.extend({
64231
+ operator: zod_default.literal("contains"),
64232
+ value: betweenRangeValueSchema.nullable()
64233
+ });
64234
+ var tableRecordDateFieldFilterWithinSchema = tableRecordDateFieldFilterBaseSchema.extend({
64235
+ operator: zod_default.literal("within"),
64236
+ value: betweenRangeValueSchema.nullable()
64237
+ });
64238
+ var tableRecordDateFieldFilterStartsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64239
+ operator: zod_default.literal("starts_before"),
64240
+ value: dateTimePointSchema.nullable()
64241
+ });
64242
+ var tableRecordDateFieldFilterStartsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64243
+ operator: zod_default.literal("starts_after"),
64244
+ value: dateTimePointSchema.nullable()
64245
+ });
64246
+ var tableRecordDateFieldFilterEndsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64247
+ operator: zod_default.literal("ends_before"),
64248
+ value: dateTimePointSchema.nullable()
64249
+ });
64250
+ var tableRecordDateFieldFilterEndsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64251
+ operator: zod_default.literal("ends_after"),
64252
+ value: dateTimePointSchema.nullable()
64253
+ });
64254
+ var tableRecordDateFieldFilterDurationEqualsSchema = tableRecordDateFieldFilterBaseSchema.extend({
64255
+ operator: zod_default.literal("duration_equals"),
64256
+ value: durationValueSchema.nullable()
64257
+ });
64258
+ var tableRecordDateFieldFilterDurationGreaterThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
64259
+ operator: zod_default.literal("duration_greater_than"),
64260
+ value: durationValueSchema.nullable()
64261
+ });
64262
+ var tableRecordDateFieldFilterDurationLessThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
64263
+ operator: zod_default.literal("duration_less_than"),
64264
+ value: durationValueSchema.nullable()
64265
+ });
64266
+ var tableRecordDateFieldFilterSchema = zod_default.discriminatedUnion("operator", [
64267
+ tableRecordDateFieldFilterEmptySchema,
64268
+ tableRecordDateFieldFilterNotEmptySchema,
64269
+ tableRecordDateFieldFilterBeforeSchema,
64270
+ tableRecordDateFieldFilterAfterSchema,
64271
+ tableRecordDateFieldFilterOnOrBeforeSchema,
64272
+ tableRecordDateFieldFilterOnOrAfterSchema,
64273
+ tableRecordDateFieldFilterOnSchema,
64274
+ tableRecordDateFieldFilterBetweenSchema,
64275
+ tableRecordDateFieldFilterTimeOfDaySchema,
64276
+ tableRecordDateFieldFilterOverlapsSchema,
64277
+ tableRecordDateFieldFilterContainsSchema,
64278
+ tableRecordDateFieldFilterWithinSchema,
64279
+ tableRecordDateFieldFilterStartsBeforeSchema,
64280
+ tableRecordDateFieldFilterStartsAfterSchema,
64281
+ tableRecordDateFieldFilterEndsBeforeSchema,
64282
+ tableRecordDateFieldFilterEndsAfterSchema,
64283
+ tableRecordDateFieldFilterDurationEqualsSchema,
64284
+ tableRecordDateFieldFilterDurationGreaterThanSchema,
64285
+ tableRecordDateFieldFilterDurationLessThanSchema
64286
+ ]);
64287
+ var tableRecordBooleanFieldFilterSchema = zod_default.object({
64288
+ type: zod_default.literal("boolean"),
64289
+ field_key: zod_default.string(),
64290
+ operator: zod_default.enum(["equals"]),
64291
+ value: zod_default.boolean().nullable()
64292
+ });
64293
+ var tableRecordSelectFieldFilterSchema = zod_default.object({
64294
+ type: zod_default.literal("select"),
64295
+ field_key: zod_default.string(),
64296
+ operator: zod_default.enum([
64297
+ "has_any_of",
64298
+ "has_none_of",
64299
+ "is_empty",
64300
+ "is_not_empty",
64301
+ "has_all_of"
64302
+ ]),
64303
+ value: zod_default.array(zod_default.string()).nullable()
64304
+ });
64305
+ var tableRecordSelectMemberFieldFilterSchema = zod_default.object({
64306
+ type: zod_default.literal("select_member"),
64307
+ field_key: zod_default.string(),
64308
+ operator: zod_default.enum([
64309
+ "has_any_of",
64310
+ "has_none_of",
64311
+ "is_empty",
64312
+ "is_not_empty",
64313
+ "has_all_of",
64314
+ "is_current_member",
64315
+ "is_not_current_member"
64316
+ ]),
64317
+ value: zod_default.array(zod_default.string()).nullable()
64318
+ });
64319
+ var tableRecordSelectRecordLinkFieldFilterSchema = zod_default.object({
64320
+ type: zod_default.literal("select_record_link"),
64321
+ field_key: zod_default.string(),
64322
+ operator: zod_default.enum([
64323
+ // Membership operators — match linked record IDs. value: string[].
64324
+ "has_any_of",
64325
+ "has_none_of",
64326
+ "has_all_of",
64327
+ // Text operators — match the cached display text. value: string.
64328
+ "contains",
64329
+ "not_contains",
64330
+ "starts_with",
64331
+ "ends_with",
64332
+ "is_empty",
64333
+ "is_not_empty"
64334
+ ]),
64335
+ value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
64336
+ });
64337
+ var tableRecordFilesFieldFilterSchema = zod_default.object({
64338
+ type: zod_default.literal("files"),
64339
+ field_key: zod_default.string(),
64340
+ operator: zod_default.enum(["has_filename", "has_mime_type", "has_file_count", "is_empty", "is_not_empty"]),
64341
+ value: zod_default.string().nullable()
64342
+ });
64343
+ var tableRecordLockedFilterSchema = zod_default.object({
64344
+ type: zod_default.literal("locked"),
64345
+ operator: zod_default.enum(["is_locked", "is_not_locked"]),
64346
+ value: zod_default.null()
64347
+ });
64348
+ var tableRecordCurrentMemberFilterSchema = zod_default.object({
64349
+ type: zod_default.literal("current_member"),
64350
+ operator: zod_default.enum(["in_any_group"]),
64351
+ value: zod_default.array(zod_default.string())
64352
+ });
64353
+ var tableRecordRecordIdFilterSchema = zod_default.object({
64354
+ type: zod_default.literal("record_id"),
64355
+ operator: zod_default.enum(["is_any_of", "is_none_of"]),
64356
+ value: zod_default.array(zod_default.string())
64357
+ });
64358
+ var tableRecordFieldFilterConditionSchema = zod_default.union([
64359
+ tableRecordTextFieldFilterSchema,
64360
+ tableRecordNumberFieldFilterSchema,
64361
+ tableRecordDateFieldFilterSchema,
64362
+ tableRecordBooleanFieldFilterSchema,
64363
+ tableRecordSelectMemberFieldFilterSchema,
64364
+ tableRecordSelectFieldFilterSchema,
64365
+ tableRecordSelectRecordLinkFieldFilterSchema,
64366
+ tableRecordFilesFieldFilterSchema
64367
+ ]);
64368
+ var tableRecordFiltersConditionNodeSchema = zod_default.object({
64369
+ node_type: zod_default.literal("condition"),
64370
+ field_key: zod_default.string().optional(),
64371
+ type: zod_default.string().optional(),
64372
+ operator: zod_default.string(),
64373
+ value: zod_default.unknown().optional()
64374
+ });
64375
+ var tableRecordFiltersTraversalNodeSchema = zod_default.object({
64376
+ node_type: zod_default.literal("traversal"),
64377
+ path: zod_default.array(zod_default.string()),
64378
+ condition: tableRecordFiltersConditionNodeSchema
64379
+ });
64380
+ var tableRecordFiltersGroupNodeSchema = zod_default.lazy(
64381
+ () => zod_default.object({
64382
+ node_type: zod_default.literal("group"),
64383
+ logic: zod_default.enum(["and", "or"]),
64384
+ children: zod_default.array(
64385
+ zod_default.union([
64386
+ tableRecordFiltersConditionNodeSchema,
64387
+ tableRecordFiltersTraversalNodeSchema,
64388
+ tableRecordFiltersGroupNodeSchema
64389
+ ])
64390
+ )
64391
+ })
64392
+ );
64393
+ var tableRecordFiltersSchema = zod_default.union([
64394
+ tableRecordFiltersConditionNodeSchema,
64395
+ tableRecordFiltersTraversalNodeSchema,
64396
+ tableRecordFiltersGroupNodeSchema
64397
+ ]);
64398
+ var optionColorSchema = zod_default.enum([
64399
+ "red",
64400
+ "orange",
64401
+ "amber",
64402
+ "yellow",
64403
+ "lime",
64404
+ "green",
64405
+ "emerald",
64406
+ "teal",
64407
+ "cyan",
64408
+ "sky",
64409
+ "blue",
64410
+ "indigo",
64411
+ "violet",
64412
+ "purple",
64413
+ "fuchsia",
64414
+ "pink",
64415
+ "rose",
64416
+ "slate",
64417
+ "gray",
64418
+ "zinc",
64419
+ "neutral",
64420
+ "stone"
64421
+ ]);
64422
+ var tableRecordColorSchema = zod_default.object({
64423
+ filters: tableRecordFiltersGroupNodeSchema.nullable().describe(
64424
+ "The filter conditions that determine when this color rule applies. Null means no filtering."
64425
+ ),
64426
+ color: optionColorSchema.describe(
64427
+ "The color to apply to records matching the filters."
64428
+ )
64429
+ });
64430
+ var tableRecordColorsSchema = zod_default.array(tableRecordColorSchema);
64431
+ var tableRecordSortSchema = zod_default.array(
64432
+ zod_default.object({
64433
+ field_key: zod_default.string().describe("Field key to sort by"),
64434
+ order: zod_default.enum(["asc", "desc"]).nullable().describe("Sort order: 'asc' for ascending, 'desc' for descending"),
64435
+ blank_position: zod_default.enum(["top", "bottom"]).optional().describe("Blank position: 'top' for top, 'bottom' for bottom")
64436
+ })
64437
+ );
64438
+ var TEXT_OPS = tableRecordTextFieldFilterSchema.shape.operator.options;
64439
+ var NUMBER_OPS = tableRecordNumberFieldFilterSchema.shape.operator.options;
64440
+ var DATE_OPS = tableRecordDateFieldFilterSchema.options.map((s) => s.shape.operator.value);
64441
+ var BOOLEAN_OPS = tableRecordBooleanFieldFilterSchema.shape.operator.options;
64442
+ var SELECT_OPS = tableRecordSelectFieldFilterSchema.shape.operator.options;
64443
+ var SELECT_MEMBER_OPS = tableRecordSelectMemberFieldFilterSchema.shape.operator.options;
64444
+ var SELECT_RECORD_LINK_OPS = tableRecordSelectRecordLinkFieldFilterSchema.shape.operator.options;
64445
+ var FILES_OPS = tableRecordFilesFieldFilterSchema.shape.operator.options;
64446
+ var LOCKED_OPS = tableRecordLockedFilterSchema.shape.operator.options;
64447
+ var CURRENT_MEMBER_OPS = tableRecordCurrentMemberFilterSchema.shape.operator.options;
64448
+ var RECORD_ID_OPS = tableRecordRecordIdFilterSchema.shape.operator.options;
64449
+ var VALID_OPERATORS = {
64450
+ text: TEXT_OPS,
64451
+ number: NUMBER_OPS,
64452
+ date: DATE_OPS,
64453
+ boolean: BOOLEAN_OPS,
64454
+ select: SELECT_OPS,
64455
+ select_member: SELECT_MEMBER_OPS,
64456
+ select_record_link: SELECT_RECORD_LINK_OPS,
64457
+ files: FILES_OPS,
64458
+ locked: LOCKED_OPS,
64459
+ current_member: CURRENT_MEMBER_OPS,
64460
+ record_id: RECORD_ID_OPS
64461
+ };
64462
+ var VALID_FILTER_TYPES = Object.keys(VALID_OPERATORS);
64463
+
64464
64464
  // ../shared/src/chat_models.ts
64465
- var CHAT_MODEL_IDS = ["claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5"];
64466
- var LEGACY_CHAT_MODEL_IDS = [];
64467
- var ACCEPTED_CHAT_MODEL_IDS = [...CHAT_MODEL_IDS, ...LEGACY_CHAT_MODEL_IDS];
64468
- var UTILITY_MODEL_ID = "claude-haiku-4-5";
64469
- var PICKER_MODEL_IDS = CHAT_MODEL_IDS.filter(
64470
- (id) => id !== UTILITY_MODEL_ID
64465
+ var MODEL_TIERS = ["haiku", "sonnet", "opus"];
64466
+ var TIER_MODELS = {
64467
+ haiku: "claude-haiku-4-5",
64468
+ sonnet: "claude-sonnet-5",
64469
+ opus: "claude-opus-5"
64470
+ };
64471
+ var RESOLVED_MODEL_IDS = MODEL_TIERS.map(
64472
+ (tier) => TIER_MODELS[tier]
64473
+ );
64474
+ function tierForModelId(modelId) {
64475
+ for (const tier of MODEL_TIERS) {
64476
+ if (modelId.startsWith(`claude-${tier}-`)) return tier;
64477
+ }
64478
+ return null;
64479
+ }
64480
+ var DEFAULT_MODEL_TIER = "sonnet";
64481
+ var UTILITY_MODEL_TIER = "haiku";
64482
+ var DEFAULT_MODEL_ID = TIER_MODELS[DEFAULT_MODEL_TIER];
64483
+ var PICKER_MODEL_TIERS = MODEL_TIERS.filter(
64484
+ (tier) => tier !== UTILITY_MODEL_TIER
64471
64485
  );
64472
64486
  var EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
64473
64487
 
@@ -64927,11 +64941,20 @@ var appAgentDeclarationSchema = zod_default.object({
64927
64941
  workflow_aliases: zod_default.array(zod_default.string().min(1)).optional().describe(
64928
64942
  "Workflows from this app's manifest the agent may invoke via `run_app_workflow`, validated at declare time against the app's own workflows. This is the agent's ENTIRE write surface \u2014 the same declared mutation path the app's UI uses, so table hooks and side-effect harvesting apply. Omit for a read-only agent."
64929
64943
  ),
64930
- model_id: zod_default.string().min(1).optional().describe(
64931
- "Chat model id the agent runs on, validated against ACCEPTED_CHAT_MODEL_IDS. Omit to follow the platform default chat model, resolved at run time \u2014 the preferred choice: the agent tracks model generations with no per-app rewrite. Pin only a deliberate, tested choice."
64944
+ model_tier: zod_default.enum(MODEL_TIERS).optional().describe(
64945
+ "Model tier the agent runs on \u2014 `haiku`, `sonnet`, or `opus`. Omit to follow the platform default tier, resolved at run time: the preferred choice. A tier names capability, not a version, so the generation behind it moves with the platform and this declaration never needs a rewrite. Pin only a deliberate, tested choice."
64932
64946
  ),
64947
+ /**
64948
+ * LEGACY, read-only. A version pin written by a release from before tiers.
64949
+ * Parsed so a declaration an older release wrote during the rollout window
64950
+ * still resolves (via `tierForModelId`) instead of reading as unpinned
64951
+ * and silently dropping to the default. Never written by this release, and
64952
+ * rejected on the write surface. Deleted with the strip migration, once no
64953
+ * deployed release writes it.
64954
+ */
64955
+ model_id: zod_default.string().min(1).optional(),
64933
64956
  effort_level: zod_default.enum(EFFORT_LEVELS).optional().describe(
64934
- "Reasoning depth for adaptive-thinking models \u2014 one of the chosen model's supported levels (validated against model_id at declare time). Omit to use the model default; ignored on models without adaptive thinking."
64957
+ "Reasoning depth for adaptive-thinking tiers \u2014 one of the chosen tier's supported levels (validated against model_tier at declare time). Omit to use the model default; ignored on tiers without adaptive thinking."
64935
64958
  ),
64936
64959
  inputs: zod_default.record(zod_default.string(), appWorkflowInputSchema).optional().describe(
64937
64960
  "Typed input schema for one run. Keys are input names; values declare type + constraints. The server validates the run payload against this before invoking; CLI codegen emits a typed `useAgentRun<alias>` signature. Omit for an untyped payload."
@@ -65070,6 +65093,8 @@ var agentStepSchema = stepBaseSchema.extend({
65070
65093
  instructions: zod_default.string().min(1),
65071
65094
  input: zod_default.record(zod_default.string(), toolInputValueSchema),
65072
65095
  tool_names: zod_default.array(zod_default.string().min(1)),
65096
+ model_tier: zod_default.enum(MODEL_TIERS).optional(),
65097
+ /** LEGACY, read-only — see `appAgentDeclarationSchema.model_id`. */
65073
65098
  model_id: zod_default.string().min(1).optional(),
65074
65099
  output: agentOutputSpecSchema
65075
65100
  });
@@ -69683,8 +69708,6 @@ function walkAgentInvocation(call, scope, stepId, description) {
69683
69708
  const toolsNode = kw.get("tools");
69684
69709
  if (!toolsNode) fail(arg, "agent requires `tools` (use [] for none).");
69685
69710
  const tool_names = readStaticStringArray(toolsNode, "agent `tools`");
69686
- const modelNode = kw.get("model");
69687
- const model_id = modelNode ? readStaticString(modelNode, "agent `model`") : void 0;
69688
69711
  const outputNode = kw.get("output");
69689
69712
  if (!outputNode) fail(arg, "agent requires `output`.");
69690
69713
  const outputResult = agentOutputSpecSchema.safeParse(walkStaticJsonLiteral(outputNode));
@@ -69692,6 +69715,19 @@ function walkAgentInvocation(call, scope, stepId, description) {
69692
69715
  const detail = outputResult.error.issues.map((i2) => `${i2.path.join(".") || "<root>"}: ${i2.message}`).join("; ");
69693
69716
  fail(outputNode, `Invalid agent \`output\`: ${detail}`);
69694
69717
  }
69718
+ const modelNode = kw.get("model");
69719
+ let model_tier;
69720
+ if (modelNode) {
69721
+ const literal2 = readStaticString(modelNode, "agent `model`");
69722
+ const tier = MODEL_TIERS.includes(literal2) ? literal2 : tierForModelId(literal2);
69723
+ if (!tier) {
69724
+ fail(
69725
+ modelNode,
69726
+ `Unknown agent \`model\` "${literal2}" \u2014 expected one of: ${MODEL_TIERS.join(", ")}.`
69727
+ );
69728
+ }
69729
+ model_tier = tier;
69730
+ }
69695
69731
  return {
69696
69732
  id: stepId,
69697
69733
  description: description ?? "agent",
@@ -69699,7 +69735,7 @@ function walkAgentInvocation(call, scope, stepId, description) {
69699
69735
  instructions,
69700
69736
  input,
69701
69737
  tool_names,
69702
- ...model_id !== void 0 ? { model_id } : {},
69738
+ ...model_tier !== void 0 ? { model_tier } : {},
69703
69739
  output: outputResult.data
69704
69740
  };
69705
69741
  }
@@ -77943,6 +77979,59 @@ function hueToRgb(p, q, t) {
77943
77979
  return p;
77944
77980
  }
77945
77981
 
77982
+ // ../xlsx/src/excel_utils.ts
77983
+ function colLettersToNum(letters) {
77984
+ let result = 0;
77985
+ for (let i2 = 0; i2 < letters.length; i2++) {
77986
+ result = result * 26 + (letters.charCodeAt(i2) - 64);
77987
+ }
77988
+ return result;
77989
+ }
77990
+ function colNumToLetters(col) {
77991
+ let result = "";
77992
+ let n = col;
77993
+ while (n > 0) {
77994
+ n--;
77995
+ result = String.fromCharCode(65 + n % 26) + result;
77996
+ n = Math.floor(n / 26);
77997
+ }
77998
+ return result;
77999
+ }
78000
+ function refToRowCol(ref2) {
78001
+ const match2 = ref2.match(/^(\$?)([A-Z]+)(\$?)(\d+)$/);
78002
+ if (!match2) return void 0;
78003
+ return { col: colLettersToNum(match2[2]), row: parseInt(match2[4], 10) };
78004
+ }
78005
+ function rowColToRef(row, col) {
78006
+ return colNumToLetters(col) + String(row);
78007
+ }
78008
+ function escapeXml(s) {
78009
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
78010
+ }
78011
+ var PACK_COL_BITS = 14;
78012
+ var PACK_COL_MULT = 1 << PACK_COL_BITS;
78013
+ function packRowCol(row, col) {
78014
+ return row * PACK_COL_MULT + col;
78015
+ }
78016
+ function unpackRowCol(packed) {
78017
+ const row = Math.floor(packed / PACK_COL_MULT);
78018
+ const col = packed - row * PACK_COL_MULT;
78019
+ return { row, col };
78020
+ }
78021
+ function packRef(ref2) {
78022
+ const rc = refToRowCol(ref2);
78023
+ if (!rc) return -1;
78024
+ return packRowCol(rc.row, rc.col);
78025
+ }
78026
+ function unpackRef(packed) {
78027
+ const { row, col } = unpackRowCol(packed);
78028
+ return rowColToRef(row, col);
78029
+ }
78030
+ function stripNsPrefix(tag) {
78031
+ const colon = tag.indexOf(":");
78032
+ return colon === -1 ? tag : tag.slice(colon + 1);
78033
+ }
78034
+
77946
78035
  // ../xlsx/src/excel_pattern_fills.ts
77947
78036
  var PATTERNS = {
77948
78037
  darkVertical: (fg, bg) => `repeating-linear-gradient(90deg, ${fg} 0px, ${fg} 1px, ${bg} 1px, ${bg} 4px)`,
@@ -78010,6 +78099,10 @@ var BUILTIN_NUM_FMTS = {
78010
78099
  var xmlParser2 = new XMLParser({
78011
78100
  ignoreAttributes: false,
78012
78101
  attributeNamePrefix: "@_",
78102
+ // A producer may bind spreadsheetml to a prefix (`<x:styleSheet>`) rather than
78103
+ // making it the default namespace; the prefix carries no meaning, so it is
78104
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
78105
+ transformTagName: stripNsPrefix,
78013
78106
  processEntities: false,
78014
78107
  isArray: (tagName) => tagName === "numFmt" || tagName === "font" || tagName === "fill" || tagName === "border" || tagName === "xf" || tagName === "rgbColor" || tagName === "stop"
78015
78108
  });
@@ -78339,10 +78432,24 @@ function emptyStyleResolver() {
78339
78432
  };
78340
78433
  }
78341
78434
 
78435
+ // ../xlsx/src/malformed_part_error.ts
78436
+ var MalformedPartError = class extends Error {
78437
+ constructor(reason) {
78438
+ super(
78439
+ `${reason} \u2014 the file is not a readable spreadsheet. If it opens in Excel, the reader is at fault: report the producer that wrote it.`
78440
+ );
78441
+ this.name = "MalformedPartError";
78442
+ }
78443
+ };
78444
+
78342
78445
  // ../xlsx/src/ooxml_workbook.ts
78343
78446
  var xmlParser3 = new XMLParser({
78344
78447
  ignoreAttributes: false,
78345
78448
  attributeNamePrefix: "@_",
78449
+ // A producer may bind spreadsheetml to a prefix (`<x:workbook>`) rather than
78450
+ // making it the default namespace; the prefix carries no meaning, so it is
78451
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
78452
+ transformTagName: stripNsPrefix,
78346
78453
  // Shared-string and workbook text is textual BY DEFINITION (tax IDs, phone
78347
78454
  // numbers, account codes, sheet/defined names). fast-xml-parser's default tag
78348
78455
  // coercion would parse `<t>0312345678</t>` as the number 312345678 — silently
@@ -78356,7 +78463,7 @@ var xmlParser3 = new XMLParser({
78356
78463
  function parseWorkbook(workbookXml) {
78357
78464
  const doc = xmlParser3.parse(workbookXml);
78358
78465
  const wb = doc?.["workbook"];
78359
- if (!wb) return { sheets: [], activeSheetIndex: 0, date1904: false, namedRanges: /* @__PURE__ */ new Map(), printTitlesBySheet: /* @__PURE__ */ new Map(), fullCalcOnLoad: false };
78466
+ if (!wb) throw new MalformedPartError("xl/workbook.xml has no <workbook> root");
78360
78467
  const sheetsEl = wb["sheets"];
78361
78468
  const sheetArr = sheetsEl?.["sheet"];
78362
78469
  const sheets = (sheetArr ?? []).map((s) => ({
@@ -79414,55 +79521,6 @@ function buildCellContent(displayValue, sharedString, hyperlink) {
79414
79521
  return { type: "plain", text: displayValue };
79415
79522
  }
79416
79523
 
79417
- // ../xlsx/src/excel_utils.ts
79418
- function colLettersToNum(letters) {
79419
- let result = 0;
79420
- for (let i2 = 0; i2 < letters.length; i2++) {
79421
- result = result * 26 + (letters.charCodeAt(i2) - 64);
79422
- }
79423
- return result;
79424
- }
79425
- function colNumToLetters(col) {
79426
- let result = "";
79427
- let n = col;
79428
- while (n > 0) {
79429
- n--;
79430
- result = String.fromCharCode(65 + n % 26) + result;
79431
- n = Math.floor(n / 26);
79432
- }
79433
- return result;
79434
- }
79435
- function refToRowCol(ref2) {
79436
- const match2 = ref2.match(/^(\$?)([A-Z]+)(\$?)(\d+)$/);
79437
- if (!match2) return void 0;
79438
- return { col: colLettersToNum(match2[2]), row: parseInt(match2[4], 10) };
79439
- }
79440
- function rowColToRef(row, col) {
79441
- return colNumToLetters(col) + String(row);
79442
- }
79443
- function escapeXml(s) {
79444
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
79445
- }
79446
- var PACK_COL_BITS = 14;
79447
- var PACK_COL_MULT = 1 << PACK_COL_BITS;
79448
- function packRowCol(row, col) {
79449
- return row * PACK_COL_MULT + col;
79450
- }
79451
- function unpackRowCol(packed) {
79452
- const row = Math.floor(packed / PACK_COL_MULT);
79453
- const col = packed - row * PACK_COL_MULT;
79454
- return { row, col };
79455
- }
79456
- function packRef(ref2) {
79457
- const rc = refToRowCol(ref2);
79458
- if (!rc) return -1;
79459
- return packRowCol(rc.row, rc.col);
79460
- }
79461
- function unpackRef(packed) {
79462
- const { row, col } = unpackRowCol(packed);
79463
- return rowColToRef(row, col);
79464
- }
79465
-
79466
79524
  // ../xlsx/src/ooxml_sheet.ts
79467
79525
  var MAX_ROWS_PER_SHEET = 1e4;
79468
79526
  var MAX_IMAGES = 50;
@@ -79478,7 +79536,11 @@ var xmlParser4 = new XMLParser({
79478
79536
  ignoreAttributes: false,
79479
79537
  attributeNamePrefix: "@_",
79480
79538
  processEntities: false,
79481
- isArray: (tagName) => tagName === "row" || tagName === "c" || tagName === "col" || tagName === "mergeCell" || tagName === "conditionalFormatting" || tagName === "cfRule" || tagName === "cfvo" || tagName === "color" || tagName === "hyperlink" || tagName === "Relationship" || tagName === "sheetView" || tagName === "xdr:twoCellAnchor" || tagName === "xdr:oneCellAnchor" || tagName === "dataValidation" || tagName === "filterColumn" || tagName === "filter" || tagName === "brk" || tagName === "ext",
79539
+ // A producer may bind spreadsheetml to a prefix (`<x:worksheet>`) instead of
79540
+ // making it the default namespace. The prefix carries no meaning, so it is
79541
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
79542
+ transformTagName: stripNsPrefix,
79543
+ isArray: (tagName) => tagName === "row" || tagName === "c" || tagName === "col" || tagName === "mergeCell" || tagName === "conditionalFormatting" || tagName === "cfRule" || tagName === "cfvo" || tagName === "color" || tagName === "hyperlink" || tagName === "Relationship" || tagName === "sheetView" || tagName === "dataValidation" || tagName === "filterColumn" || tagName === "filter" || tagName === "brk" || tagName === "ext",
79482
79544
  // Preserve whitespace in cell values
79483
79545
  trimValues: false
79484
79546
  });
@@ -79497,7 +79559,7 @@ var drawingParser = new XMLParser({
79497
79559
  function parseSheet(sheetXml, sheetRelsXml, styles, sharedStrings, theme, indexedColors, zipEntries, date1904, maxRows = MAX_ROWS_PER_SHEET) {
79498
79560
  const doc = xmlParser4.parse(sheetXml);
79499
79561
  const worksheet = doc?.["worksheet"];
79500
- if (!worksheet) return emptySheet("Sheet");
79562
+ if (!worksheet) throw new MalformedPartError("A worksheet part has no <worksheet> root");
79501
79563
  const rels = sheetRelsXml ? parseSheetRels(sheetRelsXml) : /* @__PURE__ */ new Map();
79502
79564
  const sheetFormatPr = worksheet["sheetFormatPr"];
79503
79565
  const defaultRowHeight = sheetFormatPr?.["@_defaultRowHeight"] ? parseFloat(sheetFormatPr["@_defaultRowHeight"]) : 15;
@@ -81747,9 +81809,7 @@ function parseExcelFromZip(zip, options) {
81747
81809
  const stylesEntry = findEntry(zip, "xl/styles.xml");
81748
81810
  const styles = stylesEntry ? parseStyles(decodeUtf8(stylesEntry), theme) : emptyStyleResolver();
81749
81811
  const wbEntry = findEntry(zip, "xl/workbook.xml");
81750
- if (!wbEntry) {
81751
- return { sheets: [emptySheet("Sheet1")], activeSheetIndex: 0 };
81752
- }
81812
+ if (!wbEntry) throw new MalformedPartError("The package has no xl/workbook.xml");
81753
81813
  const workbookInfo = parseWorkbook(decodeUtf8(wbEntry));
81754
81814
  const wbRelsEntry = findEntry(zip, "xl/_rels/workbook.xml.rels");
81755
81815
  const wbRels = wbRelsEntry ? parseWorkbookRels(decodeUtf8(wbRelsEntry)) : /* @__PURE__ */ new Map();
@@ -81763,22 +81823,20 @@ function parseExcelFromZip(zip, options) {
81763
81823
  });
81764
81824
  const parseXmlDoc = (xml) => xmlParser5.parse(xml);
81765
81825
  const pivotCaches = /* @__PURE__ */ new Map();
81766
- if (wbEntry) {
81767
- const wbDoc = parseXmlDoc(decodeUtf8(wbEntry));
81768
- const wbCacheMap = extractWorkbookPivotCaches(wbDoc);
81769
- for (const [cacheId, rId] of wbCacheMap) {
81770
- const cacheTarget = wbRels.get(rId);
81771
- if (!cacheTarget) continue;
81772
- const cachePath = cacheTarget.startsWith("/") ? cacheTarget.slice(1) : `xl/${cacheTarget}`;
81773
- const cacheEntry = findEntry(zip, cachePath);
81774
- if (!cacheEntry) continue;
81775
- try {
81776
- pivotCaches.set(
81777
- cacheId,
81778
- parsePivotCacheDefinitionXml(decodeUtf8(cacheEntry), cacheId, parseXmlDoc)
81779
- );
81780
- } catch {
81781
- }
81826
+ const wbDoc = parseXmlDoc(decodeUtf8(wbEntry));
81827
+ const wbCacheMap = extractWorkbookPivotCaches(wbDoc);
81828
+ for (const [cacheId, rId] of wbCacheMap) {
81829
+ const cacheTarget = wbRels.get(rId);
81830
+ if (!cacheTarget) continue;
81831
+ const cachePath = cacheTarget.startsWith("/") ? cacheTarget.slice(1) : `xl/${cacheTarget}`;
81832
+ const cacheEntry = findEntry(zip, cachePath);
81833
+ if (!cacheEntry) continue;
81834
+ try {
81835
+ pivotCaches.set(
81836
+ cacheId,
81837
+ parsePivotCacheDefinitionXml(decodeUtf8(cacheEntry), cacheId, parseXmlDoc)
81838
+ );
81839
+ } catch {
81782
81840
  }
81783
81841
  }
81784
81842
  const sheets = [];
@@ -81902,6 +81960,11 @@ function parseExcelFromZip(zip, options) {
81902
81960
  }
81903
81961
  visibleIndex++;
81904
81962
  }
81963
+ if (sheets.length === 0 && workbookInfo.sheets.length > 0) {
81964
+ throw new MalformedPartError(
81965
+ `xl/workbook.xml declares ${workbookInfo.sheets.length} sheet(s) and none of their parts could be resolved`
81966
+ );
81967
+ }
81905
81968
  if (sheets.length === 0) {
81906
81969
  return { sheets: [emptySheet("Sheet1")], activeSheetIndex: 0 };
81907
81970
  }
@@ -83136,6 +83199,8 @@ function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMa
83136
83199
  }
83137
83200
  arr.push({ col: rc.col, cell });
83138
83201
  }
83202
+ for (const rowNum of sheet.rowHeights.keys()) if (!rowMap.has(rowNum)) rowMap.set(rowNum, []);
83203
+ for (const rowNum of sheet.hiddenRows) if (!rowMap.has(rowNum)) rowMap.set(rowNum, []);
83139
83204
  const sortedRows = Array.from(rowMap.keys()).sort((a, b) => a - b);
83140
83205
  for (const rowNum of sortedRows) {
83141
83206
  const cells = rowMap.get(rowNum);
@@ -83292,11 +83357,12 @@ function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMa
83292
83357
  }
83293
83358
  }
83294
83359
  let dimensionRef = "A1";
83295
- if (sortedRows.length > 0) {
83360
+ const cellRows = sortedRows.filter((rowNum) => rowMap.get(rowNum).length > 0);
83361
+ if (cellRows.length > 0) {
83296
83362
  let minCol = Infinity, maxCol = 0;
83297
- const minRow = sortedRows[0];
83298
- const maxRow = sortedRows[sortedRows.length - 1];
83299
- for (const rowNum of sortedRows) {
83363
+ const minRow = cellRows[0];
83364
+ const maxRow = cellRows[cellRows.length - 1];
83365
+ for (const rowNum of cellRows) {
83300
83366
  const cells = rowMap.get(rowNum);
83301
83367
  for (const { col } of cells) {
83302
83368
  if (col < minCol) minCol = col;
@@ -92892,6 +92958,9 @@ function adjustMergedCellsForColDelete(sheet, atCol, count) {
92892
92958
 
92893
92959
  // src/xlsx.ts
92894
92960
  var SIMPLE_CELL_KEYS = /* @__PURE__ */ new Set(["value", "formula", "numFmt", "style"]);
92961
+ var SIMPLE_SHEET_KEYS = /* @__PURE__ */ new Set(["name", "cells", "merges", "freeze", "colWidths", "rowHeights"]);
92962
+ var MAX_COLUMN = 16384;
92963
+ var MAX_ROW = 1048576;
92895
92964
  function loadFile(filePath) {
92896
92965
  if (!fs6.existsSync(filePath)) fail2(`File not found: ${filePath}`);
92897
92966
  const buffer = fs6.readFileSync(filePath);
@@ -92943,7 +93012,7 @@ function lazyEngine(workbook) {
92943
93012
  }
92944
93013
  };
92945
93014
  }
92946
- function readToJson(filePath, filter3) {
93015
+ function readToJson(filePath, filter3, opts) {
92947
93016
  const buffer = fs6.readFileSync(filePath);
92948
93017
  const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
92949
93018
  const parsed = parseExcelBuffer(arrayBuffer);
@@ -92962,13 +93031,13 @@ function readToJson(filePath, filter3) {
92962
93031
  name: s.name,
92963
93032
  totalRowCount: s.totalRowCount,
92964
93033
  truncated: s.truncated,
92965
- cells: cellsFromParsedRows(s.rows, filter3?.range),
93034
+ cells: cellsFromParsedRows(s.rows, filter3?.range, opts?.withFormat === true),
92966
93035
  merges: s.mergedCells.map((m) => `${rowColToRef(m.startRow, m.startCol)}:${rowColToRef(m.endRow, m.endCol)}`),
92967
93036
  freeze: s.freezePane ? { row: s.freezePane.frozenRows, col: s.freezePane.frozenCols } : void 0
92968
93037
  }))
92969
93038
  };
92970
93039
  }
92971
- function cellsFromParsedRows(rows, range2) {
93040
+ function cellsFromParsedRows(rows, range2, withFormat = false) {
92972
93041
  const out = {};
92973
93042
  for (const row of rows) {
92974
93043
  if (range2 && (row.index < range2.startRow || row.index > range2.endRow)) continue;
@@ -92978,6 +93047,8 @@ function cellsFromParsedRows(rows, range2) {
92978
93047
  const value2 = cell.typedValue ?? cell.value;
92979
93048
  const entry = { value: value2 };
92980
93049
  if (cell.formula) entry.formula = cell.formula;
93050
+ if (cell.numFmtCode && cell.numFmtCode !== "General") entry.numFmt = cell.numFmtCode;
93051
+ if (withFormat && cell.style && Object.keys(cell.style).length > 0) entry.style = cell.style;
92981
93052
  out[ref2] = entry;
92982
93053
  }
92983
93054
  }
@@ -92998,6 +93069,10 @@ function buildWorkbookFromJson(input) {
92998
93069
  }
92999
93070
  function validateSimpleSheet(s, index) {
93000
93071
  if (!s || typeof s !== "object") fail2(`sheets[${index}] must be an object`);
93072
+ const unknown2 = Object.keys(s).filter((k) => !SIMPLE_SHEET_KEYS.has(k));
93073
+ if (unknown2.length > 0) {
93074
+ fail2(`sheets[${index}] has unknown propert${unknown2.length > 1 ? "ies" : "y"}: ${unknown2.join(", ")}. Supported: ${[...SIMPLE_SHEET_KEYS].join(", ")}.`);
93075
+ }
93001
93076
  if (typeof s.name !== "string" || s.name === "") fail2(`sheets[${index}].name must be a non-empty string`);
93002
93077
  if (s.cells !== void 0 && (typeof s.cells !== "object" || s.cells === null || Array.isArray(s.cells))) {
93003
93078
  fail2(`sheets[${index}].cells must be an object keyed by cell ref (e.g. {"A1": "value"})`);
@@ -93011,6 +93086,23 @@ function validateSimpleSheet(s, index) {
93011
93086
  fail2(`sheets[${index}].freeze.row and .col must be numbers`);
93012
93087
  }
93013
93088
  }
93089
+ validateDimensionMap(s.colWidths, `sheets[${index}].colWidths`, "column letter within A..XFD", (k) => {
93090
+ const coord = /^[A-Za-z]+$/.test(k) ? refToRowCol(`${k.toUpperCase()}1`) : void 0;
93091
+ return coord !== void 0 && coord.col <= MAX_COLUMN;
93092
+ });
93093
+ validateDimensionMap(s.rowHeights, `sheets[${index}].rowHeights`, `row number within 1..${MAX_ROW}`, (k) => /^[0-9]+$/.test(k) && Number(k) >= 1 && Number(k) <= MAX_ROW);
93094
+ }
93095
+ function validateDimensionMap(map3, label, keyHint, keyOk) {
93096
+ if (map3 === void 0) return;
93097
+ if (typeof map3 !== "object" || map3 === null || Array.isArray(map3)) {
93098
+ fail2(`${label} must be an object keyed by ${keyHint}`);
93099
+ }
93100
+ for (const [key, value2] of Object.entries(map3)) {
93101
+ if (!keyOk(key)) fail2(`${label} key "${key}" must be a ${keyHint}`);
93102
+ if (typeof value2 !== "number" || !Number.isFinite(value2) || value2 <= 0) {
93103
+ fail2(`${label}["${key}"] must be a positive number`);
93104
+ }
93105
+ }
93014
93106
  }
93015
93107
  function applySheetCells(workbook, sheetIndex, def) {
93016
93108
  const sheet = workbook.sheets[sheetIndex];
@@ -93043,6 +93135,20 @@ function applySheetCells(workbook, sheetIndex, def) {
93043
93135
  if (def.freeze) {
93044
93136
  sheet.freeze = { row: def.freeze.row, col: def.freeze.col };
93045
93137
  }
93138
+ if (def.colWidths) {
93139
+ for (const [letter, width] of Object.entries(def.colWidths)) {
93140
+ const coord = refToRowCol(`${letter.toUpperCase()}1`);
93141
+ if (!coord) fail2(`Invalid column in sheet "${def.name}".colWidths: ${letter}`);
93142
+ sheet.colWidths.set(coord.col, width);
93143
+ }
93144
+ }
93145
+ if (def.rowHeights) {
93146
+ for (const [rowKey, height] of Object.entries(def.rowHeights)) {
93147
+ const row = Number(rowKey);
93148
+ if (!Number.isInteger(row) || row < 1) fail2(`Invalid row in sheet "${def.name}".rowHeights: ${rowKey}`);
93149
+ sheet.rowHeights.set(row, height);
93150
+ }
93151
+ }
93046
93152
  }
93047
93153
  function normalizeSimpleCell(raw, sheetName, ref2) {
93048
93154
  if (raw && typeof raw === "object" && !Array.isArray(raw)) {
@@ -93073,9 +93179,10 @@ function splitOptionalSheetRef(spec) {
93073
93179
  return { sheet: spec.slice(0, idx), ref: spec.slice(idx + 1) };
93074
93180
  }
93075
93181
  function xlsxRead(filePath, rest2) {
93076
- if (!filePath) fail2("Usage: lotics xlsx read <file> [--sheet <name>] [--range <sheet>!<A1:G60>]");
93182
+ if (!filePath) fail2("Usage: lotics xlsx read <file> [--sheet <name>] [--range <sheet>!<A1:G60>] [--with-format]");
93077
93183
  const rangeArg = readOptionFlag(rest2, "--range");
93078
93184
  const sheetArg = readOptionFlag(rest2, "--sheet");
93185
+ const withFormat = rest2.includes("--with-format");
93079
93186
  let filter3;
93080
93187
  if (rangeArg !== void 0) {
93081
93188
  const { sheet, ref: ref2 } = splitOptionalSheetRef(rangeArg);
@@ -93087,7 +93194,7 @@ function xlsxRead(filePath, rest2) {
93087
93194
  } else if (sheetArg !== void 0) {
93088
93195
  filter3 = { sheet: sheetArg };
93089
93196
  }
93090
- const data2 = readToJson(filePath, filter3);
93197
+ const data2 = readToJson(filePath, filter3, { withFormat });
93091
93198
  console.log(JSON.stringify(data2, null, 2));
93092
93199
  }
93093
93200
  function xlsxWrite(filePath, json2) {
@@ -93324,14 +93431,17 @@ function printXlsxHelp() {
93324
93431
  console.error(`Lotics xlsx commands \u2014 manipulate .xlsx files in place.
93325
93432
  Uses Lotics' own xlsx engine; round-trips faithfully with the Lotics editor and templates.
93326
93433
 
93327
- lotics xlsx read <file> [--sheet <name>] [--range <sheet>!<A1:G60>]
93434
+ lotics xlsx read <file> [--sheet <name>] [--range <sheet>!<A1:G60>] [--with-format]
93328
93435
  Dump file as JSON (sheets, cells, merges, freeze).
93329
93436
  --sheet limits to one sheet; --range to a cell window
93330
93437
  (its <sheet>! prefix is optional when --sheet is given)
93438
+ A cell carries numFmt when it has one; --with-format
93439
+ adds the resolved style (always present, hence a flag)
93331
93440
  lotics xlsx write <file> '<json>' Create .xlsx from {"sheets":[{"name","cells":{"A1":...}}]}
93332
93441
  A cell is a bare value, or {value|formula, numFmt, style}:
93333
93442
  {"A1":{"value":1234,"numFmt":"#,##0 \\"\u20AB\\"","style":{"fontBold":true}}}
93334
- Unknown cell properties are rejected, not ignored.
93443
+ A sheet also takes merges, freeze, colWidths ({"A":34}),
93444
+ rowHeights ({"1":44}). Unknown properties are rejected.
93335
93445
  lotics xlsx set-cell <file> <sheet>!<ref> '<v>' Set cell value (prefix '=' for formula)
93336
93446
  lotics xlsx clear-range <file> <sheet>!<range> Clear all cells in a range
93337
93447
  lotics xlsx merge <file> <sheet>!<range> Merge a range into one cell
@@ -95325,7 +95435,7 @@ function parseLegacyDoc(bytes) {
95325
95435
  }
95326
95436
 
95327
95437
  // ../ooxml/src/document.ts
95328
- var import_jszip = __toESM(require_lib4(), 1);
95438
+ var import_jszip2 = __toESM(require_lib4(), 1);
95329
95439
 
95330
95440
  // ../ooxml/node_modules/fast-xml-parser/src/util.js
95331
95441
  var nameStartChar2 = ":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
@@ -98004,6 +98114,14 @@ async function docModelToDocx(model) {
98004
98114
  return doc;
98005
98115
  }
98006
98116
 
98117
+ // ../ooxml/src/opc.ts
98118
+ var import_jszip = __toESM(require_lib4(), 1);
98119
+ function dropFolderEntries(zip) {
98120
+ for (const [path8, entry] of Object.entries(zip.files)) {
98121
+ if (entry.dir) delete zip.files[path8];
98122
+ }
98123
+ }
98124
+
98007
98125
  // ../ooxml/src/document.ts
98008
98126
  var DOCUMENT_ATTRS = {
98009
98127
  "@_xmlns:wpc": "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas",
@@ -98013,6 +98131,10 @@ var DOCUMENT_ATTRS = {
98013
98131
  "@_xmlns:m": "http://schemas.openxmlformats.org/officeDocument/2006/math",
98014
98132
  "@_xmlns:v": "urn:schemas-microsoft-com:vml",
98015
98133
  "@_xmlns:wp": "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
98134
+ // Declared because mc:Ignorable below names it. Markup Compatibility (ECMA-376 Part 3) requires
98135
+ // every prefix listed there to be a declared namespace prefix; an undeclared one made Word
98136
+ // report unreadable content and offer to repair EVERY document this package wrote.
98137
+ "@_xmlns:wp14": "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
98016
98138
  "@_xmlns:w10": "urn:schemas-microsoft-com:office:word",
98017
98139
  "@_xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
98018
98140
  "@_xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml",
@@ -98108,7 +98230,7 @@ async function loadDocxFromBuffer(buffer) {
98108
98230
  if (isLegacyDoc(buffer)) {
98109
98231
  return docxFromLegacyDoc(buffer);
98110
98232
  }
98111
- const zip = await import_jszip.default.loadAsync(buffer);
98233
+ const zip = await import_jszip2.default.loadAsync(buffer);
98112
98234
  const docFile = zip.file("word/document.xml");
98113
98235
  if (!docFile) {
98114
98236
  throw new Error("Invalid .docx: missing word/document.xml");
@@ -98133,19 +98255,38 @@ async function loadDocxFromBuffer(buffer) {
98133
98255
  const bodyElements = getChildren(bodyEl);
98134
98256
  return { zip, bodyElements, documentAttrs };
98135
98257
  }
98258
+ function withTrailingParagraph(body) {
98259
+ const sectPrAt = body.findIndex((e) => getTagName(e) === "w:sectPr");
98260
+ const lastBlock = sectPrAt >= 0 ? sectPrAt - 1 : body.length - 1;
98261
+ if (lastBlock < 0 || getTagName(body[lastBlock]) !== "w:tbl") return body;
98262
+ const out = [...body];
98263
+ out.splice(lastBlock + 1, 0, { "w:p": [] });
98264
+ return out;
98265
+ }
98266
+ function pruneIgnorable(attrs) {
98267
+ const listed = (attrs["@_mc:Ignorable"] ?? "").split(/\s+/).filter(Boolean);
98268
+ if (listed.length === 0) return attrs;
98269
+ const kept = listed.filter((prefix) => `@_xmlns:${prefix}` in attrs);
98270
+ if (kept.length === listed.length) return attrs;
98271
+ const next = { ...attrs };
98272
+ if (kept.length === 0) delete next["@_mc:Ignorable"];
98273
+ else next["@_mc:Ignorable"] = kept.join(" ");
98274
+ return next;
98275
+ }
98136
98276
  async function saveDocxToBuffer(doc) {
98137
- const bodyChildren = [...doc.bodyElements];
98277
+ const bodyChildren = withTrailingParagraph(doc.bodyElements);
98138
98278
  const documentEl = {
98139
98279
  "w:document": [{ "w:body": bodyChildren }],
98140
- ":@": { ...doc.documentAttrs }
98280
+ ":@": pruneIgnorable(doc.documentAttrs)
98141
98281
  };
98142
98282
  const xml = buildXml([documentEl]);
98143
98283
  doc.zip.file("word/document.xml", xml);
98284
+ dropFolderEntries(doc.zip);
98144
98285
  const buffer = await doc.zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
98145
98286
  return buffer;
98146
98287
  }
98147
98288
  function createBlankDocx(opts) {
98148
- const zip = new import_jszip.default();
98289
+ const zip = new import_jszip2.default();
98149
98290
  zip.file("[Content_Types].xml", CONTENT_TYPES_XML);
98150
98291
  zip.file("_rels/.rels", RELS_XML);
98151
98292
  zip.file("word/_rels/document.xml.rels", DOCUMENT_RELS_XML);
@@ -98204,9 +98345,9 @@ async function ensureContentTypeOverride(doc, partName, contentType) {
98204
98345
  }
98205
98346
 
98206
98347
  // ../docx/src/parse/parser.ts
98207
- var import_jszip2 = __toESM(require_lib4(), 1);
98348
+ var import_jszip3 = __toESM(require_lib4(), 1);
98208
98349
  async function parseDocx(buffer) {
98209
- const zip = await import_jszip2.default.loadAsync(buffer);
98350
+ const zip = await import_jszip3.default.loadAsync(buffer);
98210
98351
  const parts = /* @__PURE__ */ new Map();
98211
98352
  const filePromises = [];
98212
98353
  zip.forEach((path8, file2) => {
@@ -98341,7 +98482,7 @@ function parseOpaqueRunChild(el) {
98341
98482
  }
98342
98483
 
98343
98484
  // ../docx/src/serialize/serializer.ts
98344
- var import_jszip3 = __toESM(require_lib4(), 1);
98485
+ var import_jszip4 = __toESM(require_lib4(), 1);
98345
98486
 
98346
98487
  // ../docx/src/serialize/default_parts.ts
98347
98488
  var encoder = new TextEncoder();
@@ -98455,7 +98596,7 @@ function fillDefaultParts(parts) {
98455
98596
 
98456
98597
  // ../docx/src/serialize/serializer.ts
98457
98598
  async function serializeDocx(doc) {
98458
- const zip = new import_jszip3.default();
98599
+ const zip = new import_jszip4.default();
98459
98600
  const parts = fillDefaultParts(new Map(doc.parts));
98460
98601
  for (const [path8, bytes] of parts) {
98461
98602
  if (path8 === "word/document.xml") continue;
@@ -98463,6 +98604,7 @@ async function serializeDocx(doc) {
98463
98604
  }
98464
98605
  const documentXml = serializeDocumentXml(doc);
98465
98606
  zip.file("word/document.xml", documentXml);
98607
+ dropFolderEntries(zip);
98466
98608
  const out = await zip.generateAsync({
98467
98609
  type: "uint8array",
98468
98610
  compression: "DEFLATE"
@@ -100293,7 +100435,7 @@ Available workspaces:`);
100293
100435
  if (subcommand === "query") {
100294
100436
  const action = toolArgs;
100295
100437
  if (action === "set") {
100296
- if (restArgs.includes("--all")) {
100438
+ if (flags.all) {
100297
100439
  await appQuerySet(client, { all: true });
100298
100440
  return;
100299
100441
  }