@abyssinia-labs/sokie 0.3.1 → 0.4.0-staging.123

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.
Files changed (2) hide show
  1. package/dist/sokie.mjs +1696 -664
  2. package/package.json +2 -2
package/dist/sokie.mjs CHANGED
@@ -287,8 +287,8 @@ var require_directives = __commonJS((exports) => {
287
287
  this.atNextDocument = false;
288
288
  }
289
289
  const parts = line.trim().split(/[ \t]+/);
290
- const name = parts.shift();
291
- switch (name) {
290
+ const name2 = parts.shift();
291
+ switch (name2) {
292
292
  case "%TAG": {
293
293
  if (parts.length !== 2) {
294
294
  onError(0, "%TAG directive should contain exactly two parts");
@@ -316,7 +316,7 @@ var require_directives = __commonJS((exports) => {
316
316
  }
317
317
  }
318
318
  default:
319
- onError(0, `Unknown directive ${name}`, true);
319
+ onError(0, `Unknown directive ${name2}`, true);
320
320
  return false;
321
321
  }
322
322
  }
@@ -413,9 +413,9 @@ var require_anchors = __commonJS((exports) => {
413
413
  }
414
414
  function findNewAnchor(prefix, exclude) {
415
415
  for (let i2 = 1;; ++i2) {
416
- const name = `${prefix}${i2}`;
417
- if (!exclude.has(name))
418
- return name;
416
+ const name2 = `${prefix}${i2}`;
417
+ if (!exclude.has(name2))
418
+ return name2;
419
419
  }
420
420
  }
421
421
  function createNodeAnchors(doc, prefix) {
@@ -1411,8 +1411,8 @@ var require_stringify = __commonJS((exports) => {
1411
1411
  tagObj = tags.find((t) => t.nodeClass && obj instanceof t.nodeClass);
1412
1412
  }
1413
1413
  if (!tagObj) {
1414
- const name = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
1415
- throw new Error(`Tag not resolved for ${name} value`);
1414
+ const name2 = obj?.constructor?.name ?? (obj === null ? "null" : typeof obj);
1415
+ throw new Error(`Tag not resolved for ${name2} value`);
1416
1416
  }
1417
1417
  return tagObj;
1418
1418
  }
@@ -3267,10 +3267,10 @@ var require_Document = __commonJS((exports) => {
3267
3267
  if (assertCollection(this.contents))
3268
3268
  this.contents.addIn(path, value);
3269
3269
  }
3270
- createAlias(node, name) {
3270
+ createAlias(node, name2) {
3271
3271
  if (!node.anchor) {
3272
3272
  const prev = anchors.anchorNames(this);
3273
- node.anchor = !name || prev.has(name) ? anchors.findNewAnchor(name || "a", prev) : name;
3273
+ node.anchor = !name2 || prev.has(name2) ? anchors.findNewAnchor(name2 || "a", prev) : name2;
3274
3274
  }
3275
3275
  return new Alias.Alias(node.anchor);
3276
3276
  }
@@ -3431,9 +3431,9 @@ var require_Document = __commonJS((exports) => {
3431
3431
  // ../../node_modules/yaml/dist/errors.js
3432
3432
  var require_errors = __commonJS((exports) => {
3433
3433
  class YAMLError extends Error {
3434
- constructor(name, pos, code2, message) {
3434
+ constructor(name2, pos, code2, message) {
3435
3435
  super();
3436
- this.name = name;
3436
+ this.name = name2;
3437
3437
  this.code = code2;
3438
3438
  this.message = message;
3439
3439
  this.pos = pos;
@@ -4053,8 +4053,8 @@ var require_resolve_flow_collection = __commonJS((exports) => {
4053
4053
  if (ce?.source === expectedEnd)
4054
4054
  cePos = ce.offset + ce.source.length;
4055
4055
  else {
4056
- const name = fcName[0].toUpperCase() + fcName.substring(1);
4057
- const msg = atRoot ? `${name} must end with a ${expectedEnd}` : `${name} in block collection must be sufficiently indented and end with a ${expectedEnd}`;
4056
+ const name2 = fcName[0].toUpperCase() + fcName.substring(1);
4057
+ const msg = atRoot ? `${name2} must end with a ${expectedEnd}` : `${name2} in block collection must be sufficiently indented and end with a ${expectedEnd}`;
4058
4058
  onError(offset, atRoot ? "MISSING_CHAR" : "BAD_INDENT", msg);
4059
4059
  if (ce && ce.source.length !== 1)
4060
4060
  ee.unshift(ce);
@@ -7046,9 +7046,9 @@ var require_inspect = __commonJS((exports) => {
7046
7046
  function getObjectTag(object2) {
7047
7047
  const tag = Object.prototype.toString.call(object2).replace(/^\[object /, "").replace(/]$/, "");
7048
7048
  if (tag === "Object" && typeof object2.constructor === "function") {
7049
- const name = object2.constructor.name;
7050
- if (typeof name === "string" && name !== "") {
7051
- return name;
7049
+ const name2 = object2.constructor.name;
7050
+ if (typeof name2 === "string" && name2 !== "") {
7051
+ return name2;
7052
7052
  }
7053
7053
  }
7054
7054
  return tag;
@@ -8483,8 +8483,8 @@ var require_printer = __commonJS((exports) => {
8483
8483
  },
8484
8484
  SelectionSet: { leave: ({ selections }) => block(selections) },
8485
8485
  Field: {
8486
- leave({ alias, name, arguments: args, directives, selectionSet }) {
8487
- const prefix = join([wrap("", alias, ": "), name], "");
8486
+ leave({ alias, name: name2, arguments: args, directives, selectionSet }) {
8487
+ const prefix = join([wrap("", alias, ": "), name2], "");
8488
8488
  return join([
8489
8489
  wrappedLineAndArgs(prefix, args),
8490
8490
  wrap(" ", join(directives, " ")),
@@ -8492,11 +8492,11 @@ var require_printer = __commonJS((exports) => {
8492
8492
  ]);
8493
8493
  }
8494
8494
  },
8495
- Argument: { leave: ({ name, value }) => name + ": " + value },
8496
- FragmentArgument: { leave: ({ name, value }) => name + ": " + value },
8495
+ Argument: { leave: ({ name: name2, value }) => name2 + ": " + value },
8496
+ FragmentArgument: { leave: ({ name: name2, value }) => name2 + ": " + value },
8497
8497
  FragmentSpread: {
8498
- leave: ({ name, arguments: args, directives }) => {
8499
- const prefix = "..." + name;
8498
+ leave: ({ name: name2, arguments: args, directives }) => {
8499
+ const prefix = "..." + name2;
8500
8500
  return wrappedLineAndArgs(prefix, args) + wrap(" ", join(directives, " "));
8501
8501
  }
8502
8502
  },
@@ -8509,8 +8509,8 @@ var require_printer = __commonJS((exports) => {
8509
8509
  ], " ")
8510
8510
  },
8511
8511
  FragmentDefinition: {
8512
- leave: ({ name, typeCondition, variableDefinitions, directives, selectionSet, description }) => wrap("", description, `
8513
- `) + `fragment ${name}${wrap("(", join(variableDefinitions, ", "), ")")} ` + `on ${typeCondition} ${wrap("", join(directives, " "), " ")}` + selectionSet
8512
+ leave: ({ name: name2, typeCondition, variableDefinitions, directives, selectionSet, description }) => wrap("", description, `
8513
+ `) + `fragment ${name2}${wrap("(", join(variableDefinitions, ", "), ")")} ` + `on ${typeCondition} ${wrap("", join(directives, " "), " ")}` + selectionSet
8514
8514
  },
8515
8515
  IntValue: { leave: ({ value }) => value },
8516
8516
  FloatValue: { leave: ({ value }) => value },
@@ -8538,11 +8538,11 @@ var require_printer = __commonJS((exports) => {
8538
8538
  return fieldsLine.length > MAX_LINE_LENGTH ? block(fields) : fieldsLine;
8539
8539
  }
8540
8540
  },
8541
- ObjectField: { leave: ({ name, value }) => name + ": " + value },
8541
+ ObjectField: { leave: ({ name: name2, value }) => name2 + ": " + value },
8542
8542
  Directive: {
8543
- leave: ({ name, arguments: args }) => "@" + name + wrap("(", join(args, ", "), ")")
8543
+ leave: ({ name: name2, arguments: args }) => "@" + name2 + wrap("(", join(args, ", "), ")")
8544
8544
  },
8545
- NamedType: { leave: ({ name }) => name },
8545
+ NamedType: { leave: ({ name: name2 }) => name2 },
8546
8546
  ListType: { leave: ({ type }) => "[" + type + "]" },
8547
8547
  NonNullType: { leave: ({ type }) => type + "!" },
8548
8548
  SchemaDefinition: {
@@ -8553,59 +8553,59 @@ var require_printer = __commonJS((exports) => {
8553
8553
  leave: ({ operation, type }) => operation + ": " + type
8554
8554
  },
8555
8555
  ScalarTypeDefinition: {
8556
- leave: ({ description, name, directives }) => wrap("", description, `
8557
- `) + join(["scalar", name, join(directives, " ")], " ")
8556
+ leave: ({ description, name: name2, directives }) => wrap("", description, `
8557
+ `) + join(["scalar", name2, join(directives, " ")], " ")
8558
8558
  },
8559
8559
  ObjectTypeDefinition: {
8560
- leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, `
8560
+ leave: ({ description, name: name2, interfaces, directives, fields }) => wrap("", description, `
8561
8561
  `) + join([
8562
8562
  "type",
8563
- name,
8563
+ name2,
8564
8564
  wrap("implements ", join(interfaces, " & ")),
8565
8565
  join(directives, " "),
8566
8566
  block(fields)
8567
8567
  ], " ")
8568
8568
  },
8569
8569
  FieldDefinition: {
8570
- leave: ({ description, name, arguments: args, type, directives }) => wrap("", description, `
8571
- `) + name + (hasMultilineItems(args) ? wrap(`(
8570
+ leave: ({ description, name: name2, arguments: args, type, directives }) => wrap("", description, `
8571
+ `) + name2 + (hasMultilineItems(args) ? wrap(`(
8572
8572
  `, indent(join(args, `
8573
8573
  `)), `
8574
8574
  )`) : wrap("(", join(args, ", "), ")")) + ": " + type + wrap(" ", join(directives, " "))
8575
8575
  },
8576
8576
  InputValueDefinition: {
8577
- leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, `
8578
- `) + join([name + ": " + type, wrap("= ", defaultValue), join(directives, " ")], " ")
8577
+ leave: ({ description, name: name2, type, defaultValue, directives }) => wrap("", description, `
8578
+ `) + join([name2 + ": " + type, wrap("= ", defaultValue), join(directives, " ")], " ")
8579
8579
  },
8580
8580
  InterfaceTypeDefinition: {
8581
- leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, `
8581
+ leave: ({ description, name: name2, interfaces, directives, fields }) => wrap("", description, `
8582
8582
  `) + join([
8583
8583
  "interface",
8584
- name,
8584
+ name2,
8585
8585
  wrap("implements ", join(interfaces, " & ")),
8586
8586
  join(directives, " "),
8587
8587
  block(fields)
8588
8588
  ], " ")
8589
8589
  },
8590
8590
  UnionTypeDefinition: {
8591
- leave: ({ description, name, directives, types }) => wrap("", description, `
8592
- `) + join(["union", name, join(directives, " "), wrap("= ", join(types, " | "))], " ")
8591
+ leave: ({ description, name: name2, directives, types }) => wrap("", description, `
8592
+ `) + join(["union", name2, join(directives, " "), wrap("= ", join(types, " | "))], " ")
8593
8593
  },
8594
8594
  EnumTypeDefinition: {
8595
- leave: ({ description, name, directives, values }) => wrap("", description, `
8596
- `) + join(["enum", name, join(directives, " "), block(values)], " ")
8595
+ leave: ({ description, name: name2, directives, values }) => wrap("", description, `
8596
+ `) + join(["enum", name2, join(directives, " "), block(values)], " ")
8597
8597
  },
8598
8598
  EnumValueDefinition: {
8599
- leave: ({ description, name, directives }) => wrap("", description, `
8600
- `) + join([name, join(directives, " ")], " ")
8599
+ leave: ({ description, name: name2, directives }) => wrap("", description, `
8600
+ `) + join([name2, join(directives, " ")], " ")
8601
8601
  },
8602
8602
  InputObjectTypeDefinition: {
8603
- leave: ({ description, name, directives, fields }) => wrap("", description, `
8604
- `) + join(["input", name, join(directives, " "), block(fields)], " ")
8603
+ leave: ({ description, name: name2, directives, fields }) => wrap("", description, `
8604
+ `) + join(["input", name2, join(directives, " "), block(fields)], " ")
8605
8605
  },
8606
8606
  DirectiveDefinition: {
8607
- leave: ({ description, name, arguments: args, directives, repeatable, locations }) => wrap("", description, `
8608
- `) + "directive @" + name + (hasMultilineItems(args) ? wrap(`(
8607
+ leave: ({ description, name: name2, arguments: args, directives, repeatable, locations }) => wrap("", description, `
8608
+ `) + "directive @" + name2 + (hasMultilineItems(args) ? wrap(`(
8609
8609
  `, indent(join(args, `
8610
8610
  `)), `
8611
8611
  )`) : wrap("(", join(args, ", "), ")")) + wrap(" ", join(directives, " ")) + (repeatable ? " repeatable" : "") + " on " + join(locations, " | ")
@@ -8614,53 +8614,53 @@ var require_printer = __commonJS((exports) => {
8614
8614
  leave: ({ directives, operationTypes }) => join(["extend schema", join(directives, " "), block(operationTypes)], " ")
8615
8615
  },
8616
8616
  ScalarTypeExtension: {
8617
- leave: ({ name, directives }) => join(["extend scalar", name, join(directives, " ")], " ")
8617
+ leave: ({ name: name2, directives }) => join(["extend scalar", name2, join(directives, " ")], " ")
8618
8618
  },
8619
8619
  ObjectTypeExtension: {
8620
- leave: ({ name, interfaces, directives, fields }) => join([
8620
+ leave: ({ name: name2, interfaces, directives, fields }) => join([
8621
8621
  "extend type",
8622
- name,
8622
+ name2,
8623
8623
  wrap("implements ", join(interfaces, " & ")),
8624
8624
  join(directives, " "),
8625
8625
  block(fields)
8626
8626
  ], " ")
8627
8627
  },
8628
8628
  InterfaceTypeExtension: {
8629
- leave: ({ name, interfaces, directives, fields }) => join([
8629
+ leave: ({ name: name2, interfaces, directives, fields }) => join([
8630
8630
  "extend interface",
8631
- name,
8631
+ name2,
8632
8632
  wrap("implements ", join(interfaces, " & ")),
8633
8633
  join(directives, " "),
8634
8634
  block(fields)
8635
8635
  ], " ")
8636
8636
  },
8637
8637
  UnionTypeExtension: {
8638
- leave: ({ name, directives, types }) => join([
8638
+ leave: ({ name: name2, directives, types }) => join([
8639
8639
  "extend union",
8640
- name,
8640
+ name2,
8641
8641
  join(directives, " "),
8642
8642
  wrap("= ", join(types, " | "))
8643
8643
  ], " ")
8644
8644
  },
8645
8645
  EnumTypeExtension: {
8646
- leave: ({ name, directives, values }) => join(["extend enum", name, join(directives, " "), block(values)], " ")
8646
+ leave: ({ name: name2, directives, values }) => join(["extend enum", name2, join(directives, " "), block(values)], " ")
8647
8647
  },
8648
8648
  InputObjectTypeExtension: {
8649
- leave: ({ name, directives, fields }) => join(["extend input", name, join(directives, " "), block(fields)], " ")
8649
+ leave: ({ name: name2, directives, fields }) => join(["extend input", name2, join(directives, " "), block(fields)], " ")
8650
8650
  },
8651
8651
  DirectiveExtension: {
8652
- leave: ({ name, directives }) => join(["extend directive @" + name, join(directives, " ")], " ")
8652
+ leave: ({ name: name2, directives }) => join(["extend directive @" + name2, join(directives, " ")], " ")
8653
8653
  },
8654
- TypeCoordinate: { leave: ({ name }) => name },
8654
+ TypeCoordinate: { leave: ({ name: name2 }) => name2 },
8655
8655
  MemberCoordinate: {
8656
- leave: ({ name, memberName }) => join([name, wrap(".", memberName)])
8656
+ leave: ({ name: name2, memberName }) => join([name2, wrap(".", memberName)])
8657
8657
  },
8658
8658
  ArgumentCoordinate: {
8659
- leave: ({ name, fieldName, argumentName }) => join([name, wrap(".", fieldName), wrap("(", argumentName, ":)")])
8659
+ leave: ({ name: name2, fieldName, argumentName }) => join([name2, wrap(".", fieldName), wrap("(", argumentName, ":)")])
8660
8660
  },
8661
- DirectiveCoordinate: { leave: ({ name }) => join(["@", name]) },
8661
+ DirectiveCoordinate: { leave: ({ name: name2 }) => join(["@", name2]) },
8662
8662
  DirectiveArgumentCoordinate: {
8663
- leave: ({ name, argumentName }) => join(["@", name, wrap("(", argumentName, ":)")])
8663
+ leave: ({ name: name2, argumentName }) => join(["@", name2, wrap("(", argumentName, ":)")])
8664
8664
  }
8665
8665
  };
8666
8666
  function join(maybeArray, separator = "") {
@@ -8731,25 +8731,25 @@ var require_assertName = __commonJS((exports) => {
8731
8731
  exports.assertEnumValueName = assertEnumValueName;
8732
8732
  var GraphQLError_ts_1 = require_GraphQLError();
8733
8733
  var characterClasses_ts_1 = require_characterClasses();
8734
- function assertName(name) {
8735
- if (name.length === 0) {
8734
+ function assertName(name2) {
8735
+ if (name2.length === 0) {
8736
8736
  throw new GraphQLError_ts_1.GraphQLError("Expected name to be a non-empty string.");
8737
8737
  }
8738
- for (let i2 = 1;i2 < name.length; ++i2) {
8739
- if (!(0, characterClasses_ts_1.isNameContinue)(name.charCodeAt(i2))) {
8740
- throw new GraphQLError_ts_1.GraphQLError(`Names must only contain [_a-zA-Z0-9] but "${name}" does not.`);
8738
+ for (let i2 = 1;i2 < name2.length; ++i2) {
8739
+ if (!(0, characterClasses_ts_1.isNameContinue)(name2.charCodeAt(i2))) {
8740
+ throw new GraphQLError_ts_1.GraphQLError(`Names must only contain [_a-zA-Z0-9] but "${name2}" does not.`);
8741
8741
  }
8742
8742
  }
8743
- if (!(0, characterClasses_ts_1.isNameStart)(name.charCodeAt(0))) {
8744
- throw new GraphQLError_ts_1.GraphQLError(`Names must start with [_a-zA-Z] but "${name}" does not.`);
8743
+ if (!(0, characterClasses_ts_1.isNameStart)(name2.charCodeAt(0))) {
8744
+ throw new GraphQLError_ts_1.GraphQLError(`Names must start with [_a-zA-Z] but "${name2}" does not.`);
8745
8745
  }
8746
- return name;
8746
+ return name2;
8747
8747
  }
8748
- function assertEnumValueName(name) {
8749
- if (name === "true" || name === "false" || name === "null") {
8750
- throw new GraphQLError_ts_1.GraphQLError(`Enum values cannot be named: ${name}`);
8748
+ function assertEnumValueName(name2) {
8749
+ if (name2 === "true" || name2 === "false" || name2 === "null") {
8750
+ throw new GraphQLError_ts_1.GraphQLError(`Enum values cannot be named: ${name2}`);
8751
8751
  }
8752
- return assertName(name);
8752
+ return assertName(name2);
8753
8753
  }
8754
8754
  });
8755
8755
 
@@ -9187,10 +9187,10 @@ var require_definition = __commonJS((exports) => {
9187
9187
  }
9188
9188
 
9189
9189
  class GraphQLField {
9190
- constructor(parentType, name, config2) {
9190
+ constructor(parentType, name2, config2) {
9191
9191
  this.__kind = fieldSymbol;
9192
9192
  this.parentType = parentType;
9193
- this.name = (0, assertName_ts_1.assertName)(name);
9193
+ this.name = (0, assertName_ts_1.assertName)(name2);
9194
9194
  this.description = config2.description;
9195
9195
  this.type = config2.type;
9196
9196
  const argsConfig = config2.args;
@@ -9226,10 +9226,10 @@ var require_definition = __commonJS((exports) => {
9226
9226
  exports.GraphQLField = GraphQLField;
9227
9227
 
9228
9228
  class GraphQLArgument {
9229
- constructor(parent, name, config2) {
9229
+ constructor(parent, name2, config2) {
9230
9230
  this.__kind = argumentSymbol;
9231
9231
  this.parent = parent;
9232
- this.name = (0, assertName_ts_1.assertName)(name);
9232
+ this.name = (0, assertName_ts_1.assertName)(name2);
9233
9233
  this.description = config2.description;
9234
9234
  this.type = config2.type;
9235
9235
  this.defaultValue = config2.defaultValue;
@@ -9377,9 +9377,9 @@ var require_definition = __commonJS((exports) => {
9377
9377
  }
9378
9378
  return this._values;
9379
9379
  }
9380
- getValue(name) {
9380
+ getValue(name2) {
9381
9381
  this._nameLookup ??= (0, keyMap_ts_1.keyMap)(this.getValues(), (value) => value.name);
9382
- return this._nameLookup[name];
9382
+ return this._nameLookup[name2];
9383
9383
  }
9384
9384
  serialize(outputValue) {
9385
9385
  return this.coerceOutputValue(outputValue);
@@ -9455,12 +9455,12 @@ var require_definition = __commonJS((exports) => {
9455
9455
  }
9456
9456
 
9457
9457
  class GraphQLEnumValue {
9458
- constructor(parentEnum, name, config2) {
9458
+ constructor(parentEnum, name2, config2) {
9459
9459
  this.__kind = enumValueSymbol;
9460
9460
  this.parentEnum = parentEnum;
9461
- this.name = (0, assertName_ts_1.assertEnumValueName)(name);
9461
+ this.name = (0, assertName_ts_1.assertEnumValueName)(name2);
9462
9462
  this.description = config2.description;
9463
- this.value = config2.value !== undefined ? config2.value : name;
9463
+ this.value = config2.value !== undefined ? config2.value : name2;
9464
9464
  this.deprecationReason = config2.deprecationReason;
9465
9465
  this.extensions = (0, toObjMap_ts_1.toObjMapWithSymbols)(config2.extensions);
9466
9466
  this.astNode = config2.astNode;
@@ -9531,12 +9531,12 @@ var require_definition = __commonJS((exports) => {
9531
9531
  }
9532
9532
 
9533
9533
  class GraphQLInputField {
9534
- constructor(parentType, name, config2) {
9534
+ constructor(parentType, name2, config2) {
9535
9535
  if (!!("resolve" in config2))
9536
- (0, devAssert_ts_1.devAssert)(false, `${parentType}.${name} field has a resolve property, but Input Types cannot define resolvers.`);
9536
+ (0, devAssert_ts_1.devAssert)(false, `${parentType}.${name2} field has a resolve property, but Input Types cannot define resolvers.`);
9537
9537
  this.__kind = inputFieldSymbol;
9538
9538
  this.parentType = parentType;
9539
- this.name = (0, assertName_ts_1.assertName)(name);
9539
+ this.name = (0, assertName_ts_1.assertName)(name2);
9540
9540
  this.description = config2.description;
9541
9541
  this.type = config2.type;
9542
9542
  this.defaultValue = config2.defaultValue;
@@ -9692,7 +9692,7 @@ var require_valueToLiteral = __commonJS((exports) => {
9692
9692
  }
9693
9693
  const fields = [];
9694
9694
  const fieldDefs = type.getFields();
9695
- const hasUndefinedField = Object.keys(value).some((name) => value[name] !== undefined && !Object.hasOwn(fieldDefs, name));
9695
+ const hasUndefinedField = Object.keys(value).some((name2) => value[name2] !== undefined && !Object.hasOwn(fieldDefs, name2));
9696
9696
  if (hasUndefinedField) {
9697
9697
  return;
9698
9698
  }
@@ -10343,7 +10343,7 @@ var require_scalars = __commonJS((exports) => {
10343
10343
  exports.GraphQLID
10344
10344
  ]);
10345
10345
  function isSpecifiedScalarType(type) {
10346
- return exports.specifiedScalarTypes.some(({ name }) => type.name === name);
10346
+ return exports.specifiedScalarTypes.some(({ name: name2 }) => type.name === name2);
10347
10347
  }
10348
10348
  function coerceOutputValueObject(outputValue) {
10349
10349
  if ((0, isObjectLike_ts_1.isObjectLike)(outputValue)) {
@@ -10626,7 +10626,7 @@ var require_directives2 = __commonJS((exports) => {
10626
10626
  exports.GraphQLOneOfDirective
10627
10627
  ]);
10628
10628
  function isSpecifiedDirective(directive) {
10629
- return exports.specifiedDirectives.some(({ name }) => name === directive.name);
10629
+ return exports.specifiedDirectives.some(({ name: name2 }) => name2 === directive.name);
10630
10630
  }
10631
10631
  });
10632
10632
 
@@ -11211,7 +11211,7 @@ In some cases, you need to provide options to alter GraphQL's execution behavior
11211
11211
  type: exports.__Type,
11212
11212
  description: "Request the type information of a single type.",
11213
11213
  args: { name: { type: new definition_ts_1.GraphQLNonNull(scalars_ts_1.GraphQLString) } },
11214
- resolve: (_source, { name }, _context, { schema }) => schema.getType(name)
11214
+ resolve: (_source, { name: name2 }, _context, { schema }) => schema.getType(name2)
11215
11215
  });
11216
11216
  exports.TypeNameMetaFieldDef = new definition_ts_1.GraphQLField(undefined, "__typename", {
11217
11217
  type: new definition_ts_1.GraphQLNonNull(scalars_ts_1.GraphQLString),
@@ -11229,7 +11229,7 @@ In some cases, you need to provide options to alter GraphQL's execution behavior
11229
11229
  exports.__TypeKind
11230
11230
  ]);
11231
11231
  function isIntrospectionType(type) {
11232
- return exports.introspectionTypes.some(({ name }) => type.name === name);
11232
+ return exports.introspectionTypes.some(({ name: name2 }) => type.name === name2);
11233
11233
  }
11234
11234
  });
11235
11235
 
@@ -11356,8 +11356,8 @@ var require_schema4 = __commonJS((exports) => {
11356
11356
  getTypeMap() {
11357
11357
  return this._typeMap;
11358
11358
  }
11359
- getType(name) {
11360
- return this.getTypeMap()[name];
11359
+ getType(name2) {
11360
+ return this.getTypeMap()[name2];
11361
11361
  }
11362
11362
  getPossibleTypes(abstractType) {
11363
11363
  return (0, definition_ts_1.isUnionType)(abstractType) ? abstractType.getTypes() : this.getImplementations(abstractType).objects;
@@ -11385,8 +11385,8 @@ var require_schema4 = __commonJS((exports) => {
11385
11385
  getDirectives() {
11386
11386
  return this._directives;
11387
11387
  }
11388
- getDirective(name) {
11389
- return this.getDirectives().find((directive) => directive.name === name);
11388
+ getDirective(name2) {
11389
+ return this.getDirectives().find((directive) => directive.name === name2);
11390
11390
  }
11391
11391
  getField(parentType, fieldName) {
11392
11392
  switch (fieldName) {
@@ -12589,10 +12589,10 @@ var require_source = __commonJS((exports) => {
12589
12589
  var sourceSymbol = Symbol("Source");
12590
12590
 
12591
12591
  class Source {
12592
- constructor(body, name = "GraphQL request", locationOffset = { line: 1, column: 1 }) {
12592
+ constructor(body, name2 = "GraphQL request", locationOffset = { line: 1, column: 1 }) {
12593
12593
  this.__kind = sourceSymbol;
12594
12594
  this.body = body;
12595
- this.name = name;
12595
+ this.name = name2;
12596
12596
  this.locationOffset = locationOffset;
12597
12597
  if (!(this.locationOffset.line > 0))
12598
12598
  (0, devAssert_ts_1.devAssert)(false, "line in locationOffset is 1-indexed and must be positive.");
@@ -12759,15 +12759,15 @@ var require_parser2 = __commonJS((exports) => {
12759
12759
  }
12760
12760
  const description = this.parseDescription();
12761
12761
  const operation = this.parseOperationType();
12762
- let name;
12762
+ let name2;
12763
12763
  if (this.peek(tokenKind_ts_1.TokenKind.NAME)) {
12764
- name = this.parseName();
12764
+ name2 = this.parseName();
12765
12765
  }
12766
12766
  return this.node(start, {
12767
12767
  kind: kinds_ts_1.Kind.OPERATION_DEFINITION,
12768
12768
  operation,
12769
12769
  description,
12770
- name,
12770
+ name: name2,
12771
12771
  variableDefinitions: this.parseVariableDefinitions(),
12772
12772
  directives: this.parseDirectives(false),
12773
12773
  selectionSet: this.parseSelectionSet()
@@ -12819,17 +12819,17 @@ var require_parser2 = __commonJS((exports) => {
12819
12819
  const start = this._lexer.token;
12820
12820
  const nameOrAlias = this.parseName();
12821
12821
  let alias;
12822
- let name;
12822
+ let name2;
12823
12823
  if (this.expectOptionalToken(tokenKind_ts_1.TokenKind.COLON)) {
12824
12824
  alias = nameOrAlias;
12825
- name = this.parseName();
12825
+ name2 = this.parseName();
12826
12826
  } else {
12827
- name = nameOrAlias;
12827
+ name2 = nameOrAlias;
12828
12828
  }
12829
12829
  return this.node(start, {
12830
12830
  kind: kinds_ts_1.Kind.FIELD,
12831
12831
  alias,
12832
- name,
12832
+ name: name2,
12833
12833
  arguments: this.parseArguments(false),
12834
12834
  directives: this.parseDirectives(false),
12835
12835
  selectionSet: this.peek(tokenKind_ts_1.TokenKind.BRACE_L) ? this.parseSelectionSet() : undefined
@@ -12845,11 +12845,11 @@ var require_parser2 = __commonJS((exports) => {
12845
12845
  }
12846
12846
  parseArgument(isConst = false) {
12847
12847
  const start = this._lexer.token;
12848
- const name = this.parseName();
12848
+ const name2 = this.parseName();
12849
12849
  this.expectToken(tokenKind_ts_1.TokenKind.COLON);
12850
12850
  return this.node(start, {
12851
12851
  kind: kinds_ts_1.Kind.ARGUMENT,
12852
- name,
12852
+ name: name2,
12853
12853
  value: this.parseValueLiteral(isConst)
12854
12854
  });
12855
12855
  }
@@ -12858,11 +12858,11 @@ var require_parser2 = __commonJS((exports) => {
12858
12858
  }
12859
12859
  parseFragmentArgument() {
12860
12860
  const start = this._lexer.token;
12861
- const name = this.parseName();
12861
+ const name2 = this.parseName();
12862
12862
  this.expectToken(tokenKind_ts_1.TokenKind.COLON);
12863
12863
  return this.node(start, {
12864
12864
  kind: kinds_ts_1.Kind.FRAGMENT_ARGUMENT,
12865
- name,
12865
+ name: name2,
12866
12866
  value: this.parseValueLiteral(false)
12867
12867
  });
12868
12868
  }
@@ -12871,18 +12871,18 @@ var require_parser2 = __commonJS((exports) => {
12871
12871
  this.expectToken(tokenKind_ts_1.TokenKind.SPREAD);
12872
12872
  const hasTypeCondition = this.expectOptionalKeyword("on");
12873
12873
  if (!hasTypeCondition && this.peek(tokenKind_ts_1.TokenKind.NAME)) {
12874
- const name = this.parseFragmentName();
12874
+ const name2 = this.parseFragmentName();
12875
12875
  if (this.peek(tokenKind_ts_1.TokenKind.PAREN_L) && this._options.experimentalFragmentArguments) {
12876
12876
  return this.node(start, {
12877
12877
  kind: kinds_ts_1.Kind.FRAGMENT_SPREAD,
12878
- name,
12878
+ name: name2,
12879
12879
  arguments: this.parseFragmentArguments(),
12880
12880
  directives: this.parseDirectives(false)
12881
12881
  });
12882
12882
  }
12883
12883
  return this.node(start, {
12884
12884
  kind: kinds_ts_1.Kind.FRAGMENT_SPREAD,
12885
- name,
12885
+ name: name2,
12886
12886
  directives: this.parseDirectives(false)
12887
12887
  });
12888
12888
  }
@@ -13009,11 +13009,11 @@ var require_parser2 = __commonJS((exports) => {
13009
13009
  }
13010
13010
  parseObjectField(isConst) {
13011
13011
  const start = this._lexer.token;
13012
- const name = this.parseName();
13012
+ const name2 = this.parseName();
13013
13013
  this.expectToken(tokenKind_ts_1.TokenKind.COLON);
13014
13014
  return this.node(start, {
13015
13015
  kind: kinds_ts_1.Kind.OBJECT_FIELD,
13016
- name,
13016
+ name: name2,
13017
13017
  value: this.parseValueLiteral(isConst)
13018
13018
  });
13019
13019
  }
@@ -13102,12 +13102,12 @@ var require_parser2 = __commonJS((exports) => {
13102
13102
  const start = this._lexer.token;
13103
13103
  const description = this.parseDescription();
13104
13104
  this.expectKeyword("scalar");
13105
- const name = this.parseName();
13105
+ const name2 = this.parseName();
13106
13106
  const directives = this.parseConstDirectives();
13107
13107
  return this.node(start, {
13108
13108
  kind: kinds_ts_1.Kind.SCALAR_TYPE_DEFINITION,
13109
13109
  description,
13110
- name,
13110
+ name: name2,
13111
13111
  directives
13112
13112
  });
13113
13113
  }
@@ -13115,14 +13115,14 @@ var require_parser2 = __commonJS((exports) => {
13115
13115
  const start = this._lexer.token;
13116
13116
  const description = this.parseDescription();
13117
13117
  this.expectKeyword("type");
13118
- const name = this.parseName();
13118
+ const name2 = this.parseName();
13119
13119
  const interfaces = this.parseImplementsInterfaces();
13120
13120
  const directives = this.parseConstDirectives();
13121
13121
  const fields = this.parseFieldsDefinition();
13122
13122
  return this.node(start, {
13123
13123
  kind: kinds_ts_1.Kind.OBJECT_TYPE_DEFINITION,
13124
13124
  description,
13125
- name,
13125
+ name: name2,
13126
13126
  interfaces,
13127
13127
  directives,
13128
13128
  fields
@@ -13137,7 +13137,7 @@ var require_parser2 = __commonJS((exports) => {
13137
13137
  parseFieldDefinition() {
13138
13138
  const start = this._lexer.token;
13139
13139
  const description = this.parseDescription();
13140
- const name = this.parseName();
13140
+ const name2 = this.parseName();
13141
13141
  const args = this.parseArgumentDefs();
13142
13142
  this.expectToken(tokenKind_ts_1.TokenKind.COLON);
13143
13143
  const type = this.parseTypeReference();
@@ -13145,7 +13145,7 @@ var require_parser2 = __commonJS((exports) => {
13145
13145
  return this.node(start, {
13146
13146
  kind: kinds_ts_1.Kind.FIELD_DEFINITION,
13147
13147
  description,
13148
- name,
13148
+ name: name2,
13149
13149
  arguments: args,
13150
13150
  type,
13151
13151
  directives
@@ -13157,7 +13157,7 @@ var require_parser2 = __commonJS((exports) => {
13157
13157
  parseInputValueDef() {
13158
13158
  const start = this._lexer.token;
13159
13159
  const description = this.parseDescription();
13160
- const name = this.parseName();
13160
+ const name2 = this.parseName();
13161
13161
  this.expectToken(tokenKind_ts_1.TokenKind.COLON);
13162
13162
  const type = this.parseTypeReference();
13163
13163
  let defaultValue;
@@ -13168,7 +13168,7 @@ var require_parser2 = __commonJS((exports) => {
13168
13168
  return this.node(start, {
13169
13169
  kind: kinds_ts_1.Kind.INPUT_VALUE_DEFINITION,
13170
13170
  description,
13171
- name,
13171
+ name: name2,
13172
13172
  type,
13173
13173
  defaultValue,
13174
13174
  directives
@@ -13178,14 +13178,14 @@ var require_parser2 = __commonJS((exports) => {
13178
13178
  const start = this._lexer.token;
13179
13179
  const description = this.parseDescription();
13180
13180
  this.expectKeyword("interface");
13181
- const name = this.parseName();
13181
+ const name2 = this.parseName();
13182
13182
  const interfaces = this.parseImplementsInterfaces();
13183
13183
  const directives = this.parseConstDirectives();
13184
13184
  const fields = this.parseFieldsDefinition();
13185
13185
  return this.node(start, {
13186
13186
  kind: kinds_ts_1.Kind.INTERFACE_TYPE_DEFINITION,
13187
13187
  description,
13188
- name,
13188
+ name: name2,
13189
13189
  interfaces,
13190
13190
  directives,
13191
13191
  fields
@@ -13195,13 +13195,13 @@ var require_parser2 = __commonJS((exports) => {
13195
13195
  const start = this._lexer.token;
13196
13196
  const description = this.parseDescription();
13197
13197
  this.expectKeyword("union");
13198
- const name = this.parseName();
13198
+ const name2 = this.parseName();
13199
13199
  const directives = this.parseConstDirectives();
13200
13200
  const types = this.parseUnionMemberTypes();
13201
13201
  return this.node(start, {
13202
13202
  kind: kinds_ts_1.Kind.UNION_TYPE_DEFINITION,
13203
13203
  description,
13204
- name,
13204
+ name: name2,
13205
13205
  directives,
13206
13206
  types
13207
13207
  });
@@ -13213,13 +13213,13 @@ var require_parser2 = __commonJS((exports) => {
13213
13213
  const start = this._lexer.token;
13214
13214
  const description = this.parseDescription();
13215
13215
  this.expectKeyword("enum");
13216
- const name = this.parseName();
13216
+ const name2 = this.parseName();
13217
13217
  const directives = this.parseConstDirectives();
13218
13218
  const values = this.parseEnumValuesDefinition();
13219
13219
  return this.node(start, {
13220
13220
  kind: kinds_ts_1.Kind.ENUM_TYPE_DEFINITION,
13221
13221
  description,
13222
- name,
13222
+ name: name2,
13223
13223
  directives,
13224
13224
  values
13225
13225
  });
@@ -13230,12 +13230,12 @@ var require_parser2 = __commonJS((exports) => {
13230
13230
  parseEnumValueDefinition() {
13231
13231
  const start = this._lexer.token;
13232
13232
  const description = this.parseDescription();
13233
- const name = this.parseEnumValueName();
13233
+ const name2 = this.parseEnumValueName();
13234
13234
  const directives = this.parseConstDirectives();
13235
13235
  return this.node(start, {
13236
13236
  kind: kinds_ts_1.Kind.ENUM_VALUE_DEFINITION,
13237
13237
  description,
13238
- name,
13238
+ name: name2,
13239
13239
  directives
13240
13240
  });
13241
13241
  }
@@ -13249,13 +13249,13 @@ var require_parser2 = __commonJS((exports) => {
13249
13249
  const start = this._lexer.token;
13250
13250
  const description = this.parseDescription();
13251
13251
  this.expectKeyword("input");
13252
- const name = this.parseName();
13252
+ const name2 = this.parseName();
13253
13253
  const directives = this.parseConstDirectives();
13254
13254
  const fields = this.parseInputFieldsDefinition();
13255
13255
  return this.node(start, {
13256
13256
  kind: kinds_ts_1.Kind.INPUT_OBJECT_TYPE_DEFINITION,
13257
13257
  description,
13258
- name,
13258
+ name: name2,
13259
13259
  directives,
13260
13260
  fields
13261
13261
  });
@@ -13306,14 +13306,14 @@ var require_parser2 = __commonJS((exports) => {
13306
13306
  const start = this._lexer.token;
13307
13307
  this.expectKeyword("extend");
13308
13308
  this.expectKeyword("scalar");
13309
- const name = this.parseName();
13309
+ const name2 = this.parseName();
13310
13310
  const directives = this.parseConstDirectives();
13311
13311
  if (directives === undefined) {
13312
13312
  throw this.unexpected();
13313
13313
  }
13314
13314
  return this.node(start, {
13315
13315
  kind: kinds_ts_1.Kind.SCALAR_TYPE_EXTENSION,
13316
- name,
13316
+ name: name2,
13317
13317
  directives
13318
13318
  });
13319
13319
  }
@@ -13321,7 +13321,7 @@ var require_parser2 = __commonJS((exports) => {
13321
13321
  const start = this._lexer.token;
13322
13322
  this.expectKeyword("extend");
13323
13323
  this.expectKeyword("type");
13324
- const name = this.parseName();
13324
+ const name2 = this.parseName();
13325
13325
  const interfaces = this.parseImplementsInterfaces();
13326
13326
  const directives = this.parseConstDirectives();
13327
13327
  const fields = this.parseFieldsDefinition();
@@ -13330,7 +13330,7 @@ var require_parser2 = __commonJS((exports) => {
13330
13330
  }
13331
13331
  return this.node(start, {
13332
13332
  kind: kinds_ts_1.Kind.OBJECT_TYPE_EXTENSION,
13333
- name,
13333
+ name: name2,
13334
13334
  interfaces,
13335
13335
  directives,
13336
13336
  fields
@@ -13340,7 +13340,7 @@ var require_parser2 = __commonJS((exports) => {
13340
13340
  const start = this._lexer.token;
13341
13341
  this.expectKeyword("extend");
13342
13342
  this.expectKeyword("interface");
13343
- const name = this.parseName();
13343
+ const name2 = this.parseName();
13344
13344
  const interfaces = this.parseImplementsInterfaces();
13345
13345
  const directives = this.parseConstDirectives();
13346
13346
  const fields = this.parseFieldsDefinition();
@@ -13349,7 +13349,7 @@ var require_parser2 = __commonJS((exports) => {
13349
13349
  }
13350
13350
  return this.node(start, {
13351
13351
  kind: kinds_ts_1.Kind.INTERFACE_TYPE_EXTENSION,
13352
- name,
13352
+ name: name2,
13353
13353
  interfaces,
13354
13354
  directives,
13355
13355
  fields
@@ -13359,7 +13359,7 @@ var require_parser2 = __commonJS((exports) => {
13359
13359
  const start = this._lexer.token;
13360
13360
  this.expectKeyword("extend");
13361
13361
  this.expectKeyword("union");
13362
- const name = this.parseName();
13362
+ const name2 = this.parseName();
13363
13363
  const directives = this.parseConstDirectives();
13364
13364
  const types = this.parseUnionMemberTypes();
13365
13365
  if (directives === undefined && types === undefined) {
@@ -13367,7 +13367,7 @@ var require_parser2 = __commonJS((exports) => {
13367
13367
  }
13368
13368
  return this.node(start, {
13369
13369
  kind: kinds_ts_1.Kind.UNION_TYPE_EXTENSION,
13370
- name,
13370
+ name: name2,
13371
13371
  directives,
13372
13372
  types
13373
13373
  });
@@ -13376,7 +13376,7 @@ var require_parser2 = __commonJS((exports) => {
13376
13376
  const start = this._lexer.token;
13377
13377
  this.expectKeyword("extend");
13378
13378
  this.expectKeyword("enum");
13379
- const name = this.parseName();
13379
+ const name2 = this.parseName();
13380
13380
  const directives = this.parseConstDirectives();
13381
13381
  const values = this.parseEnumValuesDefinition();
13382
13382
  if (directives === undefined && values === undefined) {
@@ -13384,7 +13384,7 @@ var require_parser2 = __commonJS((exports) => {
13384
13384
  }
13385
13385
  return this.node(start, {
13386
13386
  kind: kinds_ts_1.Kind.ENUM_TYPE_EXTENSION,
13387
- name,
13387
+ name: name2,
13388
13388
  directives,
13389
13389
  values
13390
13390
  });
@@ -13393,7 +13393,7 @@ var require_parser2 = __commonJS((exports) => {
13393
13393
  const start = this._lexer.token;
13394
13394
  this.expectKeyword("extend");
13395
13395
  this.expectKeyword("input");
13396
- const name = this.parseName();
13396
+ const name2 = this.parseName();
13397
13397
  const directives = this.parseConstDirectives();
13398
13398
  const fields = this.parseInputFieldsDefinition();
13399
13399
  if (directives === undefined && fields === undefined) {
@@ -13401,7 +13401,7 @@ var require_parser2 = __commonJS((exports) => {
13401
13401
  }
13402
13402
  return this.node(start, {
13403
13403
  kind: kinds_ts_1.Kind.INPUT_OBJECT_TYPE_EXTENSION,
13404
- name,
13404
+ name: name2,
13405
13405
  directives,
13406
13406
  fields
13407
13407
  });
@@ -13411,14 +13411,14 @@ var require_parser2 = __commonJS((exports) => {
13411
13411
  this.expectKeyword("extend");
13412
13412
  this.expectKeyword("directive");
13413
13413
  this.expectToken(tokenKind_ts_1.TokenKind.AT);
13414
- const name = this.parseName();
13414
+ const name2 = this.parseName();
13415
13415
  const directives = this.parseConstDirectives();
13416
13416
  if (directives === undefined) {
13417
13417
  throw this.unexpected();
13418
13418
  }
13419
13419
  return this.node(start, {
13420
13420
  kind: kinds_ts_1.Kind.DIRECTIVE_EXTENSION,
13421
- name,
13421
+ name: name2,
13422
13422
  directives
13423
13423
  });
13424
13424
  }
@@ -13427,7 +13427,7 @@ var require_parser2 = __commonJS((exports) => {
13427
13427
  const description = this.parseDescription();
13428
13428
  this.expectKeyword("directive");
13429
13429
  this.expectToken(tokenKind_ts_1.TokenKind.AT);
13430
- const name = this.parseName();
13430
+ const name2 = this.parseName();
13431
13431
  const args = this.parseArgumentDefs();
13432
13432
  const directives = this.parseConstDirectives();
13433
13433
  const repeatable = this.expectOptionalKeyword("repeatable");
@@ -13436,7 +13436,7 @@ var require_parser2 = __commonJS((exports) => {
13436
13436
  return this.node(start, {
13437
13437
  kind: kinds_ts_1.Kind.DIRECTIVE_DEFINITION,
13438
13438
  description,
13439
- name,
13439
+ name: name2,
13440
13440
  arguments: args,
13441
13441
  directives,
13442
13442
  repeatable,
@@ -13448,16 +13448,16 @@ var require_parser2 = __commonJS((exports) => {
13448
13448
  }
13449
13449
  parseDirectiveLocation() {
13450
13450
  const start = this._lexer.token;
13451
- const name = this.parseName();
13452
- if (Object.hasOwn(directiveLocation_ts_1.DirectiveLocation, name.value)) {
13453
- return name;
13451
+ const name2 = this.parseName();
13452
+ if (Object.hasOwn(directiveLocation_ts_1.DirectiveLocation, name2.value)) {
13453
+ return name2;
13454
13454
  }
13455
13455
  throw this.unexpected(start);
13456
13456
  }
13457
13457
  parseSchemaCoordinate() {
13458
13458
  const start = this._lexer.token;
13459
13459
  const ofDirective = this.expectOptionalToken(tokenKind_ts_1.TokenKind.AT);
13460
- const name = this.parseName();
13460
+ const name2 = this.parseName();
13461
13461
  let memberName;
13462
13462
  if (!ofDirective && this.expectOptionalToken(tokenKind_ts_1.TokenKind.DOT)) {
13463
13463
  memberName = this.parseName();
@@ -13472,32 +13472,32 @@ var require_parser2 = __commonJS((exports) => {
13472
13472
  if (argumentName) {
13473
13473
  return this.node(start, {
13474
13474
  kind: kinds_ts_1.Kind.DIRECTIVE_ARGUMENT_COORDINATE,
13475
- name,
13475
+ name: name2,
13476
13476
  argumentName
13477
13477
  });
13478
13478
  }
13479
13479
  return this.node(start, {
13480
13480
  kind: kinds_ts_1.Kind.DIRECTIVE_COORDINATE,
13481
- name
13481
+ name: name2
13482
13482
  });
13483
13483
  } else if (memberName) {
13484
13484
  if (argumentName) {
13485
13485
  return this.node(start, {
13486
13486
  kind: kinds_ts_1.Kind.ARGUMENT_COORDINATE,
13487
- name,
13487
+ name: name2,
13488
13488
  fieldName: memberName,
13489
13489
  argumentName
13490
13490
  });
13491
13491
  }
13492
13492
  return this.node(start, {
13493
13493
  kind: kinds_ts_1.Kind.MEMBER_COORDINATE,
13494
- name,
13494
+ name: name2,
13495
13495
  memberName
13496
13496
  });
13497
13497
  }
13498
13498
  return this.node(start, {
13499
13499
  kind: kinds_ts_1.Kind.TYPE_COORDINATE,
13500
- name
13500
+ name: name2
13501
13501
  });
13502
13502
  }
13503
13503
  node(startToken, node2) {
@@ -14414,20 +14414,20 @@ var require_KnownDirectivesRule = __commonJS((exports) => {
14414
14414
  const astDefinitions = context.getDocument().definitions;
14415
14415
  for (const def of astDefinitions) {
14416
14416
  if (def.kind === kinds_ts_1.Kind.DIRECTIVE_DEFINITION) {
14417
- locationsMap.set(def.name.value, def.locations.map((name) => name.value));
14417
+ locationsMap.set(def.name.value, def.locations.map((name2) => name2.value));
14418
14418
  }
14419
14419
  }
14420
14420
  return {
14421
14421
  Directive(node2, _key, _parent, _path, ancestors) {
14422
- const name = node2.name.value;
14423
- const locations = locationsMap.get(name);
14422
+ const name2 = node2.name.value;
14423
+ const locations = locationsMap.get(name2);
14424
14424
  if (locations == null) {
14425
- context.reportError(new GraphQLError_ts_1.GraphQLError(`Unknown directive "@${name}".`, { nodes: node2 }));
14425
+ context.reportError(new GraphQLError_ts_1.GraphQLError(`Unknown directive "@${name2}".`, { nodes: node2 }));
14426
14426
  return;
14427
14427
  }
14428
14428
  const candidateLocation = getDirectiveLocationForASTPath(ancestors);
14429
14429
  if (candidateLocation != null && !locations.includes(candidateLocation)) {
14430
- context.reportError(new GraphQLError_ts_1.GraphQLError(`Directive "@${name}" may not be used on ${candidateLocation}.`, { nodes: node2 }));
14430
+ context.reportError(new GraphQLError_ts_1.GraphQLError(`Directive "@${name2}" may not be used on ${candidateLocation}.`, { nodes: node2 }));
14431
14431
  }
14432
14432
  }
14433
14433
  };
@@ -15059,8 +15059,8 @@ var require_OverlappingFieldsCanBeMergedRule = __commonJS((exports) => {
15059
15059
  if (args1.length !== args2.length) {
15060
15060
  return false;
15061
15061
  }
15062
- const values2 = new Map(args2.map(({ name, value }) => [
15063
- name.value,
15062
+ const values2 = new Map(args2.map(({ name: name2, value }) => [
15063
+ name2.value,
15064
15064
  varMap2 === undefined ? value : replaceFragmentVariables(value, varMap2)
15065
15065
  ]));
15066
15066
  return args1.every((arg1) => {
@@ -15301,8 +15301,8 @@ var require_PossibleFragmentSpreadsRule = __commonJS((exports) => {
15301
15301
  }
15302
15302
  };
15303
15303
  }
15304
- function getFragmentType(context, name) {
15305
- const frag = context.getFragment(name);
15304
+ function getFragmentType(context, name2) {
15305
+ const frag = context.getFragment(name2);
15306
15306
  if (frag) {
15307
15307
  const type = (0, typeFromAST_ts_1.typeFromAST)(context.getSchema(), frag.typeCondition);
15308
15308
  if ((0, definition_ts_1.isCompositeType)(type)) {
@@ -15840,11 +15840,11 @@ var require_values = __commonJS((exports) => {
15840
15840
  }
15841
15841
  return { sources, coerced };
15842
15842
  }
15843
- function maybeUseDefaultValue(coercedValues, name, inputValue, onError, hideSuggestions) {
15843
+ function maybeUseDefaultValue(coercedValues, name2, inputValue, onError, hideSuggestions) {
15844
15844
  try {
15845
15845
  const coercedDefaultValue = (0, coerceInputValue_ts_1.coerceDefaultValue)(inputValue);
15846
15846
  if (coercedDefaultValue !== undefined) {
15847
- coercedValues[name] = coercedDefaultValue;
15847
+ coercedValues[name2] = coercedDefaultValue;
15848
15848
  }
15849
15849
  } catch (error62) {
15850
15850
  const defaultInput = inputValue.default;
@@ -15888,8 +15888,8 @@ var require_values = __commonJS((exports) => {
15888
15888
  const argumentNodes = node2.arguments ?? [];
15889
15889
  const argNodeMap = new Map(argumentNodes.map((arg) => [arg.name.value, arg]));
15890
15890
  for (const argDef of def.args) {
15891
- const name = argDef.name;
15892
- coerceArgument(coercedValues, node2, name, argDef, argNodeMap.get(argDef.name), variableValues, fragmentVariableValues, hideSuggestions);
15891
+ const name2 = argDef.name;
15892
+ coerceArgument(coercedValues, node2, name2, argDef, argNodeMap.get(argDef.name), variableValues, fragmentVariableValues, hideSuggestions);
15893
15893
  }
15894
15894
  return coercedValues;
15895
15895
  }
@@ -16840,7 +16840,7 @@ var require_ValidationContext = __commonJS((exports) => {
16840
16840
  getDocument() {
16841
16841
  return this._ast;
16842
16842
  }
16843
- getFragment(name) {
16843
+ getFragment(name2) {
16844
16844
  let fragments;
16845
16845
  if (this._fragments) {
16846
16846
  fragments = this._fragments;
@@ -16853,7 +16853,7 @@ var require_ValidationContext = __commonJS((exports) => {
16853
16853
  }
16854
16854
  this._fragments = fragments;
16855
16855
  }
16856
- return fragments[name];
16856
+ return fragments[name2];
16857
16857
  }
16858
16858
  getFragmentSpreads(node2) {
16859
16859
  let spreads = this._fragmentSpreads.get(node2);
@@ -21774,10 +21774,10 @@ var require_extendSchema = __commonJS((exports) => {
21774
21774
  return opTypes;
21775
21775
  }
21776
21776
  function namedTypeFromAST(node2) {
21777
- const name = node2.name.value;
21778
- const type = getNamedType(name);
21777
+ const name2 = node2.name.value;
21778
+ const type = getNamedType(name2);
21779
21779
  if (!(type !== undefined))
21780
- (0, invariant_ts_1.invariant)(false, `Unknown type: "${name}".`);
21780
+ (0, invariant_ts_1.invariant)(false, `Unknown type: "${name2}".`);
21781
21781
  return type;
21782
21782
  }
21783
21783
  function typeFromAST(node2) {
@@ -21884,13 +21884,13 @@ var require_extendSchema = __commonJS((exports) => {
21884
21884
  return nodes.flatMap((node2) => node2.types?.map(namedTypeFromAST) ?? []);
21885
21885
  }
21886
21886
  function buildNamedType(astNode) {
21887
- const name = astNode.name.value;
21887
+ const name2 = astNode.name.value;
21888
21888
  switch (astNode.kind) {
21889
21889
  case kinds_ts_1.Kind.OBJECT_TYPE_DEFINITION: {
21890
- const extensionASTNodes = objectExtensions.get(name) ?? [];
21890
+ const extensionASTNodes = objectExtensions.get(name2) ?? [];
21891
21891
  const allNodes = [astNode, ...extensionASTNodes];
21892
21892
  return new definition_ts_1.GraphQLObjectType({
21893
- name,
21893
+ name: name2,
21894
21894
  description: astNode.description?.value,
21895
21895
  interfaces: () => buildInterfaces(allNodes),
21896
21896
  fields: () => buildFieldMap(allNodes),
@@ -21899,10 +21899,10 @@ var require_extendSchema = __commonJS((exports) => {
21899
21899
  });
21900
21900
  }
21901
21901
  case kinds_ts_1.Kind.INTERFACE_TYPE_DEFINITION: {
21902
- const extensionASTNodes = interfaceExtensions.get(name) ?? [];
21902
+ const extensionASTNodes = interfaceExtensions.get(name2) ?? [];
21903
21903
  const allNodes = [astNode, ...extensionASTNodes];
21904
21904
  return new definition_ts_1.GraphQLInterfaceType({
21905
- name,
21905
+ name: name2,
21906
21906
  description: astNode.description?.value,
21907
21907
  interfaces: () => buildInterfaces(allNodes),
21908
21908
  fields: () => buildFieldMap(allNodes),
@@ -21911,10 +21911,10 @@ var require_extendSchema = __commonJS((exports) => {
21911
21911
  });
21912
21912
  }
21913
21913
  case kinds_ts_1.Kind.ENUM_TYPE_DEFINITION: {
21914
- const extensionASTNodes = enumExtensions.get(name) ?? [];
21914
+ const extensionASTNodes = enumExtensions.get(name2) ?? [];
21915
21915
  const allNodes = [astNode, ...extensionASTNodes];
21916
21916
  return new definition_ts_1.GraphQLEnumType({
21917
- name,
21917
+ name: name2,
21918
21918
  description: astNode.description?.value,
21919
21919
  values: () => buildEnumValueMap(allNodes),
21920
21920
  astNode,
@@ -21922,10 +21922,10 @@ var require_extendSchema = __commonJS((exports) => {
21922
21922
  });
21923
21923
  }
21924
21924
  case kinds_ts_1.Kind.UNION_TYPE_DEFINITION: {
21925
- const extensionASTNodes = unionExtensions.get(name) ?? [];
21925
+ const extensionASTNodes = unionExtensions.get(name2) ?? [];
21926
21926
  const allNodes = [astNode, ...extensionASTNodes];
21927
21927
  return new definition_ts_1.GraphQLUnionType({
21928
- name,
21928
+ name: name2,
21929
21929
  description: astNode.description?.value,
21930
21930
  types: () => buildUnionTypes(allNodes),
21931
21931
  astNode,
@@ -21933,13 +21933,13 @@ var require_extendSchema = __commonJS((exports) => {
21933
21933
  });
21934
21934
  }
21935
21935
  case kinds_ts_1.Kind.SCALAR_TYPE_DEFINITION: {
21936
- const extensionASTNodes = scalarExtensions.get(name) ?? [];
21936
+ const extensionASTNodes = scalarExtensions.get(name2) ?? [];
21937
21937
  let specifiedByURL = getSpecifiedByURL(astNode);
21938
21938
  for (const extensionNode of extensionASTNodes) {
21939
21939
  specifiedByURL = getSpecifiedByURL(extensionNode) ?? specifiedByURL;
21940
21940
  }
21941
21941
  return new definition_ts_1.GraphQLScalarType({
21942
- name,
21942
+ name: name2,
21943
21943
  description: astNode.description?.value,
21944
21944
  specifiedByURL,
21945
21945
  astNode,
@@ -21947,10 +21947,10 @@ var require_extendSchema = __commonJS((exports) => {
21947
21947
  });
21948
21948
  }
21949
21949
  case kinds_ts_1.Kind.INPUT_OBJECT_TYPE_DEFINITION: {
21950
- const extensionASTNodes = inputObjectExtensions.get(name) ?? [];
21950
+ const extensionASTNodes = inputObjectExtensions.get(name2) ?? [];
21951
21951
  const allNodes = [astNode, ...extensionASTNodes];
21952
21952
  return new definition_ts_1.GraphQLInputObjectType({
21953
- name,
21953
+ name: name2,
21954
21954
  description: astNode.description?.value,
21955
21955
  fields: () => buildInputFieldMap(allNodes),
21956
21956
  astNode,
@@ -22993,8 +22993,8 @@ var require_findSchemaChanges = __commonJS((exports) => {
22993
22993
  const added = [];
22994
22994
  const removed = [];
22995
22995
  const persisted = [];
22996
- const oldMap = (0, keyMap_ts_1.keyMap)(oldArray, ({ name }) => name);
22997
- const newMap = (0, keyMap_ts_1.keyMap)(newArray, ({ name }) => name);
22996
+ const oldMap = (0, keyMap_ts_1.keyMap)(oldArray, ({ name: name2 }) => name2);
22997
+ const newMap = (0, keyMap_ts_1.keyMap)(newArray, ({ name: name2 }) => name2);
22998
22998
  for (const oldItem of oldArray) {
22999
22999
  const newItem = newMap[oldItem.name];
23000
23000
  if (newItem === undefined) {
@@ -24030,10 +24030,12 @@ var require___dev__ = __commonJS((exports, module) => {
24030
24030
  enableDevMode();
24031
24031
  module.exports = require_graphql2();
24032
24032
  });
24033
+
24033
24034
  // package.json
24034
- var version = "0.3.1";
24035
+ var name = "@abyssinia-labs/sokie";
24036
+ var version = "0.4.0-staging.123";
24035
24037
  var sokie = {
24036
- site: "https://sokie.sh"
24038
+ site: "https://staging.sokie.sh"
24037
24039
  };
24038
24040
 
24039
24041
  // src/command.ts
@@ -24055,7 +24057,7 @@ function parseCommandArgs(argv, options) {
24055
24057
  }
24056
24058
  }
24057
24059
  async function fail(out, code, message, exit) {
24058
- await out.problem(`✗ ${message}`);
24060
+ await out.problem(`✗ ${message}`, "fail");
24059
24061
  await out.result({ ok: false, error: { code, message } });
24060
24062
  return exit;
24061
24063
  }
@@ -24066,6 +24068,9 @@ function splitGlobalFlags(argv) {
24066
24068
  return { json: head.includes("--json"), rest: [...head.filter((a) => a !== "--json"), ...tail] };
24067
24069
  }
24068
24070
 
24071
+ // src/tint.ts
24072
+ var plain = (_tone, text) => text;
24073
+
24069
24074
  // src/logs.ts
24070
24075
  var OUTCOME = {
24071
24076
  ok: "ok",
@@ -24075,26 +24080,40 @@ var OUTCOME = {
24075
24080
  rateLimited: "rate limited",
24076
24081
  failed: "failed"
24077
24082
  };
24083
+ var OUTCOME_TONE = {
24084
+ ok: "ok",
24085
+ toolError: "fail",
24086
+ refused: "warn",
24087
+ paused: "warn",
24088
+ rateLimited: "warn",
24089
+ failed: "fail"
24090
+ };
24091
+ var OUTCOME_WIDTH = 12;
24078
24092
  var two = (n) => String(n).padStart(2, "0");
24079
24093
  function stamp(at) {
24080
24094
  const d = new Date(at);
24081
24095
  return `${d.getFullYear()}-${two(d.getMonth() + 1)}-${two(d.getDate())} ${two(d.getHours())}:${two(d.getMinutes())}:${two(d.getSeconds())}`;
24082
24096
  }
24083
- function logLine(entry) {
24097
+ function logLine(entry, tint = plain) {
24084
24098
  const error = [entry.errorClass, entry.upstreamStatus].filter((part) => part !== undefined);
24085
24099
  const extra = [
24086
24100
  error.length > 0 ? error.join(" ") : null,
24087
24101
  entry.client ?? null,
24088
24102
  entry.preview !== undefined ? `preview #${entry.preview}` : null
24089
24103
  ].filter((part) => part !== null);
24090
- return [
24104
+ const tone = OUTCOME_TONE[entry.outcome];
24105
+ const failed = tone === "fail";
24106
+ const outcome = OUTCOME[entry.outcome];
24107
+ const cell = `${failed ? outcome : tint(tone, outcome)}${" ".repeat(OUTCOME_WIDTH - outcome.length)}`;
24108
+ const line = [
24091
24109
  stamp(entry.at),
24092
- OUTCOME[entry.outcome].padEnd(12),
24110
+ cell,
24093
24111
  String(entry.status).padStart(3),
24094
24112
  `${entry.durationMs}ms`.padStart(7),
24095
24113
  ` ${(entry.tool ?? entry.method ?? "-").padEnd(24)}`,
24096
24114
  extra.join(" ")
24097
24115
  ].join(" ").trimEnd();
24116
+ return failed ? tint("fail", line) : line;
24098
24117
  }
24099
24118
  function liveLine(deployment) {
24100
24119
  if (deployment.number === undefined)
@@ -24571,14 +24590,14 @@ function getFunctionName(functionReference) {
24571
24590
  }
24572
24591
  if (typeof functionReference === "string")
24573
24592
  return functionReference;
24574
- const name = functionReference[functionName];
24575
- if (!name) {
24593
+ const name2 = functionReference[functionName];
24594
+ if (!name2) {
24576
24595
  throw new Error(`${functionReference} is not a functionReference`);
24577
24596
  }
24578
- return name;
24597
+ return name2;
24579
24598
  }
24580
- function makeFunctionReference(name) {
24581
- return { [functionName]: name };
24599
+ function makeFunctionReference(name2) {
24600
+ return { [functionName]: name2 };
24582
24601
  }
24583
24602
  function createApi(pathParts = []) {
24584
24603
  const handler = {
@@ -24620,9 +24639,9 @@ var AUDIT_CATEGORIES = [
24620
24639
  "workspace",
24621
24640
  "billing"
24622
24641
  ];
24623
- var query = (name) => makeFunctionReference(name);
24624
- var mutation = (name) => makeFunctionReference(name);
24625
- var action = (name) => makeFunctionReference(name);
24642
+ var query = (name2) => makeFunctionReference(name2);
24643
+ var mutation = (name2) => makeFunctionReference(name2);
24644
+ var action = (name2) => makeFunctionReference(name2);
24626
24645
  var fn = {
24627
24646
  me: query("account:me"),
24628
24647
  serverBySlug: query("servers:bySlug"),
@@ -24630,6 +24649,13 @@ var fn = {
24630
24649
  sourceUploadUrl: mutation("deployments:sourceUploadUrl"),
24631
24650
  startDeploy: mutation("deployments:start"),
24632
24651
  deployment: query("deployments:get"),
24652
+ deployments: query("deployments:forServer"),
24653
+ deployByNumber: query("deployDiffs:byNumber"),
24654
+ server: query("servers:get"),
24655
+ serverFiles: query("serverFiles:download"),
24656
+ restoreCheck: query("restores:check"),
24657
+ restore: mutation("restores:start"),
24658
+ resume: mutation("restores:resume"),
24633
24659
  keyServer: query("deployKeys:keyServer"),
24634
24660
  secrets: query("secrets:list"),
24635
24661
  logs: query("callLogs:recent"),
@@ -24651,8 +24677,8 @@ var fn = {
24651
24677
 
24652
24678
  // src/audit.ts
24653
24679
  var TYPE_NAMES = AUDIT_CATEGORIES.map((category) => category.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`));
24654
- function auditType(name) {
24655
- const index = TYPE_NAMES.indexOf(name.trim().toLowerCase());
24680
+ function auditType(name2) {
24681
+ const index = TYPE_NAMES.indexOf(name2.trim().toLowerCase());
24656
24682
  return index === -1 ? null : AUDIT_CATEGORIES[index] ?? null;
24657
24683
  }
24658
24684
  function auditActor(actor) {
@@ -24662,9 +24688,9 @@ function auditActor(actor) {
24662
24688
  return `deploy key ${actor.name}`;
24663
24689
  return actor.name;
24664
24690
  }
24665
- function auditLine(entry) {
24691
+ function auditLine(entry, tint = plain) {
24666
24692
  const where = entry.network?.ip ? ` ${entry.network.ip}` : "";
24667
- return `${stamp(entry.at)} ${entry.summary} · ${auditActor(entry.actor)}${where}`;
24693
+ return `${stamp(entry.at)} ${entry.summary} ${tint("dim", `· ${auditActor(entry.actor)}${where}`)}`;
24668
24694
  }
24669
24695
 
24670
24696
  // ../../node_modules/yaml/dist/index.js
@@ -24863,14 +24889,14 @@ for (const word of "send email mail notify invite publish charge pay refund tran
24863
24889
  }
24864
24890
  var SEVERITY = { read: 0, write: 1, delete: 2, external_effect: 3 };
24865
24891
  var BOUNDING = /^(limit|max(_?results)?|per_?page|page_?size|size|count|top|first|last|take|skip|offset|page|page_?token|next_?token|cursor|after|before|starting_?after|ending_?before)$/i;
24866
- function words(name) {
24867
- return name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map((word) => word.toLowerCase());
24892
+ function words(name2) {
24893
+ return name2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).filter(Boolean).map((word) => word.toLowerCase());
24868
24894
  }
24869
24895
  function singular(word) {
24870
24896
  return word.length > 3 && word.endsWith("s") && !word.endsWith("ss") ? word.slice(0, -1) : word;
24871
24897
  }
24872
- function nameKey(name) {
24873
- return words(name).map(singular).join(" ");
24898
+ function nameKey(name2) {
24899
+ return words(name2).map(singular).join(" ");
24874
24900
  }
24875
24901
  function finding(rule, file, problem) {
24876
24902
  const { level, fix } = USABILITY_RULES[rule];
@@ -24943,9 +24969,9 @@ function stemOf(path, dir) {
24943
24969
  }
24944
24970
  function caseCollisions(names) {
24945
24971
  const groups = new Map;
24946
- for (const name of names) {
24947
- const key = name.toLowerCase();
24948
- groups.set(key, [...groups.get(key) ?? [], name]);
24972
+ for (const name2 of names) {
24973
+ const key = name2.toLowerCase();
24974
+ groups.set(key, [...groups.get(key) ?? [], name2]);
24949
24975
  }
24950
24976
  return [...groups.values()].filter((group) => group.length > 1);
24951
24977
  }
@@ -24962,11 +24988,11 @@ function defaultToolNames(index) {
24962
24988
  if (op.excluded)
24963
24989
  continue;
24964
24990
  const base = defaultToolName(op);
24965
- let name = base;
24966
- for (let n = 2;taken.has(name.toLowerCase()); n++)
24967
- name = `${base.slice(0, 60)}${n}`;
24968
- taken.add(name.toLowerCase());
24969
- names.set(op.key, name);
24991
+ let name2 = base;
24992
+ for (let n = 2;taken.has(name2.toLowerCase()); n++)
24993
+ name2 = `${base.slice(0, 60)}${n}`;
24994
+ taken.add(name2.toLowerCase());
24995
+ names.set(op.key, name2);
24970
24996
  }
24971
24997
  return names;
24972
24998
  }
@@ -26053,12 +26079,12 @@ function merge(a, b) {
26053
26079
  });
26054
26080
  return clone(a, def);
26055
26081
  }
26056
- function partial(Class, schema, mask, name = "partial") {
26082
+ function partial(Class, schema, mask, name2 = "partial") {
26057
26083
  const currDef = schema._zod.def;
26058
26084
  const checks = currDef.checks;
26059
26085
  const hasChecks = checks && checks.length > 0;
26060
26086
  if (hasChecks) {
26061
- throw new Error(`.${name}() cannot be used on object schemas containing refinements`);
26087
+ throw new Error(`.${name2}() cannot be used on object schemas containing refinements`);
26062
26088
  }
26063
26089
  const def = mergeDefs(schema._zod.def, {
26064
26090
  get shape() {
@@ -26411,7 +26437,7 @@ function newError(Definition) {
26411
26437
  }
26412
26438
  return new Definition;
26413
26439
  }
26414
- function $constructor(name, initializer, proto, params) {
26440
+ function $constructor(name2, initializer, proto, params) {
26415
26441
  const zodProto = {};
26416
26442
  function Internals(def) {
26417
26443
  this.def = def;
@@ -26430,10 +26456,10 @@ function $constructor(name, initializer, proto, params) {
26430
26456
  _zodDesc.value = undefined;
26431
26457
  }
26432
26458
  }
26433
- if (inst._zod.traits.has(name)) {
26459
+ if (inst._zod.traits.has(name2)) {
26434
26460
  return;
26435
26461
  }
26436
- inst._zod.traits.add(name);
26462
+ inst._zod.traits.add(name2);
26437
26463
  initializer(inst, def);
26438
26464
  if (initialized) {
26439
26465
  const own2 = Object.getPrototypeOf(inst);
@@ -26460,7 +26486,7 @@ function $constructor(name, initializer, proto, params) {
26460
26486
 
26461
26487
  class Definition extends Parent {
26462
26488
  }
26463
- Object.defineProperty(Definition, "name", { value: name });
26489
+ Object.defineProperty(Definition, "name", { value: name2 });
26464
26490
  function _(def) {
26465
26491
  const inst = params?.Parent ? newError(Definition) : this;
26466
26492
  init(inst, def);
@@ -26481,10 +26507,10 @@ function $constructor(name, initializer, proto, params) {
26481
26507
  value: (inst) => {
26482
26508
  if (params?.Parent && inst instanceof params.Parent)
26483
26509
  return true;
26484
- return inst?._zod?.traits?.has(name);
26510
+ return inst?._zod?.traits?.has(name2);
26485
26511
  }
26486
26512
  });
26487
- Object.defineProperty(_, "name", { value: name });
26513
+ Object.defineProperty(_, "name", { value: name2 });
26488
26514
  return _;
26489
26515
  }
26490
26516
  var $brand = /* @__PURE__ */ Symbol("zod_brand");
@@ -26496,8 +26522,8 @@ class $ZodAsyncError extends Error {
26496
26522
  }
26497
26523
 
26498
26524
  class $ZodEncodeError extends Error {
26499
- constructor(name) {
26500
- super(`Encountered unidirectional transform during encode: ${name}`);
26525
+ constructor(name2) {
26526
+ super(`Encountered unidirectional transform during encode: ${name2}`);
26501
26527
  this.name = "ZodEncodeError";
26502
26528
  }
26503
26529
  }
@@ -37521,13 +37547,13 @@ ${code2}
37521
37547
  return fn2;
37522
37548
  }
37523
37549
  function addConstant(ctx, value) {
37524
- for (const [name2, v] of ctx.constants) {
37550
+ for (const [name3, v] of ctx.constants) {
37525
37551
  if (v === value)
37526
- return name2;
37552
+ return name3;
37527
37553
  }
37528
- const name = `c${ctx.constantCounter++}`;
37529
- ctx.constants.set(name, value);
37530
- return name;
37554
+ const name2 = `c${ctx.constantCounter++}`;
37555
+ ctx.constants.set(name2, value);
37556
+ return name2;
37531
37557
  }
37532
37558
  function newVar(ctx) {
37533
37559
  return `v${ctx.varCounter++}`;
@@ -43610,9 +43636,9 @@ var resourceFrontmatter = exports_external.strictObject({
43610
43636
  function templatePlaceholders(template) {
43611
43637
  const names = new Set;
43612
43638
  for (const match of template.matchAll(/\{\{\s*([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g)) {
43613
- const name = match[1];
43614
- if (name)
43615
- names.add(name);
43639
+ const name2 = match[1];
43640
+ if (name2)
43641
+ names.add(name2);
43616
43642
  }
43617
43643
  return [...names];
43618
43644
  }
@@ -43751,10 +43777,10 @@ function declaredBaseUrl(doc2, sourceUrl) {
43751
43777
  if (!isRecord2(server) || !url2)
43752
43778
  return null;
43753
43779
  if (isRecord2(server.variables)) {
43754
- for (const [name, variable] of Object.entries(server.variables)) {
43780
+ for (const [name2, variable] of Object.entries(server.variables)) {
43755
43781
  const fallback = isRecord2(variable) ? text(variable.default) : null;
43756
43782
  if (fallback)
43757
- url2 = url2.replaceAll(`{${name}}`, fallback);
43783
+ url2 = url2.replaceAll(`{${name2}}`, fallback);
43758
43784
  }
43759
43785
  }
43760
43786
  if (/^[a-z][a-z0-9+.-]*:\/\//i.test(url2) || !sourceUrl)
@@ -43792,8 +43818,8 @@ function schemaIsList(doc2, raw) {
43792
43818
  if (schema.type === "array")
43793
43819
  return true;
43794
43820
  const properties = isRecord3(schema.properties) ? schema.properties : {};
43795
- return LIST_ENVELOPES.some((name) => {
43796
- const property = deref(doc2, properties[name]);
43821
+ return LIST_ENVELOPES.some((name2) => {
43822
+ const property = deref(doc2, properties[name2]);
43797
43823
  return isRecord3(property) && property.type === "array";
43798
43824
  });
43799
43825
  }
@@ -44018,7 +44044,7 @@ function newToolRisk(op) {
44018
44044
  var SERVER_SCHEMA_VERSION = 1;
44019
44045
  var SERVER_CONFIG_FILE = "sokie.json";
44020
44046
  var SERVER_SCHEMA_URL = "https://sokie.sh/schema/server.v1.json";
44021
- var secretName = exports_external.string().regex(SECRET_NAME, "Secret names are UPPER_SNAKE_CASE").refine((name) => !name.startsWith("SOKIE_"), "Names starting with SOKIE_ are reserved for the platform");
44047
+ var secretName = exports_external.string().regex(SECRET_NAME, "Secret names are UPPER_SNAKE_CASE").refine((name2) => !name2.startsWith("SOKIE_"), "Names starting with SOKIE_ are reserved for the platform");
44022
44048
  var secretRef = exports_external.strictObject({ secret: secretName });
44023
44049
  var httpsUrl = exports_external.url({ protocol: /^https?$/, error: "Must be an http(s) URL" });
44024
44050
  var sourceConfig = exports_external.strictObject({
@@ -44139,17 +44165,17 @@ function planInit(input2) {
44139
44165
  const toolFor = new Map;
44140
44166
  const names = namesFor(facts.operations);
44141
44167
  for (const op of included) {
44142
- const name = names.get(op.key);
44143
- if (!name)
44168
+ const name2 = names.get(op.key);
44169
+ if (!name2)
44144
44170
  continue;
44145
44171
  const text2 = toolText(op, input2.choices?.get(op.key));
44146
44172
  if (typeof text2 !== "string") {
44147
- problems.push(`${name}: ${text2.problem}`);
44173
+ problems.push(`${name2}: ${text2.problem}`);
44148
44174
  continue;
44149
44175
  }
44150
- files.set(`tools/${name}.md`, text2);
44151
- tools.push(name);
44152
- toolFor.set(op.key, name);
44176
+ files.set(`tools/${name2}.md`, text2);
44177
+ tools.push(name2);
44178
+ toolFor.set(op.key, name2);
44153
44179
  }
44154
44180
  const left = facts.operations.length - included.length;
44155
44181
  if (left > 0) {
@@ -44184,8 +44210,8 @@ function sendable(scheme) {
44184
44210
  function chosenScheme(doc2) {
44185
44211
  const schemes = schemesOf(doc2);
44186
44212
  const applied = Array.isArray(doc2.security) && isRecord5(doc2.security[0]) ? doc2.security[0] : {};
44187
- const name = Object.keys(applied)[0] ?? Object.keys(schemes).find((key) => sendable(schemes[key])) ?? Object.keys(schemes)[0];
44188
- const scheme = name ? schemes[name] : undefined;
44213
+ const name2 = Object.keys(applied)[0] ?? Object.keys(schemes).find((key) => sendable(schemes[key])) ?? Object.keys(schemes)[0];
44214
+ const scheme = name2 ? schemes[name2] : undefined;
44189
44215
  return isRecord5(scheme) ? scheme : null;
44190
44216
  }
44191
44217
  function upstreamAuthFor(doc2) {
@@ -44194,9 +44220,9 @@ function upstreamAuthFor(doc2) {
44194
44220
  return { auth: null, note: null };
44195
44221
  const type = text2(scheme.type)?.toLowerCase();
44196
44222
  const where = text2(scheme.in);
44197
- const name = text2(scheme.name);
44198
- if (type === "apikey" && (where === "header" || where === "query") && name) {
44199
- return { auth: { type: "apiKey", in: where, name, key: "perCaller" }, note: null };
44223
+ const name2 = text2(scheme.name);
44224
+ if (type === "apikey" && (where === "header" || where === "query") && name2) {
44225
+ return { auth: { type: "apiKey", in: where, name: name2, key: "perCaller" }, note: null };
44200
44226
  }
44201
44227
  if (type === "http" && text2(scheme.scheme)?.toLowerCase() === "bearer") {
44202
44228
  return {
@@ -44510,13 +44536,13 @@ function loadCases(files, findings) {
44510
44536
  for (const [file2, content] of files) {
44511
44537
  if (!file2.startsWith(`${TESTS_DIR}/`))
44512
44538
  continue;
44513
- const name = caseStem(file2);
44514
- if (name === null) {
44539
+ const name2 = caseStem(file2);
44540
+ if (name2 === null) {
44515
44541
  findings.push(warning(file2, "stray-file", "Only `tests/<name>.json` files are read; this one is ignored."));
44516
44542
  continue;
44517
44543
  }
44518
- if (!TOOL_NAME.test(name)) {
44519
- findings.push(error(file2, "invalid-name", `"${name}" is not a valid case name: start with a letter, then letters, digits, _ or -, 64 at most.`));
44544
+ if (!TOOL_NAME.test(name2)) {
44545
+ findings.push(error(file2, "invalid-name", `"${name2}" is not a valid case name: start with a letter, then letters, digits, _ or -, 64 at most.`));
44520
44546
  continue;
44521
44547
  }
44522
44548
  let raw;
@@ -44532,7 +44558,7 @@ function loadCases(files, findings) {
44532
44558
  findings.push(...issuesToFindings(file2, parsed.error.issues));
44533
44559
  continue;
44534
44560
  }
44535
- cases.push({ name, file: file2, data: parsed.data });
44561
+ cases.push({ name: name2, file: file2, data: parsed.data });
44536
44562
  }
44537
44563
  for (const group of caseCollisions(cases.map((item) => item.name))) {
44538
44564
  findings.push(error(TESTS_DIR, "case-collision", `${group.join(" and ")} differ only in case; macOS and Windows checkouts keep one of them.`));
@@ -44542,16 +44568,16 @@ function loadCases(files, findings) {
44542
44568
  function defaultTargets(tool) {
44543
44569
  return tool.enforcedRisk === "read" ? ["dev", "preview", "production"] : ["dev", "preview"];
44544
44570
  }
44545
- function unknownToolMessage(name, tools) {
44546
- const lower = name.toLowerCase();
44571
+ function unknownToolMessage(name2, tools) {
44572
+ const lower = name2.toLowerCase();
44547
44573
  const near = tools.find((tool) => tool.name.toLowerCase() === lower || tool.name.toLowerCase().startsWith(lower) || lower.startsWith(tool.name.toLowerCase()));
44548
44574
  const hint = near ? ` Did you mean ${near.name}?` : "";
44549
- return `No tool named ${name} in tools/.${hint} Point the case at a tool's file name, or add the tool.`;
44575
+ return `No tool named ${name2} in tools/.${hint} Point the case at a tool's file name, or add the tool.`;
44550
44576
  }
44551
44577
  function checkCases(loaded, tools, toolFiles, findings) {
44552
44578
  const byName2 = new Map(tools.map((tool) => [tool.name, tool]));
44553
44579
  const cases = [];
44554
- for (const { name, file: file2, data } of loaded) {
44580
+ for (const { name: name2, file: file2, data } of loaded) {
44555
44581
  const tool = byName2.get(data.tool);
44556
44582
  if (!tool) {
44557
44583
  if (toolFiles.has(data.tool))
@@ -44561,7 +44587,7 @@ function checkCases(loaded, tools, toolFiles, findings) {
44561
44587
  }
44562
44588
  const on = data.on ? [...new Set(data.on)] : defaultTargets(tool);
44563
44589
  cases.push({
44564
- name,
44590
+ name: name2,
44565
44591
  file: file2,
44566
44592
  ...data.description ? { description: data.description } : {},
44567
44593
  tool: tool.name,
@@ -44577,7 +44603,7 @@ var UNEXPOSED_SAMPLE = 5;
44577
44603
  function checkTools(tools, config2, index, findings) {
44578
44604
  const resolved = [];
44579
44605
  const boundBy = new Map;
44580
- for (const { name, file: file2, data, body } of tools) {
44606
+ for (const { name: name2, file: file2, data, body } of tools) {
44581
44607
  const key = normaliseOperation(data.operation);
44582
44608
  const operation = index.operations.get(key);
44583
44609
  if (!operation) {
@@ -44602,7 +44628,7 @@ function checkTools(tools, config2, index, findings) {
44602
44628
  findings.push(error(file2, "auth-without-oauth", `\`auth: ${data.auth}\` only means something when \`upstream.auth\` is OAuth.`));
44603
44629
  }
44604
44630
  resolved.push({
44605
- name,
44631
+ name: name2,
44606
44632
  file: file2,
44607
44633
  operation: key,
44608
44634
  title: data.title,
@@ -44642,13 +44668,13 @@ function loadDir(files, dir, schema, findings) {
44642
44668
  for (const [file2, content] of files) {
44643
44669
  if (!file2.startsWith(`${dir}/`))
44644
44670
  continue;
44645
- const name = stemOf(file2, dir);
44646
- if (name === null) {
44671
+ const name2 = stemOf(file2, dir);
44672
+ if (name2 === null) {
44647
44673
  findings.push(warning(file2, "stray-file", `Only \`${dir}/<name>.md\` files are read; this one is ignored.`));
44648
44674
  continue;
44649
44675
  }
44650
- if (!TOOL_NAME.test(name)) {
44651
- findings.push(error(file2, "invalid-name", `"${name}" is not a valid name: start with a letter, then letters, digits, _ or -, 64 at most.`));
44676
+ if (!TOOL_NAME.test(name2)) {
44677
+ findings.push(error(file2, "invalid-name", `"${name2}" is not a valid name: start with a letter, then letters, digits, _ or -, 64 at most.`));
44652
44678
  continue;
44653
44679
  }
44654
44680
  const split = splitFrontmatter(content);
@@ -44662,7 +44688,7 @@ function loadDir(files, dir, schema, findings) {
44662
44688
  findings.push(...issuesToFindings(file2, parsed.error.issues));
44663
44689
  continue;
44664
44690
  }
44665
- items.push({ name, file: file2, data: parsed.data, body: split.file.body });
44691
+ items.push({ name: name2, file: file2, data: parsed.data, body: split.file.body });
44666
44692
  }
44667
44693
  for (const group of caseCollisions(items.map((item) => item.name))) {
44668
44694
  findings.push(error(dir, "case-collision", `${group.join(" and ")} differ only in case; macOS and Windows checkouts keep one of them.`));
@@ -44680,7 +44706,7 @@ function loadTools(files, findings) {
44680
44706
  }
44681
44707
  function loadPrompts(files, findings) {
44682
44708
  const prompts = loadDir(files, "prompts", promptFrontmatter, findings);
44683
- return prompts.map(({ name, file: file2, data, body }) => {
44709
+ return prompts.map(({ name: name2, file: file2, data, body }) => {
44684
44710
  const declared = new Set((data.arguments ?? []).map((arg) => arg.name));
44685
44711
  const used = new Set(templatePlaceholders(body));
44686
44712
  for (const placeholder of used) {
@@ -44695,7 +44721,7 @@ function loadPrompts(files, findings) {
44695
44721
  if (body === "")
44696
44722
  findings.push(error(file2, "missing-template", "The body is the prompt's template; it is empty."));
44697
44723
  return {
44698
- name,
44724
+ name: name2,
44699
44725
  file: file2,
44700
44726
  title: data.title,
44701
44727
  description: data.description,
@@ -44714,8 +44740,8 @@ function loadResources(files, findings) {
44714
44740
  }
44715
44741
  seen.set(resource.data.uri, resource.file);
44716
44742
  }
44717
- return resources.map(({ name, file: file2, data, body }) => ({
44718
- name,
44743
+ return resources.map(({ name: name2, file: file2, data, body }) => ({
44744
+ name: name2,
44719
44745
  file: file2,
44720
44746
  uri: data.uri,
44721
44747
  title: data.title,
@@ -44735,14 +44761,14 @@ function unexposedOperations(index, tools) {
44735
44761
  if (op.excluded || bound.has(op.key))
44736
44762
  continue;
44737
44763
  const base = names.get(op.key) ?? op.key;
44738
- let name = base;
44739
- for (let n = 2;taken.has(name.toLowerCase()); n++)
44740
- name = `${base.slice(0, 60)}${n}`;
44741
- taken.add(name.toLowerCase());
44764
+ let name2 = base;
44765
+ for (let n = 2;taken.has(name2.toLowerCase()); n++)
44766
+ name2 = `${base.slice(0, 60)}${n}`;
44767
+ taken.add(name2.toLowerCase());
44742
44768
  unexposed.push({
44743
44769
  operation: op.key,
44744
44770
  specName: op.specName,
44745
- name,
44771
+ name: name2,
44746
44772
  floor: op.floor,
44747
44773
  summary: op.summary,
44748
44774
  description: op.description
@@ -44800,15 +44826,15 @@ function loadSource(files, config2, findings) {
44800
44826
  function checkSecrets(config2, findings) {
44801
44827
  const declared = new Set(Object.keys(config2.secrets));
44802
44828
  const used = new Set;
44803
- for (const { name, at } of secretRefsIn(config2)) {
44804
- used.add(name);
44805
- if (!declared.has(name)) {
44806
- findings.push(error("sokie.json", "undeclared-secret", `${at} refers to the secret ${name}, which is not declared under \`secrets\`.`));
44829
+ for (const { name: name2, at } of secretRefsIn(config2)) {
44830
+ used.add(name2);
44831
+ if (!declared.has(name2)) {
44832
+ findings.push(error("sokie.json", "undeclared-secret", `${at} refers to the secret ${name2}, which is not declared under \`secrets\`.`));
44807
44833
  }
44808
44834
  }
44809
- for (const name of declared) {
44810
- if (!used.has(name))
44811
- findings.push(warning("sokie.json", "unused-secret", `The secret ${name} is declared but nothing refers to it.`));
44835
+ for (const name2 of declared) {
44836
+ if (!used.has(name2))
44837
+ findings.push(warning("sokie.json", "unused-secret", `The secret ${name2} is declared but nothing refers to it.`));
44812
44838
  }
44813
44839
  }
44814
44840
  function checkBaseUrl(config2, index, findings) {
@@ -44909,6 +44935,12 @@ function refusal(error62) {
44909
44935
  if (error62 instanceof ConvexError && error62.data === "DEPLOY_IN_PROGRESS") {
44910
44936
  throw new DeployError("deploy_in_progress", IN_PROGRESS_MESSAGE);
44911
44937
  }
44938
+ const data = error62 instanceof ConvexError ? error62.data : null;
44939
+ if (typeof data === "object" && data !== null && "code" in data && data.code === "STALE_BASE") {
44940
+ const live = "live" in data ? String(data.live) : "?";
44941
+ const base = "base" in data ? String(data.base) : "?";
44942
+ throw new DeployError("stale_base", `Production is #${live} now, but these files came from #${base}, so deploying them would undo what changed since. Run sokie pull to bring them up to date, or sokie deploy --force to deploy these as they are.`);
44943
+ }
44912
44944
  throw error62;
44913
44945
  }
44914
44946
  function sourceArchive(files) {
@@ -44930,7 +44962,14 @@ async function serverBySlug(platform, slug) {
44930
44962
  async function deployArchive(platform, serverId, archive, options) {
44931
44963
  const { key, url: url2 } = await platform.mutation(fn.sourceUploadUrl, { serverId }).catch(refusal);
44932
44964
  await platform.upload(url2, archive);
44933
- const deploymentId = await platform.mutation(fn.startDeploy, { serverId, sourceKey: key }).catch(refusal);
44965
+ const deploymentId = await platform.mutation(fn.startDeploy, {
44966
+ serverId,
44967
+ sourceKey: key,
44968
+ ...options.base === undefined ? {} : { base: options.base }
44969
+ }).catch(refusal);
44970
+ return await followDeploy(platform, deploymentId, options);
44971
+ }
44972
+ async function followDeploy(platform, deploymentId, options) {
44934
44973
  let last = null;
44935
44974
  const deadline = Date.now() + WAIT_MS;
44936
44975
  for (;; ) {
@@ -44979,11 +45018,11 @@ async function refused(response) {
44979
45018
  const description = typeof body.error_description === "string" ? body.error_description : response.statusText;
44980
45019
  return new OAuthError(code2, description);
44981
45020
  }
44982
- async function registerClient(info2, name, fetchFn = fetch) {
45021
+ async function registerClient(info2, name2, fetchFn = fetch) {
44983
45022
  const response = await fetchFn(info2.registrationEndpoint, {
44984
45023
  method: "POST",
44985
45024
  headers: { "content-type": "application/json" },
44986
- body: JSON.stringify({ client_name: name, redirect_uris: [REGISTERED_REDIRECT] })
45025
+ body: JSON.stringify({ client_name: name2, redirect_uris: [REGISTERED_REDIRECT] })
44987
45026
  });
44988
45027
  if (!response.ok)
44989
45028
  throw await refused(response);
@@ -45322,7 +45361,7 @@ class ConvexHttpClient {
45322
45361
  return await this.queryInner(query2, queryArgs, {});
45323
45362
  }
45324
45363
  async queryInner(query2, queryArgs, options) {
45325
- const name = getFunctionName(query2);
45364
+ const name2 = getFunctionName(query2);
45326
45365
  const args = [convexToJson(queryArgs)];
45327
45366
  const headers = {
45328
45367
  "Content-Type": "application/json",
@@ -45336,7 +45375,7 @@ class ConvexHttpClient {
45336
45375
  const localFetch = this.fetch || specifiedFetch || fetch;
45337
45376
  const timestamp = options.timestampPromise ? await options.timestampPromise : undefined;
45338
45377
  const body = JSON.stringify({
45339
- path: name,
45378
+ path: name2,
45340
45379
  format: "convex_encoded_json",
45341
45380
  args,
45342
45381
  ...timestamp ? { ts: timestamp } : {}
@@ -45354,7 +45393,7 @@ class ConvexHttpClient {
45354
45393
  const respJSON = await response.json();
45355
45394
  if (this.debug) {
45356
45395
  for (const line of respJSON.logLines ?? []) {
45357
- logForFunction(this.logger, "info", "query", name, line);
45396
+ logForFunction(this.logger, "info", "query", name2, line);
45358
45397
  }
45359
45398
  }
45360
45399
  switch (respJSON.status) {
@@ -45370,9 +45409,9 @@ class ConvexHttpClient {
45370
45409
  }
45371
45410
  }
45372
45411
  async mutationInner(mutation2, mutationArgs) {
45373
- const name = getFunctionName(mutation2);
45412
+ const name2 = getFunctionName(mutation2);
45374
45413
  const body = JSON.stringify({
45375
- path: name,
45414
+ path: name2,
45376
45415
  format: "convex_encoded_json",
45377
45416
  args: [convexToJson(mutationArgs)]
45378
45417
  });
@@ -45398,7 +45437,7 @@ class ConvexHttpClient {
45398
45437
  const respJSON = await response.json();
45399
45438
  if (this.debug) {
45400
45439
  for (const line of respJSON.logLines ?? []) {
45401
- logForFunction(this.logger, "info", "mutation", name, line);
45440
+ logForFunction(this.logger, "info", "mutation", name2, line);
45402
45441
  }
45403
45442
  }
45404
45443
  switch (respJSON.status) {
@@ -45447,9 +45486,9 @@ class ConvexHttpClient {
45447
45486
  }
45448
45487
  async action(action2, ...args) {
45449
45488
  const actionArgs = parseArgs2(args[0]);
45450
- const name = getFunctionName(action2);
45489
+ const name2 = getFunctionName(action2);
45451
45490
  const body = JSON.stringify({
45452
- path: name,
45491
+ path: name2,
45453
45492
  format: "convex_encoded_json",
45454
45493
  args: [convexToJson(actionArgs)]
45455
45494
  });
@@ -45475,7 +45514,7 @@ class ConvexHttpClient {
45475
45514
  const respJSON = await response.json();
45476
45515
  if (this.debug) {
45477
45516
  for (const line of respJSON.logLines ?? []) {
45478
- logForFunction(this.logger, "info", "action", name, line);
45517
+ logForFunction(this.logger, "info", "action", name2, line);
45479
45518
  }
45480
45519
  }
45481
45520
  switch (respJSON.status) {
@@ -45492,10 +45531,10 @@ class ConvexHttpClient {
45492
45531
  }
45493
45532
  async function(anyFunction, componentPath, ...args) {
45494
45533
  const functionArgs = parseArgs2(args[0]);
45495
- const name = typeof anyFunction === "string" ? anyFunction : getFunctionName(anyFunction);
45534
+ const name2 = typeof anyFunction === "string" ? anyFunction : getFunctionName(anyFunction);
45496
45535
  const body = JSON.stringify({
45497
45536
  componentPath,
45498
- path: name,
45537
+ path: name2,
45499
45538
  format: "convex_encoded_json",
45500
45539
  args: convexToJson(functionArgs)
45501
45540
  });
@@ -45521,7 +45560,7 @@ class ConvexHttpClient {
45521
45560
  const respJSON = await response.json();
45522
45561
  if (this.debug) {
45523
45562
  for (const line of respJSON.logLines ?? []) {
45524
- logForFunction(this.logger, "info", "any", name, line);
45563
+ logForFunction(this.logger, "info", "any", name2, line);
45525
45564
  }
45526
45565
  }
45527
45566
  switch (respJSON.status) {
@@ -45600,8 +45639,14 @@ function fileStore(path = join2(configDir(), "notices.json")) {
45600
45639
  }
45601
45640
  var billingUrl = (site) => `${site.replace(/\/+$/, "")}/billing`;
45602
45641
  function noticeLines(notice, site) {
45603
- const mark = notice.level === "stopped" ? "✗" : "!";
45604
- return [`${mark} ${notice.title}. ${notice.body}`, ` Billing: ${billingUrl(site)}`];
45642
+ const stopped = notice.level === "stopped";
45643
+ return [
45644
+ {
45645
+ text: `${stopped ? "✗" : "!"} ${notice.title}. ${notice.body}`,
45646
+ tone: stopped ? "fail" : "warn"
45647
+ },
45648
+ { text: ` Billing: ${billingUrl(site)}`, tone: "dim" }
45649
+ ];
45605
45650
  }
45606
45651
  function shownKey(notice, site) {
45607
45652
  return `${site} ${notice.level}:${notice.of}`;
@@ -45620,7 +45665,7 @@ async function maybeNotice(out, client, site, now = Date.now(), store = fileStor
45620
45665
  if (now - (shown[key] ?? 0) < DAY_MS)
45621
45666
  return;
45622
45667
  for (const line of noticeLines(notice, site))
45623
- await out.problem(line);
45668
+ await out.problem(line.text, line.tone);
45624
45669
  store.write({ ...shown, [key]: now });
45625
45670
  } catch {}
45626
45671
  }
@@ -45689,7 +45734,7 @@ async function run(argv, out) {
45689
45734
  cursor = result.continueCursor;
45690
45735
  }
45691
45736
  for (const event of [...events].reverse())
45692
- await out.line(auditLine(event));
45737
+ await out.line(auditLine(event, out.tint));
45693
45738
  if (events.length === 0) {
45694
45739
  await out.line(server ? `Nothing has changed on ${server.slug} in the last year.` : "Nothing has changed in this workspace in the last year.");
45695
45740
  }
@@ -45941,21 +45986,21 @@ function checkObject(schema, value, path, issues) {
45941
45986
  }
45942
45987
  const properties = isSchema(schema.properties) ? schema.properties : {};
45943
45988
  const required2 = Array.isArray(schema.required) ? schema.required.filter((n) => typeof n === "string") : [];
45944
- for (const name of required2) {
45945
- if (value[name] === undefined)
45946
- issues.push(`${at([...path, name])} is required`);
45989
+ for (const name2 of required2) {
45990
+ if (value[name2] === undefined)
45991
+ issues.push(`${at([...path, name2])} is required`);
45947
45992
  }
45948
- for (const [name, item] of Object.entries(value)) {
45993
+ for (const [name2, item] of Object.entries(value)) {
45949
45994
  if (item === undefined)
45950
45995
  continue;
45951
- const propertySchema = properties[name];
45996
+ const propertySchema = properties[name2];
45952
45997
  if (isSchema(propertySchema)) {
45953
- check2(propertySchema, item, [...path, name], issues);
45998
+ check2(propertySchema, item, [...path, name2], issues);
45954
45999
  } else if (schema.additionalProperties === false) {
45955
- const suggestion = suggestName(name, Object.keys(properties));
45956
- issues.push(`${at([...path, name])} is not allowed${suggestion ? ` (did you mean "${suggestion}"?)` : ""}`);
46000
+ const suggestion = suggestName(name2, Object.keys(properties));
46001
+ issues.push(`${at([...path, name2])} is not allowed${suggestion ? ` (did you mean "${suggestion}"?)` : ""}`);
45957
46002
  } else if (isSchema(schema.additionalProperties)) {
45958
- check2(schema.additionalProperties, item, [...path, name], issues);
46003
+ check2(schema.additionalProperties, item, [...path, name2], issues);
45959
46004
  }
45960
46005
  }
45961
46006
  }
@@ -46016,8 +46061,8 @@ var import_graphql5 = __toESM(require___dev__(), 1);
46016
46061
 
46017
46062
  // ../codegen/src/graphql/input.ts
46018
46063
  var import_graphql3 = __toESM(require___dev__(), 1);
46019
- function scalarSchema(name, warnings, path) {
46020
- switch (name) {
46064
+ function scalarSchema(name2, warnings, path) {
46065
+ switch (name2) {
46021
46066
  case "ID":
46022
46067
  case "String":
46023
46068
  return { type: "string" };
@@ -46036,8 +46081,8 @@ function scalarSchema(name, warnings, path) {
46036
46081
  case "URL":
46037
46082
  return { type: "string", format: "uri" };
46038
46083
  default:
46039
- warnings.push(`${path} uses the custom scalar ${name}, sent as a string.`);
46040
- return { type: "string", title: name };
46084
+ warnings.push(`${path} uses the custom scalar ${name2}, sent as a string.`);
46085
+ return { type: "string", title: name2 };
46041
46086
  }
46042
46087
  }
46043
46088
  function described(schema, description) {
@@ -46097,10 +46142,10 @@ var MAX_DEPTH = 4;
46097
46142
  var MAX_ABSTRACT_TYPES = 8;
46098
46143
  var PAGE_SIZE = 10;
46099
46144
  function pageArgument(args) {
46100
- for (const name of ["first", "last"]) {
46101
- const arg = args.find((candidate) => candidate.name === name);
46145
+ for (const name2 of ["first", "last"]) {
46146
+ const arg = args.find((candidate) => candidate.name === name2);
46102
46147
  if (arg && import_graphql4.getNamedType(arg.type).name === "Int")
46103
- return `(${name}: ${PAGE_SIZE})`;
46148
+ return `(${name2}: ${PAGE_SIZE})`;
46104
46149
  }
46105
46150
  return "";
46106
46151
  }
@@ -46148,7 +46193,7 @@ function abstractSelection(possible, schema, warnings, path, depth, stack) {
46148
46193
  typesByField.set(field.name, (typesByField.get(field.name) ?? new Set).add(String(field.type)));
46149
46194
  }
46150
46195
  }
46151
- const conflicting = new Set([...typesByField].filter(([, types2]) => types2.size > 1).map(([name]) => name));
46196
+ const conflicting = new Set([...typesByField].filter(([, types2]) => types2.size > 1).map(([name2]) => name2));
46152
46197
  const fragments = variants.map((variant) => {
46153
46198
  const alias = conflicting.size > 0 ? { prefix: variant.name, fields: conflicting } : undefined;
46154
46199
  const inner = objectSelection(variant, schema, warnings, `${path}.${variant.name}`, depth + 1, stack, alias);
@@ -46199,7 +46244,7 @@ function buildGraphQLTool(schema, file2, config2) {
46199
46244
  return { tool: null, warnings: [], errors: [`The schema has no ${type} field ${field}.`] };
46200
46245
  const warnings = [];
46201
46246
  const selection = selectionFor(definition.type, schema, warnings, field, 0, []);
46202
- const name = `${type === "query" ? "Query" : "Mutation"}${field.charAt(0).toUpperCase()}${field.slice(1)}`;
46247
+ const name2 = `${type === "query" ? "Query" : "Mutation"}${field.charAt(0).toUpperCase()}${field.slice(1)}`;
46203
46248
  const tool = {
46204
46249
  name: file2.name,
46205
46250
  ...file2.title ? { title: file2.title } : {},
@@ -46218,7 +46263,7 @@ function buildGraphQLTool(schema, file2, config2) {
46218
46263
  field,
46219
46264
  document: operationDocument({
46220
46265
  type,
46221
- name,
46266
+ name: name2,
46222
46267
  field,
46223
46268
  fieldArguments: definition.args,
46224
46269
  selection
@@ -46338,16 +46383,16 @@ function convert(value) {
46338
46383
  out.type = withNull(out.type);
46339
46384
  if (isRecord8(value.properties) && Array.isArray(out.required)) {
46340
46385
  const kept = new Set(Object.keys(out.properties));
46341
- out.required = out.required.filter((name) => typeof name === "string" && kept.has(name));
46386
+ out.required = out.required.filter((name2) => typeof name2 === "string" && kept.has(name2));
46342
46387
  }
46343
46388
  return out;
46344
46389
  }
46345
46390
  function writableProperties(properties) {
46346
46391
  const out = {};
46347
- for (const [name, schema] of Object.entries(properties)) {
46392
+ for (const [name2, schema] of Object.entries(properties)) {
46348
46393
  if (isRecord8(schema) && schema.readOnly === true)
46349
46394
  continue;
46350
- out[name] = toInputSchema(schema);
46395
+ out[name2] = toInputSchema(schema);
46351
46396
  }
46352
46397
  return out;
46353
46398
  }
@@ -46384,10 +46429,10 @@ function overlappingOneOf(schema) {
46384
46429
  if (i2 === j || !isObjectBranch(second))
46385
46430
  return;
46386
46431
  const secondProps = isRecord8(second.properties) ? new Set(Object.keys(second.properties)) : new Set;
46387
- if (second.additionalProperties === false && [...defines].some((name) => !secondProps.has(name)))
46432
+ if (second.additionalProperties === false && [...defines].some((name2) => !secondProps.has(name2)))
46388
46433
  return;
46389
46434
  const requires = requiredOf(second);
46390
- if (!requires.every((name) => defines.has(name)))
46435
+ if (!requires.every((name2) => defines.has(name2)))
46391
46436
  return;
46392
46437
  const why = requires.length === 0 ? `branch ${j + 1} requires nothing` : `branch ${j + 1} only requires ${requires.join(", ")}, which branch ${i2 + 1} also defines`;
46393
46438
  notes.push(`oneOf branches ${i2 + 1} and ${j + 1} overlap (${why}), so one value fits both. The tool accepts either; give each branch a distinct required property to keep them apart.`);
@@ -46476,26 +46521,26 @@ function buildInput(doc2, operation) {
46476
46521
  const required2 = [];
46477
46522
  const params = {};
46478
46523
  for (const parameter of operation.parameters) {
46479
- const name = parameter.name;
46524
+ const name2 = parameter.name;
46480
46525
  const location = parameter.in;
46481
46526
  if (location === "body" || location === "formData")
46482
46527
  continue;
46483
46528
  if (location !== "path" && location !== "query" && location !== "header") {
46484
- warnings.push(`The ${String(location)} parameter "${name}" is not sent: tools send path, query and header parameters only.`);
46529
+ warnings.push(`The ${String(location)} parameter "${name2}" is not sent: tools send path, query and header parameters only.`);
46485
46530
  continue;
46486
46531
  }
46487
- if (name === "body") {
46532
+ if (name2 === "body") {
46488
46533
  errors5.push('A parameter is named "body", which is the name a tool gives its request body. Rename the parameter in the spec.');
46489
46534
  continue;
46490
46535
  }
46491
- if (params[name]) {
46492
- warnings.push(`"${name}" is both a ${params[name]} and a ${location} parameter; the ${params[name]} one is kept.`);
46536
+ if (params[name2]) {
46537
+ warnings.push(`"${name2}" is both a ${params[name2]} and a ${location} parameter; the ${params[name2]} one is kept.`);
46493
46538
  continue;
46494
46539
  }
46495
- params[name] = location;
46496
- properties[name] = toInputSchema(withDescription(parameterSchema(parameter, swagger2), text3(parameter.description)));
46540
+ params[name2] = location;
46541
+ properties[name2] = toInputSchema(withDescription(parameterSchema(parameter, swagger2), text3(parameter.description)));
46497
46542
  if (parameter.required === true || location === "path")
46498
- required2.push(name);
46543
+ required2.push(name2);
46499
46544
  }
46500
46545
  let body;
46501
46546
  const found = swagger2 ? swagger2Body(operation.parameters, warnings) : openApi3Body(operation.op, warnings);
@@ -46765,15 +46810,15 @@ function generateBundle(input2) {
46765
46810
  headers: config2.upstream.headers,
46766
46811
  discovery: config2.settings.discovery,
46767
46812
  tools,
46768
- prompts: definition.prompts.map(({ name, title, description, arguments: args, template }) => ({
46769
- name,
46813
+ prompts: definition.prompts.map(({ name: name2, title, description, arguments: args, template }) => ({
46814
+ name: name2,
46770
46815
  ...title ? { title } : {},
46771
46816
  description,
46772
46817
  arguments: args,
46773
46818
  template
46774
46819
  })),
46775
- resources: definition.resources.map(({ name, uri, title, description, mimeType, content }) => ({
46776
- name,
46820
+ resources: definition.resources.map(({ name: name2, uri, title, description, mimeType, content }) => ({
46821
+ name: name2,
46777
46822
  uri,
46778
46823
  ...title ? { title } : {},
46779
46824
  ...description ? { description } : {},
@@ -46880,11 +46925,17 @@ function summaryLine(summary) {
46880
46925
  // src/findings.ts
46881
46926
  var MARK = { error: "✗", warning: "!", info: "·" };
46882
46927
  var ORDER = ["error", "warning", "info"];
46928
+ var LEVEL_TONE = {
46929
+ error: "fail",
46930
+ warning: "warn",
46931
+ info: "dim"
46932
+ };
46883
46933
  function plural2(n, noun) {
46884
46934
  return `${n} ${noun}${n === 1 ? "" : "s"}`;
46885
46935
  }
46886
- function findingLine(finding3) {
46887
- return `${MARK[finding3.level]} ${finding3.file || "."} ${finding3.message} [${finding3.rule}]`;
46936
+ function findingLine(finding3, tint = plain) {
46937
+ const where = tint(LEVEL_TONE[finding3.level], `${MARK[finding3.level]} ${finding3.file || "."}`);
46938
+ return `${where} ${finding3.message} ${tint("dim", `[${finding3.rule}]`)}`;
46888
46939
  }
46889
46940
  function sortFindings(findings) {
46890
46941
  return [...findings].sort((a, b) => ORDER.indexOf(a.level) - ORDER.indexOf(b.level) || a.file.localeCompare(b.file));
@@ -46955,20 +47006,20 @@ function inputsOf(schema, prefix = "") {
46955
47006
  const required2 = new Set(Array.isArray(schema.required) ? schema.required : []);
46956
47007
  return Object.entries(properties).flatMap(([key, value]) => {
46957
47008
  const property = isRecord11(value) ? value : {};
46958
- const name = `${prefix}${key}`;
47009
+ const name2 = `${prefix}${key}`;
46959
47010
  if (isRecord11(property.properties))
46960
- return inputsOf(property, `${name}.`);
47011
+ return inputsOf(property, `${name2}.`);
46961
47012
  const description = typeof property.description === "string" ? property.description : null;
46962
- return [{ name, type: typeOf(property), required: required2.has(key), description }];
47013
+ return [{ name: name2, type: typeOf(property), required: required2.has(key), description }];
46963
47014
  });
46964
47015
  }
46965
- function findingLabels(findings) {
46966
- return findings.map((finding3) => `${MARK2[finding3.level]} ${LABEL[finding3.rule] ?? finding3.rule}`).join(" ");
47016
+ function findingLabels(findings, tint) {
47017
+ return findings.map((finding3) => tint(LEVEL_TONE[finding3.level], `${MARK2[finding3.level]} ${LABEL[finding3.rule] ?? finding3.rule}`)).join(" ");
46967
47018
  }
46968
- function listLines(rows, unexposed, all) {
47019
+ function listLines(rows, unexposed, all, tint = plain) {
46969
47020
  const findings = rows.reduce((sum, row) => sum + row.findings.length, 0);
46970
47021
  const lines = [
46971
- `${plural2(rows.length, "tool")} in tools/ · ${findings === 0 ? "no findings" : plural2(findings, "finding")}`
47022
+ tint("dim", `${plural2(rows.length, "tool")} in tools/ · ${findings === 0 ? "no findings" : plural2(findings, "finding")}`)
46972
47023
  ];
46973
47024
  const shown = all || rows.length <= LIST_LIMIT + LIST_SLACK ? rows : rows.slice(0, LIST_LIMIT);
46974
47025
  if (shown.length > 0)
@@ -46977,17 +47028,17 @@ function listLines(rows, unexposed, all) {
46977
47028
  const opWidth = Math.max(...shown.map((row) => row.operation.length)) + 2;
46978
47029
  for (const row of shown) {
46979
47030
  const head = ` ${row.name.padEnd(nameWidth)}${row.effect.padEnd(10)}`;
46980
- lines.push(row.findings.length === 0 ? `${head}${row.operation}` : `${head}${row.operation.padEnd(opWidth)}${findingLabels(row.findings)}`);
47031
+ lines.push(row.findings.length === 0 ? `${head}${row.operation}` : `${head}${row.operation.padEnd(opWidth)}${findingLabels(row.findings, tint)}`);
46981
47032
  }
46982
47033
  const hidden = rows.slice(shown.length);
46983
47034
  if (hidden.length > 0) {
46984
47035
  const flagged = hidden.filter((row) => row.findings.length > 0).length;
46985
47036
  const note = flagged === 0 ? "" : `, ${flagged} with findings`;
46986
- lines.push(` … ${hidden.length} more${note}. --all lists every one; --json for scripts.`);
47037
+ lines.push(tint("dim", ` … ${hidden.length} more${note}. --all lists every one; --json for scripts.`));
46987
47038
  }
46988
47039
  if (unexposed > 0) {
46989
47040
  const are = unexposed === 1 ? "operation in the spec is" : "operations in the spec are";
46990
- lines.push("", `${unexposed} ${are} not exposed. sokie tools --unexposed lists them.`);
47041
+ lines.push("", tint("dim", `${unexposed} ${are} not exposed. sokie tools --unexposed lists them.`));
46991
47042
  }
46992
47043
  return lines;
46993
47044
  }
@@ -46997,17 +47048,18 @@ var HINTS = [
46997
47048
  ["idempotentHint", "idempotent"],
46998
47049
  ["openWorldHint", "openWorld"]
46999
47050
  ];
47000
- function detailLines(tool) {
47051
+ function detailLines(tool, tint = plain) {
47001
47052
  const annotations = HINTS.filter(([key]) => tool.annotations[key] !== undefined).map(([key, label]) => `${label} ${String(tool.annotations[key])}`).join(" · ");
47002
47053
  const input2 = tool.input.map((field) => `${field.name} ${field.type}${field.required ? " (required)" : ""}`).join(" · ");
47003
47054
  const lines = [
47004
- tool.title ? `${tool.name} · ${tool.title}` : tool.name,
47005
- `${tool.operation} · ${tool.file} · effect ${tool.effect}`,
47055
+ tint("strong", tool.title ? `${tool.name} · ${tool.title}` : tool.name),
47056
+ tint("dim", `${tool.operation} · ${tool.file} · effect ${tool.effect}`),
47006
47057
  `annotations ${annotations || "none"}`,
47007
47058
  `input ${input2 || "none"}`
47008
47059
  ];
47009
47060
  for (const finding3 of tool.findings) {
47010
- lines.push(`${MARK2[finding3.level]} ${finding3.rule}: ${finding3.message}`);
47061
+ const rule = tint(LEVEL_TONE[finding3.level], `${MARK2[finding3.level]} ${finding3.rule}:`);
47062
+ lines.push(`${rule} ${finding3.message}`);
47011
47063
  }
47012
47064
  return lines;
47013
47065
  }
@@ -47017,22 +47069,22 @@ var CATALOG_TOOLS = new Set(["searchTools", "getToolDefinition"]);
47017
47069
  function record2(value) {
47018
47070
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
47019
47071
  }
47020
- function routeCall(definition, name, input2) {
47072
+ function routeCall(definition, name2, input2) {
47021
47073
  if (!definition)
47022
47074
  return { problem: "not_buildable" };
47023
47075
  const discovery = definition.config.settings.discovery;
47024
47076
  const rows = toolRows(definition, []);
47025
- const effect = rows.find((row) => row.name === name)?.effect;
47077
+ const effect = rows.find((row) => row.name === name2)?.effect;
47026
47078
  if (effect)
47027
- return { tool: name, call: caseCall({ tool: name, input: input2 }, discovery), effect };
47079
+ return { tool: name2, call: caseCall({ tool: name2, input: input2 }, discovery), effect };
47028
47080
  if (discovery === "search") {
47029
- if (CATALOG_TOOLS.has(name))
47030
- return { tool: name, call: { name, arguments: input2 }, effect: "read" };
47031
- if (name === "useTool" && typeof input2.name === "string") {
47081
+ if (CATALOG_TOOLS.has(name2))
47082
+ return { tool: name2, call: { name: name2, arguments: input2 }, effect: "read" };
47083
+ if (name2 === "useTool" && typeof input2.name === "string") {
47032
47084
  return routeCall(definition, input2.name, record2(input2.arguments));
47033
47085
  }
47034
47086
  }
47035
- return { problem: "unknown_tool", tool: name };
47087
+ return { problem: "unknown_tool", tool: name2 };
47036
47088
  }
47037
47089
 
47038
47090
  // src/call-target.ts
@@ -47098,9 +47150,9 @@ var __hasOwnProp2 = Object.prototype.hasOwnProperty;
47098
47150
  var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
47099
47151
  var __exportAll = (all, symbols) => {
47100
47152
  let target = {};
47101
- for (var name in all) {
47102
- __defProp5(target, name, {
47103
- get: all[name],
47153
+ for (var name2 in all) {
47154
+ __defProp5(target, name2, {
47155
+ get: all[name2],
47104
47156
  enumerable: true
47105
47157
  });
47106
47158
  }
@@ -51472,7 +51524,7 @@ function walkRequestedSchema(converted2, vendor) {
51472
51524
  const unsupported = [];
51473
51525
  for (const [key, value] of Object.entries(converted2))
51474
51526
  if (key === "properties" && isJsonObject(value))
51475
- pruned[key] = Object.fromEntries(Object.entries(value).map(([name, node2]) => [name, walkProperty(node2, `properties.${name}`, vendor, unsupported)]));
51527
+ pruned[key] = Object.fromEntries(Object.entries(value).map(([name2, node2]) => [name2, walkProperty(node2, `properties.${name2}`, vendor, unsupported)]));
51476
51528
  else if (ROOT_KEYS.has(key))
51477
51529
  pruned[key] = value;
51478
51530
  else if (!isAnnotationOnlyJsonSchemaKeyword(key))
@@ -51484,7 +51536,7 @@ function walkRequestedSchema(converted2, vendor) {
51484
51536
  function describeUnsupportedProperties(pruned, fallback) {
51485
51537
  if (!isJsonObject(pruned.properties))
51486
51538
  return fallback;
51487
- const offenders = Object.entries(pruned.properties).filter(([, node2]) => !parseSchema(PrimitiveSchemaDefinitionSchema, node2).success).map(([name]) => `properties.${name}`);
51539
+ const offenders = Object.entries(pruned.properties).filter(([, node2]) => !parseSchema(PrimitiveSchemaDefinitionSchema, node2).success).map(([name2]) => `properties.${name2}`);
51488
51540
  return offenders.length > 0 ? offenders.join(", ") : fallback;
51489
51541
  }
51490
51542
  function findDroppedConstraintPaths(original, parsed, path = "") {
@@ -51855,9 +51907,9 @@ var authSchemas = {
51855
51907
  var _specTypeSchemas = {};
51856
51908
  var _isSpecType = {};
51857
51909
  function register(key, schema) {
51858
- const name = key.slice(0, -6);
51859
- _specTypeSchemas[name] = schema;
51860
- _isSpecType[name] = (v) => schema.safeParse(v).success;
51910
+ const name2 = key.slice(0, -6);
51911
+ _specTypeSchemas[name2] = schema;
51912
+ _isSpecType[name2] = (v) => schema.safeParse(v).success;
51861
51913
  }
51862
51914
  for (const key of SPEC_SCHEMA_KEYS)
51863
51915
  register(key, schemas_exports[key]);
@@ -52996,9 +53048,9 @@ var require_scope = /* @__PURE__ */ __commonJSMin((exports) => {
52996
53048
  exports.ValueScope = exports.ValueScopeName = exports.Scope = exports.varKinds = exports.UsedValueState = undefined;
52997
53049
  const code_1 = require_code$1();
52998
53050
  var ValueError = class extends Error {
52999
- constructor(name) {
53000
- super(`CodeGen: "code" for ${name} not defined`);
53001
- this.value = name.value;
53051
+ constructor(name2) {
53052
+ super(`CodeGen: "code" for ${name2} not defined`);
53053
+ this.value = name2.value;
53002
53054
  }
53003
53055
  };
53004
53056
  var UsedValueState;
@@ -53070,8 +53122,8 @@ var require_scope = /* @__PURE__ */ __commonJSMin((exports) => {
53070
53122
  var _a4;
53071
53123
  if (value.ref === undefined)
53072
53124
  throw new Error("CodeGen: ref must be passed in value");
53073
- const name = this.toName(nameOrPrefix);
53074
- const { prefix } = name;
53125
+ const name2 = this.toName(nameOrPrefix);
53126
+ const { prefix } = name2;
53075
53127
  const valueKey = (_a4 = value.key) !== null && _a4 !== undefined ? _a4 : value.ref;
53076
53128
  let vs = this._values[prefix];
53077
53129
  if (vs) {
@@ -53080,15 +53132,15 @@ var require_scope = /* @__PURE__ */ __commonJSMin((exports) => {
53080
53132
  return _name;
53081
53133
  } else
53082
53134
  vs = this._values[prefix] = /* @__PURE__ */ new Map;
53083
- vs.set(valueKey, name);
53135
+ vs.set(valueKey, name2);
53084
53136
  const s = this._scope[prefix] || (this._scope[prefix] = []);
53085
53137
  const itemIndex = s.length;
53086
53138
  s[itemIndex] = value.ref;
53087
- name.setValue(value, {
53139
+ name2.setValue(value, {
53088
53140
  property: prefix,
53089
53141
  itemIndex
53090
53142
  });
53091
- return name;
53143
+ return name2;
53092
53144
  }
53093
53145
  getValue(prefix, keyOrRef) {
53094
53146
  const vs = this._values[prefix];
@@ -53097,17 +53149,17 @@ var require_scope = /* @__PURE__ */ __commonJSMin((exports) => {
53097
53149
  return vs.get(keyOrRef);
53098
53150
  }
53099
53151
  scopeRefs(scopeName, values = this._values) {
53100
- return this._reduceValues(values, (name) => {
53101
- if (name.scopePath === undefined)
53102
- throw new Error(`CodeGen: name "${name}" has no value`);
53103
- return (0, code_1._)`${scopeName}${name.scopePath}`;
53152
+ return this._reduceValues(values, (name2) => {
53153
+ if (name2.scopePath === undefined)
53154
+ throw new Error(`CodeGen: name "${name2}" has no value`);
53155
+ return (0, code_1._)`${scopeName}${name2.scopePath}`;
53104
53156
  });
53105
53157
  }
53106
53158
  scopeCode(values = this._values, usedValues, getCode) {
53107
- return this._reduceValues(values, (name) => {
53108
- if (name.value === undefined)
53109
- throw new Error(`CodeGen: name "${name}" has no value`);
53110
- return name.value.code;
53159
+ return this._reduceValues(values, (name2) => {
53160
+ if (name2.value === undefined)
53161
+ throw new Error(`CodeGen: name "${name2}" has no value`);
53162
+ return name2.value.code;
53111
53163
  }, usedValues, getCode);
53112
53164
  }
53113
53165
  _reduceValues(values, valueCode, usedValues = {}, getCode) {
@@ -53117,19 +53169,19 @@ var require_scope = /* @__PURE__ */ __commonJSMin((exports) => {
53117
53169
  if (!vs)
53118
53170
  continue;
53119
53171
  const nameSet = usedValues[prefix] = usedValues[prefix] || /* @__PURE__ */ new Map;
53120
- vs.forEach((name) => {
53121
- if (nameSet.has(name))
53172
+ vs.forEach((name2) => {
53173
+ if (nameSet.has(name2))
53122
53174
  return;
53123
- nameSet.set(name, UsedValueState.Started);
53124
- let c = valueCode(name);
53175
+ nameSet.set(name2, UsedValueState.Started);
53176
+ let c = valueCode(name2);
53125
53177
  if (c) {
53126
53178
  const def = this.opts.es5 ? exports.varKinds.var : exports.varKinds.const;
53127
- code2 = (0, code_1._)`${code2}${def} ${name} = ${c};${this.opts._n}`;
53128
- } else if (c = getCode === null || getCode === undefined ? undefined : getCode(name))
53179
+ code2 = (0, code_1._)`${code2}${def} ${name2} = ${c};${this.opts._n}`;
53180
+ } else if (c = getCode === null || getCode === undefined ? undefined : getCode(name2))
53129
53181
  code2 = (0, code_1._)`${code2}${c}${this.opts._n}`;
53130
53182
  else
53131
- throw new ValueError(name);
53132
- nameSet.set(name, UsedValueState.Completed);
53183
+ throw new ValueError(name2);
53184
+ nameSet.set(name2, UsedValueState.Completed);
53133
53185
  });
53134
53186
  }
53135
53187
  return code2;
@@ -53237,10 +53289,10 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53237
53289
  }
53238
53290
  };
53239
53291
  var Def = class extends Node {
53240
- constructor(varKind, name, rhs) {
53292
+ constructor(varKind, name2, rhs) {
53241
53293
  super();
53242
53294
  this.varKind = varKind;
53243
- this.name = name;
53295
+ this.name = name2;
53244
53296
  this.rhs = rhs;
53245
53297
  }
53246
53298
  render({ es5, _n }) {
@@ -53458,28 +53510,28 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53458
53510
  }
53459
53511
  };
53460
53512
  var ForRange = class extends For {
53461
- constructor(varKind, name, from, to) {
53513
+ constructor(varKind, name2, from, to) {
53462
53514
  super();
53463
53515
  this.varKind = varKind;
53464
- this.name = name;
53516
+ this.name = name2;
53465
53517
  this.from = from;
53466
53518
  this.to = to;
53467
53519
  }
53468
53520
  render(opts) {
53469
53521
  const varKind = opts.es5 ? scope_1.varKinds.var : this.varKind;
53470
- const { name, from, to } = this;
53471
- return `for(${varKind} ${name}=${from}; ${name}<${to}; ${name}++)` + super.render(opts);
53522
+ const { name: name2, from, to } = this;
53523
+ return `for(${varKind} ${name2}=${from}; ${name2}<${to}; ${name2}++)` + super.render(opts);
53472
53524
  }
53473
53525
  get names() {
53474
53526
  return addExprNames(addExprNames(super.names, this.from), this.to);
53475
53527
  }
53476
53528
  };
53477
53529
  var ForIter = class extends For {
53478
- constructor(loop, varKind, name, iterable) {
53530
+ constructor(loop, varKind, name2, iterable) {
53479
53531
  super();
53480
53532
  this.loop = loop;
53481
53533
  this.varKind = varKind;
53482
- this.name = name;
53534
+ this.name = name2;
53483
53535
  this.iterable = iterable;
53484
53536
  }
53485
53537
  render(opts) {
@@ -53496,9 +53548,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53496
53548
  }
53497
53549
  };
53498
53550
  var Func = class extends BlockNode {
53499
- constructor(name, args, async) {
53551
+ constructor(name2, args, async) {
53500
53552
  super();
53501
- this.name = name;
53553
+ this.name = name2;
53502
53554
  this.args = args;
53503
53555
  this.async = async;
53504
53556
  }
@@ -53585,9 +53637,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53585
53637
  return this._extScope.name(prefix);
53586
53638
  }
53587
53639
  scopeValue(prefixOrName, value) {
53588
- const name = this._extScope.value(prefixOrName, value);
53589
- (this._values[name.prefix] || (this._values[name.prefix] = /* @__PURE__ */ new Set)).add(name);
53590
- return name;
53640
+ const name2 = this._extScope.value(prefixOrName, value);
53641
+ (this._values[name2.prefix] || (this._values[name2.prefix] = /* @__PURE__ */ new Set)).add(name2);
53642
+ return name2;
53591
53643
  }
53592
53644
  getScopeValue(prefix, keyOrRef) {
53593
53645
  return this._extScope.getValue(prefix, keyOrRef);
@@ -53599,11 +53651,11 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53599
53651
  return this._extScope.scopeCode(this._values);
53600
53652
  }
53601
53653
  _def(varKind, nameOrPrefix, rhs, constant) {
53602
- const name = this._scope.toName(nameOrPrefix);
53654
+ const name2 = this._scope.toName(nameOrPrefix);
53603
53655
  if (rhs !== undefined && constant)
53604
- this._constants[name.str] = rhs;
53605
- this._leafNode(new Def(varKind, name, rhs));
53606
- return name;
53656
+ this._constants[name2.str] = rhs;
53657
+ this._leafNode(new Def(varKind, name2, rhs));
53658
+ return name2;
53607
53659
  }
53608
53660
  const(nameOrPrefix, rhs, _constant) {
53609
53661
  return this._def(scope_1.varKinds.const, nameOrPrefix, rhs, _constant);
@@ -53670,25 +53722,25 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53670
53722
  return this._for(new ForLoop(iteration), forBody);
53671
53723
  }
53672
53724
  forRange(nameOrPrefix, from, to, forBody, varKind = this.opts.es5 ? scope_1.varKinds.var : scope_1.varKinds.let) {
53673
- const name = this._scope.toName(nameOrPrefix);
53674
- return this._for(new ForRange(varKind, name, from, to), () => forBody(name));
53725
+ const name2 = this._scope.toName(nameOrPrefix);
53726
+ return this._for(new ForRange(varKind, name2, from, to), () => forBody(name2));
53675
53727
  }
53676
53728
  forOf(nameOrPrefix, iterable, forBody, varKind = scope_1.varKinds.const) {
53677
- const name = this._scope.toName(nameOrPrefix);
53729
+ const name2 = this._scope.toName(nameOrPrefix);
53678
53730
  if (this.opts.es5) {
53679
53731
  const arr = iterable instanceof code_1.Name ? iterable : this.var("_arr", iterable);
53680
53732
  return this.forRange("_i", 0, (0, code_1._)`${arr}.length`, (i2) => {
53681
- this.var(name, (0, code_1._)`${arr}[${i2}]`);
53682
- forBody(name);
53733
+ this.var(name2, (0, code_1._)`${arr}[${i2}]`);
53734
+ forBody(name2);
53683
53735
  });
53684
53736
  }
53685
- return this._for(new ForIter("of", varKind, name, iterable), () => forBody(name));
53737
+ return this._for(new ForIter("of", varKind, name2, iterable), () => forBody(name2));
53686
53738
  }
53687
53739
  forIn(nameOrPrefix, obj, forBody, varKind = this.opts.es5 ? scope_1.varKinds.var : scope_1.varKinds.const) {
53688
53740
  if (this.opts.ownProperties)
53689
53741
  return this.forOf(nameOrPrefix, (0, code_1._)`Object.keys(${obj})`, forBody);
53690
- const name = this._scope.toName(nameOrPrefix);
53691
- return this._for(new ForIter("in", varKind, name, obj), () => forBody(name));
53742
+ const name2 = this._scope.toName(nameOrPrefix);
53743
+ return this._for(new ForIter("in", varKind, name2, obj), () => forBody(name2));
53692
53744
  }
53693
53745
  endFor() {
53694
53746
  return this._endBlockNode(For);
@@ -53743,8 +53795,8 @@ var require_codegen = /* @__PURE__ */ __commonJSMin((exports) => {
53743
53795
  this._nodes.length = len2;
53744
53796
  return this;
53745
53797
  }
53746
- func(name, args = code_1.nil, async, funcBody) {
53747
- this._blockNode(new Func(name, args, async));
53798
+ func(name2, args = code_1.nil, async, funcBody) {
53799
+ this._blockNode(new Func(name2, args, async));
53748
53800
  if (funcBody)
53749
53801
  this.code(funcBody).endFunc();
53750
53802
  return this;
@@ -56055,8 +56107,8 @@ var require_schemes = /* @__PURE__ */ __commonJSMin((exports, module) => {
56055
56107
  "urn",
56056
56108
  "urn:uuid"
56057
56109
  ];
56058
- function isValidSchemeName(name) {
56059
- return supportedSchemeNames.indexOf(name) !== -1;
56110
+ function isValidSchemeName(name2) {
56111
+ return supportedSchemeNames.indexOf(name2) !== -1;
56060
56112
  }
56061
56113
  function wsIsSecure(wsComponent) {
56062
56114
  if (wsComponent.secure === true)
@@ -56843,10 +56895,10 @@ var require_core$3 = /* @__PURE__ */ __commonJSMin((exports) => {
56843
56895
  }
56844
56896
  return this;
56845
56897
  }
56846
- addFormat(name, format) {
56898
+ addFormat(name2, format) {
56847
56899
  if (typeof format == "string")
56848
56900
  format = new RegExp(format);
56849
- this.formats[name] = format;
56901
+ this.formats[name2] = format;
56850
56902
  return this;
56851
56903
  }
56852
56904
  errorsText(errors5 = this.errors, { separator = ", ", dataVar = "data" } = {}) {
@@ -56966,10 +57018,10 @@ var require_core$3 = /* @__PURE__ */ __commonJSMin((exports) => {
56966
57018
  this.addSchema(optsSchemas[key], key);
56967
57019
  }
56968
57020
  function addInitialFormats() {
56969
- for (const name in this.opts.formats) {
56970
- const format = this.opts.formats[name];
57021
+ for (const name2 in this.opts.formats) {
57022
+ const format = this.opts.formats[name2];
56971
57023
  if (format)
56972
- this.addFormat(name, format);
57024
+ this.addFormat(name2, format);
56973
57025
  }
56974
57026
  }
56975
57027
  function addInitialKeywords(defs) {
@@ -60345,10 +60397,10 @@ var require_dist = /* @__PURE__ */ __commonJSMin((exports, module) => {
60345
60397
  (0, limit_1.default)(ajv);
60346
60398
  return ajv;
60347
60399
  };
60348
- formatsPlugin.get = (name, mode = "full") => {
60349
- const f = (mode === "fast" ? formats_1.fastFormats : formats_1.fullFormats)[name];
60400
+ formatsPlugin.get = (name2, mode = "full") => {
60401
+ const f = (mode === "fast" ? formats_1.fastFormats : formats_1.fullFormats)[name2];
60350
60402
  if (!f)
60351
- throw new Error(`Unknown format "${name}"`);
60403
+ throw new Error(`Unknown format "${name2}"`);
60352
60404
  return f;
60353
60405
  };
60354
60406
  function addFormats(ajv, list, fs, exportName) {
@@ -61730,7 +61782,7 @@ var ClientResponseCache = class {
61730
61782
  this._toolOutputValidatorIndex = undefined;
61731
61783
  this._serverIdentity = "";
61732
61784
  }
61733
- async toolDefinition(name) {
61785
+ async toolDefinition(name2) {
61734
61786
  const entry = await this._probe("tools/list");
61735
61787
  if (entry === undefined) {
61736
61788
  this._toolIndex = undefined;
@@ -61747,9 +61799,9 @@ var ClientResponseCache = class {
61747
61799
  byName: byName2
61748
61800
  };
61749
61801
  }
61750
- return this._toolIndex.byName.get(name);
61802
+ return this._toolIndex.byName.get(name2);
61751
61803
  }
61752
- async outputValidator(name, compile3) {
61804
+ async outputValidator(name2, compile3) {
61753
61805
  const entry = await this._probe("tools/list");
61754
61806
  if (entry === undefined) {
61755
61807
  this._toolOutputValidatorIndex = undefined;
@@ -61768,7 +61820,7 @@ var ClientResponseCache = class {
61768
61820
  byName: byName2
61769
61821
  };
61770
61822
  }
61771
- return this._toolOutputValidatorIndex.byName.get(name);
61823
+ return this._toolOutputValidatorIndex.byName.get(name2);
61772
61824
  }
61773
61825
  _decodeListTools(entry) {
61774
61826
  try {
@@ -62935,8 +62987,8 @@ var Client = class extends Protocol {
62935
62987
  };
62936
62988
  }
62937
62989
  }
62938
- async _resolveXMcpHeaderScan(name, override) {
62939
- const tool = override ?? await this._cache.toolDefinition(name);
62990
+ async _resolveXMcpHeaderScan(name2, override) {
62991
+ const tool = override ?? await this._cache.toolDefinition(name2);
62940
62992
  return tool === undefined ? undefined : scanXMcpHeaderDeclarations(tool.inputSchema);
62941
62993
  }
62942
62994
  async readResource(params, options) {
@@ -63780,10 +63832,10 @@ var StreamableHTTPClientTransport = class {
63780
63832
  if (isHandshake)
63781
63833
  headers.delete("mcp-session-id");
63782
63834
  if (options?.headers !== undefined)
63783
- for (const [name, value] of Object.entries(options.headers)) {
63784
- if (RESERVED_REQUEST_HEADER_NAMES.has(name.toLowerCase()))
63835
+ for (const [name2, value] of Object.entries(options.headers)) {
63836
+ if (RESERVED_REQUEST_HEADER_NAMES.has(name2.toLowerCase()))
63785
63837
  continue;
63786
- headers.set(name, value);
63838
+ headers.set(name2, value);
63787
63839
  }
63788
63840
  headers.set("content-type", "application/json");
63789
63841
  const types2 = [
@@ -63961,12 +64013,12 @@ function listCatalog(serverUrl, token) {
63961
64013
  return { tools: tools.tools, prompts: prompts.prompts, resources: resources.resources };
63962
64014
  });
63963
64015
  }
63964
- function callTool(serverUrl, token, name, args) {
63965
- return withClient(serverUrl, token, (client) => client.callTool({ name, arguments: args }));
64016
+ function callTool(serverUrl, token, name2, args) {
64017
+ return withClient(serverUrl, token, (client) => client.callTool({ name: name2, arguments: args }));
63966
64018
  }
63967
- function callToolReporting(serverUrl, token, name, args) {
64019
+ function callToolReporting(serverUrl, token, name2, args) {
63968
64020
  return withClient(serverUrl, token, async (client) => ({
63969
- result: await client.callTool({ name, arguments: args }),
64021
+ result: await client.callTool({ name: name2, arguments: args }),
63970
64022
  serverVersion: client.getServerVersion()?.version ?? null
63971
64023
  }));
63972
64024
  }
@@ -64010,21 +64062,21 @@ function readDevSecrets(root) {
64010
64062
  return { values: new Map, malformed: [] };
64011
64063
  return parseDevSecrets(readFileSync4(path, "utf8"));
64012
64064
  }
64013
- function writeDevSecret(root, name, value) {
64014
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
64015
- throw new Error(`${name} isn't a variable name.`);
64065
+ function writeDevSecret(root, name2, value) {
64066
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name2))
64067
+ throw new Error(`${name2} isn't a variable name.`);
64016
64068
  if (/[\r\n]/.test(value))
64017
- throw new Error(`${name}'s value has a line break.`);
64069
+ throw new Error(`${name2}'s value has a line break.`);
64018
64070
  const path = join4(root, DEV_SECRETS_FILE);
64019
64071
  mkdirSync3(dirname3(path), { recursive: true, mode: 448 });
64020
64072
  const lines = existsSync4(path) ? readFileSync4(path, "utf8").split(/\r?\n/) : [];
64021
64073
  if (lines.at(-1) === "")
64022
64074
  lines.pop();
64023
- const own2 = new RegExp(`^\\s*(?:export\\s+)?${name}\\s*=`);
64075
+ const own2 = new RegExp(`^\\s*(?:export\\s+)?${name2}\\s*=`);
64024
64076
  const quoted = value !== value.trim() || /^(["']).*\1$/.test(value);
64025
64077
  const at2 = lines.findIndex((line) => own2.test(line));
64026
64078
  const kept = lines.filter((line) => !own2.test(line));
64027
- kept.splice(at2 === -1 ? kept.length : at2, 0, `${name}=${quoted ? `"${value}"` : value}`);
64079
+ kept.splice(at2 === -1 ? kept.length : at2, 0, `${name2}=${quoted ? `"${value}"` : value}`);
64028
64080
  writeFileSync3(path, `${kept.join(`
64029
64081
  `)}
64030
64082
  `, { mode: 384 });
@@ -64052,8 +64104,8 @@ function needsOAuthToken(config2) {
64052
64104
  }
64053
64105
  function reportSecrets(config2, secrets) {
64054
64106
  const declared = Object.entries(config2.secrets);
64055
- const missing = declared.filter(([name]) => !secrets.values.get(name)).map(([name, declaration]) => ({ name, description: declaration.description }));
64056
- const unknown2 = [...secrets.values.keys()].filter((name) => !config2.secrets[name] && !STAND_INS.has(name));
64107
+ const missing = declared.filter(([name2]) => !secrets.values.get(name2)).map(([name2, declaration]) => ({ name: name2, description: declaration.description }));
64108
+ const unknown2 = [...secrets.values.keys()].filter((name2) => !config2.secrets[name2] && !STAND_INS.has(name2));
64057
64109
  const standInsMissing = [
64058
64110
  ...needsCallerKey(config2) && !secrets.values.get(CALLER_KEY) ? [CALLER_KEY] : [],
64059
64111
  ...needsOAuthToken(config2) && !secrets.values.get(OAUTH_TOKEN) ? [OAUTH_TOKEN] : []
@@ -64062,10 +64114,10 @@ function reportSecrets(config2, secrets) {
64062
64114
  }
64063
64115
  function secretBindings(config2, secrets) {
64064
64116
  const bindings = {};
64065
- for (const name of Object.keys(config2.secrets)) {
64066
- const value = secrets.values.get(name);
64117
+ for (const name2 of Object.keys(config2.secrets)) {
64118
+ const value = secrets.values.get(name2);
64067
64119
  if (value)
64068
- bindings[name] = value;
64120
+ bindings[name2] = value;
64069
64121
  }
64070
64122
  const baseUrl = secrets.values.get(UPSTREAM_BASE_URL);
64071
64123
  if (baseUrl)
@@ -64143,6 +64195,32 @@ function writeLink(root, site, link) {
64143
64195
 
64144
64196
  // src/prompt.ts
64145
64197
  import { stderr, stdin } from "node:process";
64198
+
64199
+ // src/style.ts
64200
+ var SGR = {
64201
+ ok: [32, 39],
64202
+ warn: [33, 39],
64203
+ fail: [31, 39],
64204
+ dim: [90, 39],
64205
+ strong: [1, 22]
64206
+ };
64207
+ function colorFor(stream, env = process.env) {
64208
+ if (env.NO_COLOR !== undefined && env.NO_COLOR !== "")
64209
+ return false;
64210
+ if (env.FORCE_COLOR !== undefined)
64211
+ return env.FORCE_COLOR !== "0" && env.FORCE_COLOR !== "false";
64212
+ if (env.TERM === "dumb")
64213
+ return false;
64214
+ return stream.isTTY === true;
64215
+ }
64216
+ function paint(on, tone, text5) {
64217
+ if (!on || tone === undefined || text5 === "")
64218
+ return text5;
64219
+ const [open2, close] = SGR[tone];
64220
+ return `\x1B[${open2}m${text5}\x1B[${close}m`;
64221
+ }
64222
+
64223
+ // src/prompt.ts
64146
64224
  async function readSecretValue(label) {
64147
64225
  if (!stdin.isTTY) {
64148
64226
  const chunks = [];
@@ -64190,7 +64268,7 @@ async function readLine(label) {
64190
64268
  return line.trim();
64191
64269
  }
64192
64270
  async function confirm(question) {
64193
- const answer = await readLine(`${question} (y/N)`);
64271
+ const answer = await readLine(paint(colorFor(stderr), "warn", `${question} (y/N)`));
64194
64272
  return /^y(es)?$/i.test(answer);
64195
64273
  }
64196
64274
 
@@ -64215,8 +64293,8 @@ function parseInput(raw) {
64215
64293
  }
64216
64294
  return parsed;
64217
64295
  }
64218
- function localRoute(root, name, input2) {
64219
- return routeCall(buildFromFiles(readRepoFiles(root)).definition, name, input2);
64296
+ function localRoute(root, name2, input2) {
64297
+ return routeCall(buildFromFiles(readRepoFiles(root)).definition, name2, input2);
64220
64298
  }
64221
64299
  function answeringDeploy(target, serverVersion) {
64222
64300
  if (target.kind === "dev" || serverVersion === null || !/^\d+$/.test(serverVersion))
@@ -64224,16 +64302,16 @@ function answeringDeploy(target, serverVersion) {
64224
64302
  return Number(serverVersion);
64225
64303
  }
64226
64304
  async function callAndPrint(out, deps, endpoint, call) {
64227
- const { name, effect } = call;
64305
+ const { name: name2, effect } = call;
64228
64306
  const where = targetName(call.target);
64229
64307
  if (effect !== "read" && !call.yes) {
64230
- const what = effect ? `${name} is ${effect}.` : `${name}'s effect can't be read from here.`;
64308
+ const what = effect ? `${name2} is ${effect}.` : `${name2}'s effect can't be read from here.`;
64231
64309
  if (!deps.interactive) {
64232
64310
  const message = `${what} There's no terminal to ask in, so pass --yes to call it on ${where}.`;
64233
64311
  return fail(out, "confirmation_needed", message, EXIT.usage);
64234
64312
  }
64235
64313
  if (!await deps.confirm(`${what} Call it on ${where}?`)) {
64236
- return fail(out, "declined", `Didn't call ${name}.`, EXIT.no);
64314
+ return fail(out, "declined", `Didn't call ${name2}.`, EXIT.no);
64237
64315
  }
64238
64316
  }
64239
64317
  const started = performance.now();
@@ -64244,11 +64322,11 @@ async function callAndPrint(out, deps, endpoint, call) {
64244
64322
  } catch (error62) {
64245
64323
  const ms = Math.round(performance.now() - started);
64246
64324
  const message = error62 instanceof Error ? error62.message : String(error62);
64247
- await out.problem(`✗ ${message}`);
64248
- await out.line(summaryLine({ ok: false, ms, errorClass: null, requestId: null }));
64325
+ await out.problem(`✗ ${message}`, "fail");
64326
+ await out.line(summaryLine({ ok: false, ms, errorClass: null, requestId: null }), "fail");
64249
64327
  await out.result({
64250
64328
  ok: false,
64251
- tool: name,
64329
+ tool: name2,
64252
64330
  target: where,
64253
64331
  ms,
64254
64332
  error: { code: "mcp_error", message }
@@ -64260,10 +64338,10 @@ async function callAndPrint(out, deps, endpoint, call) {
64260
64338
  const deploy = answeringDeploy(call.target, outcome.serverVersion);
64261
64339
  for (const line of contentLines(result))
64262
64340
  await out.line(line);
64263
- await out.line(`${summaryLine(summary)}${deploy === null ? "" : ` · deploy #${deploy}`}`);
64341
+ await out.line(`${summaryLine(summary)}${deploy === null ? "" : ` · deploy #${deploy}`}`, summary.ok ? "ok" : "fail");
64264
64342
  await out.result({
64265
64343
  ...summary,
64266
- tool: name,
64344
+ tool: name2,
64267
64345
  target: where,
64268
64346
  ...deploy === null ? {} : { deploy },
64269
64347
  effect,
@@ -64281,8 +64359,8 @@ async function runCall(argv, out, deps) {
64281
64359
  preview: { type: "string" },
64282
64360
  production: { type: "boolean", default: false }
64283
64361
  });
64284
- const [name, ...extra] = positionals;
64285
- if (!name || extra.length > 0) {
64362
+ const [name2, ...extra] = positionals;
64363
+ if (!name2 || extra.length > 0) {
64286
64364
  throw new UsageError(`Give one tool's name: sokie call getTask --input '{"taskId":"t_1"}'.`);
64287
64365
  }
64288
64366
  const input2 = parseInput(values.input);
@@ -64291,7 +64369,7 @@ async function runCall(argv, out, deps) {
64291
64369
  throw new UsageError("--server picks a deploy: add --preview <n> or --production.");
64292
64370
  }
64293
64371
  const root = resolve(values.dir ?? ".");
64294
- const local = localRoute(root, name, input2);
64372
+ const local = localRoute(root, name2, input2);
64295
64373
  const yes = values.yes;
64296
64374
  if (target.kind === "dev") {
64297
64375
  if ("problem" in local) {
@@ -64317,7 +64395,7 @@ async function runCall(argv, out, deps) {
64317
64395
  }
64318
64396
  const server = await serverBySlug(client, slug);
64319
64397
  const endpoint = await mintEndpoint(client, server, target);
64320
- const call = linked === server.slug && !("problem" in local) ? { name: local.tool, request: local.call, effect: local.effect } : { name, request: { name, arguments: input2 }, effect: null };
64398
+ const call = linked === server.slug && !("problem" in local) ? { name: local.tool, request: local.call, effect: local.effect } : { name: name2, request: { name: name2, arguments: input2 }, effect: null };
64321
64399
  return await callAndPrint(out, deps, endpoint, { ...call, target, yes });
64322
64400
  } catch (error62) {
64323
64401
  if (error62 instanceof DeployError)
@@ -64373,7 +64451,7 @@ async function run2(argv, out) {
64373
64451
  resources: build2.bundle.resources.length
64374
64452
  } : null;
64375
64453
  for (const finding3 of findings)
64376
- await out.line(findingLine(finding3));
64454
+ await out.line(findingLine(finding3, out.tint));
64377
64455
  if (findings.length > 0)
64378
64456
  await out.line();
64379
64457
  if (server) {
@@ -64382,9 +64460,9 @@ async function run2(argv, out) {
64382
64460
  plural2(server.prompts, "prompt"),
64383
64461
  plural2(server.resources, "resource")
64384
64462
  ];
64385
- await out.line(`OK: ${server.name}, ${parts.join(", ")}.`);
64463
+ await out.line(`OK: ${server.name}, ${parts.join(", ")}.`, "ok");
64386
64464
  } else {
64387
- await out.line(`${plural2(counts.error, "error")}; nothing can be built from this repository yet.`);
64465
+ await out.line(`${plural2(counts.error, "error")}; nothing can be built from this repository yet.`, "fail");
64388
64466
  }
64389
64467
  await out.result({ ok: server !== null, server, counts, findings });
64390
64468
  return server ? EXIT.ok : EXIT.no;
@@ -64421,8 +64499,8 @@ async function run3(argv, out) {
64421
64499
  return withSignedIn(out, values.site, async (info2, client) => {
64422
64500
  const current = await client.query(fn.cliLimits, {});
64423
64501
  if (verb === "get") {
64424
- await out.line(`session.max-age ${current.maxAgeDays}d (from approval)`);
64425
- await out.line(`session.idle ${current.idleDays}d (without use)`);
64502
+ await out.line(`session.max-age ${current.maxAgeDays}d ${out.tint("dim", "(from approval)")}`);
64503
+ await out.line(`session.idle ${current.idleDays}d ${out.tint("dim", "(without use)")}`);
64426
64504
  await out.result({ ok: true, site: info2.site, ...current });
64427
64505
  return EXIT.ok;
64428
64506
  }
@@ -64445,7 +64523,7 @@ async function run3(argv, out) {
64445
64523
  }
64446
64524
  throw error62;
64447
64525
  }
64448
- await out.line(`${key} is now ${next[field]}d. Sign-ins already made follow it at their next refresh.`);
64526
+ await out.line(`${key} is now ${next[field]}d. Sign-ins already made follow it at their next refresh.`, "ok");
64449
64527
  await out.result({ ok: true, site: info2.site, ...next });
64450
64528
  return EXIT.ok;
64451
64529
  });
@@ -64535,7 +64613,8 @@ async function run4(argv, out) {
64535
64613
  server: { type: "string" },
64536
64614
  create: { type: "boolean", default: false },
64537
64615
  public: { type: "boolean", default: false },
64538
- "no-wait": { type: "boolean", default: false }
64616
+ "no-wait": { type: "boolean", default: false },
64617
+ force: { type: "boolean", default: false }
64539
64618
  });
64540
64619
  if (values.create && values.server)
64541
64620
  throw new UsageError("Use --create or --server, not both.");
@@ -64544,29 +64623,39 @@ async function run4(argv, out) {
64544
64623
  if (!build2.bundle || !build2.config) {
64545
64624
  const findings = sortFindings(build2.findings).filter((finding3) => finding3.level === "error");
64546
64625
  for (const finding3 of findings)
64547
- await out.problem(findingLine(finding3));
64626
+ await out.problem(findingLine(finding3), LEVEL_TONE[finding3.level]);
64548
64627
  return fail(out, "build_failed", `${plural2(countLevels(findings).error, "error")}; run \`sokie check\`.`, EXIT.no);
64549
64628
  }
64550
- const { name } = build2.config;
64629
+ const { name: name2 } = build2.config;
64551
64630
  const toolCount = build2.bundle.tools.length;
64552
- const ship = async (platform, server) => {
64553
- await out.line(`Deploying ${name} (${plural2(toolCount, "tool")}) to ${server.slug}…`);
64554
- const deployment = await deployArchive(platform, server.serverId, sourceArchive(readRepoFiles(root)), { wait: !values["no-wait"], progress: (status) => out.line(` ${status}`) });
64631
+ const ship = async (platform, server, base) => {
64632
+ await out.line(`Deploying ${name2} (${plural2(toolCount, "tool")}) to ${server.slug}…`);
64633
+ const deployment = await deployArchive(platform, server.serverId, sourceArchive(readRepoFiles(root)), {
64634
+ wait: !values["no-wait"],
64635
+ progress: (status) => out.line(` ${status}`, "dim"),
64636
+ ...base === undefined || values.force ? {} : { base }
64637
+ });
64555
64638
  const url2 = server.url;
64556
64639
  if (deployment.status === "failed") {
64557
- for (const finding3 of deployment.findings ?? [])
64558
- await out.problem(findingLine(finding3));
64640
+ for (const finding3 of deployment.findings ?? []) {
64641
+ await out.problem(findingLine(finding3), LEVEL_TONE[finding3.level]);
64642
+ }
64559
64643
  const reason = deployment.error?.message ?? "The deploy failed.";
64560
64644
  await out.result({ ok: false, server, deployment, error: deployment.error ?? null });
64561
- await out.problem(`✗ ${reason}`);
64645
+ await out.problem(`✗ ${reason}`, "fail");
64562
64646
  return EXIT.no;
64563
64647
  }
64564
- if (deployment.status === "live")
64565
- for (const line of liveLines(server, deployment))
64566
- await out.line(line);
64648
+ if (deployment.status === "live") {
64649
+ const [live, ...rest] = liveLines(server, deployment);
64650
+ if (live)
64651
+ await out.line(live, "ok");
64652
+ for (const line of rest)
64653
+ await out.line(line, "dim");
64654
+ }
64567
64655
  await out.result({ ok: true, server, deployment, url: url2, linkFile: LINK_FILE });
64568
- return EXIT.ok;
64656
+ return deployment;
64569
64657
  };
64658
+ const exit = (shipped) => typeof shipped === "number" ? shipped : EXIT.ok;
64570
64659
  const deployKey = deployKeyFrom();
64571
64660
  if (deployKey) {
64572
64661
  if (values.create)
@@ -64579,7 +64668,7 @@ async function run4(argv, out) {
64579
64668
  if (values.server && values.server !== server.slug) {
64580
64669
  return fail(out, "wrong_server", `${DEPLOY_KEY_ENV} deploys ${server.slug}, not ${values.server}.`, EXIT.no);
64581
64670
  }
64582
- return await ship(platformFor(client), server);
64671
+ return exit(await ship(platformFor(client), server));
64583
64672
  } catch (error62) {
64584
64673
  if (error62 instanceof DeployError)
64585
64674
  return fail(out, error62.code, error62.message, EXIT.no);
@@ -64595,7 +64684,7 @@ async function run4(argv, out) {
64595
64684
  const linked = readLink(root, info2.site);
64596
64685
  if (values.create) {
64597
64686
  server = await client.mutation(fn.createServer, {
64598
- name,
64687
+ name: name2,
64599
64688
  accessMode: values.public ? "public" : "private"
64600
64689
  });
64601
64690
  } else if (values.server) {
@@ -64605,13 +64694,26 @@ async function run4(argv, out) {
64605
64694
  } else {
64606
64695
  return fail(out, "not_linked", `This repository isn't linked to a server on ${info2.site}. Run \`sokie deploy --create\`, or \`--server <slug>\` for one you have.`, EXIT.no);
64607
64696
  }
64608
- writeLink(root, info2.site, { serverId: server.serverId, slug: server.slug });
64609
64697
  const github = await client.query(fn.link, { serverId: server.serverId });
64610
64698
  if (github && !github.broken) {
64611
- await out.problem(`Note: ${server.slug} is linked to ${github.repo}. The next push to ${github.defaultBranch} replaces this deploy.`);
64699
+ await out.problem(`Note: ${server.slug} is linked to ${github.repo}. The next push to ${github.defaultBranch} replaces this deploy.`, "warn");
64612
64700
  }
64701
+ const base = !github && linked?.serverId === server.serverId ? linked.base : undefined;
64702
+ writeLink(root, info2.site, {
64703
+ serverId: server.serverId,
64704
+ slug: server.slug,
64705
+ ...base === undefined ? {} : { base }
64706
+ });
64613
64707
  ensureIgnored(root, ".sokie/");
64614
- return await ship(platformFor(client), server);
64708
+ const shipped = await ship(platformFor(client), server, base);
64709
+ if (!github && typeof shipped !== "number" && shipped.number !== undefined) {
64710
+ writeLink(root, info2.site, {
64711
+ serverId: server.serverId,
64712
+ slug: server.slug,
64713
+ base: shipped.number
64714
+ });
64715
+ }
64716
+ return exit(shipped);
64615
64717
  } catch (error62) {
64616
64718
  if (error62 instanceof DeployError)
64617
64719
  return fail(out, error62.code, error62.message, EXIT.no);
@@ -64624,7 +64726,7 @@ async function run4(argv, out) {
64624
64726
  }
64625
64727
  var deployCommand = {
64626
64728
  name: "deploy",
64627
- synopsis: "sokie deploy [dir] [--create [--public] | --server <slug>] [--no-wait] [--site <url>]",
64729
+ synopsis: "sokie deploy [dir] [--create [--public] | --server <slug>] [--no-wait] [--force] [--site <url>]",
64628
64730
  summary: "Deploy the server in dir and wait until it is live.",
64629
64731
  help: `Checks the repository the way the platform will, uploads its definition
64630
64732
  files and waits for the deploy. The first deploy to a site says which server:
@@ -64637,25 +64739,32 @@ After that the repository is linked (in ${LINK_FILE}, kept out of git).
64637
64739
  In CI, set ${DEPLOY_KEY_ENV} to a deploy key from the server's page instead
64638
64740
  of signing in: it deploys that key's server, and nothing is written to disk.
64639
64741
 
64742
+ A server with no repository keeps its files on Sokie. In a folder from
64743
+ sokie edit, a deploy is refused once production has moved on since the
64744
+ files were downloaded (an edit in the app, a restore), so it never undoes
64745
+ a change unseen: sokie pull brings that change in first.
64746
+
64640
64747
  --no-wait Return once the deploy is queued.
64748
+ --force Deploy these files even if production changed since they were downloaded.
64641
64749
  ${SITE_HELP}`,
64642
64750
  run: run4
64643
64751
  };
64644
64752
 
64645
64753
  // src/commands/deploys.ts
64646
64754
  import { resolve as resolve4 } from "node:path";
64755
+ import { stdin as stdin3 } from "node:process";
64647
64756
 
64648
64757
  // src/deploy-diff.ts
64649
- var name = (side) => side.previewPr === undefined ? `#${side.number}` : `#${side.number} (preview of PR #${side.previewPr})`;
64758
+ var name2 = (side) => side.previewPr === undefined ? `#${side.number}` : `#${side.number} (preview of PR #${side.previewPr})`;
64650
64759
  function diffTitle(view) {
64651
64760
  const { to, from, basis } = view;
64652
64761
  if (!from) {
64653
- return to.previewPr === undefined ? `#${to.number} is the first production deploy: every tool is new.` : `What ${name(to)} would add: nothing is in production yet.`;
64762
+ return to.previewPr === undefined ? `#${to.number} is the first production deploy: every tool is new.` : `What ${name2(to)} would add: nothing is in production yet.`;
64654
64763
  }
64655
64764
  if (basis === "production")
64656
- return `What ${name(to)} would change in production (${name(from)}).`;
64765
+ return `What ${name2(to)} would change in production (${name2(from)}).`;
64657
64766
  const why = basis === "previous" ? ", the production deploy before it" : "";
64658
- return `What ${name(to)} changed, compared with ${name(from)}${why}.`;
64767
+ return `What ${name2(to)} changed, compared with ${name2(from)}${why}.`;
64659
64768
  }
64660
64769
  var SIGN = {
64661
64770
  added: "+",
@@ -64729,7 +64838,223 @@ function diffLines(view) {
64729
64838
  return lines;
64730
64839
  }
64731
64840
 
64841
+ // src/deploy-list.ts
64842
+ function statusOf(deploy) {
64843
+ if (deploy.status === "failed")
64844
+ return { text: "failed", tone: "fail" };
64845
+ if (deploy.status === "queued" || deploy.status === "building") {
64846
+ return { text: deploy.status, tone: "warn" };
64847
+ }
64848
+ if (deploy.previewPr !== undefined)
64849
+ return { text: "preview", tone: deploy.status === "live" ? "ok" : undefined };
64850
+ return deploy.status === "live" ? { text: "live", tone: "ok" } : { text: "replaced", tone: "dim" };
64851
+ }
64852
+ function sourceOf(deploy) {
64853
+ if (deploy.restoreOf !== undefined)
64854
+ return `restore of #${deploy.restoreOf}`;
64855
+ const source = deploy.source;
64856
+ if (!source)
64857
+ return "uploaded from the CLI";
64858
+ if (source.kind === "upload") {
64859
+ const edited = source.edited ?? [];
64860
+ if (edited.length > 0) {
64861
+ const named = edited.length <= 2 ? edited.join(" and ") : `${edited[0]} and ${edited.length - 1} more`;
64862
+ return `${named} edited in the app`;
64863
+ }
64864
+ return source.from === "web" ? "made in Sokie from a spec" : "uploaded from the CLI";
64865
+ }
64866
+ const pr = deploy.previewPr ?? source.prNumber;
64867
+ const sha = source.sha.slice(0, 7);
64868
+ return pr === undefined ? `${sha} on ${source.branch}` : `${sha} · preview #${pr}`;
64869
+ }
64870
+ var MINUTE = 60000;
64871
+ var HOUR = 60 * MINUTE;
64872
+ var DAY = 24 * HOUR;
64873
+ function ago(at2, now) {
64874
+ const gone = Math.max(0, now - at2);
64875
+ if (gone < MINUTE)
64876
+ return "just now";
64877
+ if (gone < HOUR)
64878
+ return `${Math.floor(gone / MINUTE)} min ago`;
64879
+ if (gone < DAY)
64880
+ return `${Math.floor(gone / HOUR)} h ago`;
64881
+ if (gone < 2 * DAY)
64882
+ return "yesterday";
64883
+ if (gone < 30 * DAY)
64884
+ return `${Math.floor(gone / DAY)} days ago`;
64885
+ return new Date(at2).toLocaleDateString("en-US", {
64886
+ month: "short",
64887
+ day: "numeric",
64888
+ timeZone: "UTC"
64889
+ });
64890
+ }
64891
+ function headerLine(slug, facts) {
64892
+ if (facts.pin) {
64893
+ const since = facts.pin.skippedPushes === 1 ? "1 push" : `${facts.pin.skippedPushes} pushes`;
64894
+ return {
64895
+ text: `${slug} · production stays on #${facts.live ?? "?"} until sokie deploys resume (${since} since the restore)`,
64896
+ tone: "warn"
64897
+ };
64898
+ }
64899
+ if (facts.branch)
64900
+ return { text: `${slug} · production follows ${facts.branch}`, tone: "dim" };
64901
+ return { text: `${slug} · Sokie keeps its files`, tone: "dim" };
64902
+ }
64903
+ function rowLine(deploy, now) {
64904
+ const status = statusOf(deploy);
64905
+ const number4 = deploy.number === undefined ? "—" : `#${deploy.number}`;
64906
+ const text5 = ` ${number4.padEnd(5)} ${status.text.padEnd(9)} ${sourceOf(deploy).padEnd(32)} ${ago(deploy.createdAt, now)}`;
64907
+ return { text: text5, tone: status.tone === "dim" ? undefined : status.tone };
64908
+ }
64909
+ function listLines2(slug, deploys, facts) {
64910
+ const live = deploys.find((d) => d.status === "live" && d.previewPr === undefined)?.number;
64911
+ const lines = [headerLine(slug, { ...facts, live }), { text: "" }];
64912
+ if (deploys.length === 0) {
64913
+ lines.push({ text: " No deploys yet. sokie deploy makes the first one.", tone: "dim" });
64914
+ return lines;
64915
+ }
64916
+ for (const deploy of deploys)
64917
+ lines.push(rowLine(deploy, facts.now));
64918
+ if (facts.more) {
64919
+ lines.push({
64920
+ text: ` … older ones too. sokie deploys --limit ${facts.limit * 2} goes further back; --json for scripts.`,
64921
+ tone: "dim"
64922
+ });
64923
+ }
64924
+ return lines;
64925
+ }
64926
+ function diffTone(line, index) {
64927
+ if (index === 0)
64928
+ return "strong";
64929
+ const sign = line.trimStart().slice(0, 2);
64930
+ if (sign === "+ ")
64931
+ return "ok";
64932
+ if (sign === "- ")
64933
+ return "fail";
64934
+ if (sign === "↑ " || sign === "↓ ")
64935
+ return "warn";
64936
+ return;
64937
+ }
64938
+
64939
+ // src/deploys-restore.ts
64940
+ var REFUSED = {
64941
+ ALREADY_LIVE: (n) => `#${n} is what production runs now. sokie deploys lists the others.`,
64942
+ DEPLOY_NOT_FOUND: (n) => `There is no deploy #${n} on this server.`,
64943
+ NOT_RESTORABLE: (n) => `#${n} never served production: it's a preview, it failed, or it hasn't finished. Only a deploy that went live and was replaced can be restored.`,
64944
+ DEPLOY_IN_PROGRESS: () => "A deploy is running. Try again when it finishes.",
64945
+ MISSING_SECRETS: (n) => `#${n} needs a secret production no longer has.`,
64946
+ PLAN_LIMIT_SERVERS: () => "This server is past your plan's server limit, so it takes no deploys. Delete a server or upgrade on the Billing page.",
64947
+ NOT_PINNED: () => "Production already follows the default branch."
64948
+ };
64949
+ function refused2(out, error62, n) {
64950
+ const code2 = error62 instanceof ConvexError && typeof error62.data === "string" ? error62.data : "";
64951
+ const say = REFUSED[code2];
64952
+ return say ? fail(out, code2.toLowerCase(), say(n), EXIT.no) : null;
64953
+ }
64954
+ async function agreed(out, question, yes, deps) {
64955
+ if (yes)
64956
+ return true;
64957
+ if (!deps.interactive || out.json) {
64958
+ return fail(out, "needs_confirmation", "Confirm it in a terminal, or pass --yes.", EXIT.usage);
64959
+ }
64960
+ if (await deps.confirm(question))
64961
+ return true;
64962
+ await out.line("Nothing changed.", "dim");
64963
+ await out.result({ ok: false, error: { code: "declined", message: "Nothing changed." } });
64964
+ return EXIT.no;
64965
+ }
64966
+ async function restoreDeploy(out, client, server, n, options, deps) {
64967
+ const serverId = server.serverId;
64968
+ try {
64969
+ const check3 = await client.query(fn.restoreCheck, { serverId, number: n });
64970
+ if (check3.refusal)
64971
+ return await refused2(out, new ConvexError(check3.refusal), n) ?? EXIT.no;
64972
+ if (check3.missingSecrets.length > 0) {
64973
+ const names = check3.missingSecrets.join(", ");
64974
+ return fail(out, "missing_secrets", `#${n} reads ${names}, which production doesn't have any more. Set it with sokie secrets set ${check3.missingSecrets[0]}, or restore a later deploy.`, EXIT.no);
64975
+ }
64976
+ const page = await client.query(fn.server, { serverId }).catch(() => null);
64977
+ const live = page?.live?.number;
64978
+ const picked = await client.query(fn.deployByNumber, { serverId, number: n });
64979
+ const from = picked ? ` (${sourceOf(picked)})` : "";
64980
+ await out.line(`Restore #${n}${from} to production${live === undefined ? "" : `, in place of #${live}`}?`, "strong");
64981
+ if (live !== undefined) {
64982
+ const view = await client.action(fn.compareDeploys, { serverId, from: live, to: n }).catch(() => null);
64983
+ if (view) {
64984
+ await out.line();
64985
+ await out.line(`What agents will see, compared with #${live} now:`);
64986
+ const heads = view.diff.tools.map((change) => toolLines(change)[0] ?? "");
64987
+ if (heads.length === 0)
64988
+ await out.line(" Nothing an agent sees would change.", "dim");
64989
+ for (const head of heads)
64990
+ await out.line(` ${head}`, diffTone(head, 1));
64991
+ }
64992
+ }
64993
+ await out.line();
64994
+ await out.line(`Rebuilt from #${n}'s files on today's runtime, with today's secrets.`);
64995
+ await out.line(check3.pins ? `Production stops following ${check3.branch ?? "the default branch"} until sokie deploys resume.` : `The files go back too: the next edit in the app, or sokie deploy, starts from #${n}'s.`, "warn");
64996
+ const answer = await agreed(out, `Restore #${n}?`, options.yes, deps);
64997
+ if (answer !== true)
64998
+ return answer;
64999
+ const queued = await client.mutation(fn.restore, { serverId, number: n });
65000
+ await out.line(`#${queued.number} · restore of #${n} · building`, "dim");
65001
+ const started = Date.now();
65002
+ const done = await followDeploy({ query: client.query.bind(client), sleep: deps.sleep }, queued.deploymentId, { wait: true });
65003
+ if (done.status === "failed") {
65004
+ const reason = done.error?.message ?? "The restore didn't build.";
65005
+ await out.problem(`✗ ${reason} Production is unchanged.`, "fail");
65006
+ await out.result({
65007
+ ok: false,
65008
+ deploy: done,
65009
+ error: done.error ?? { code: "restore_failed", message: reason }
65010
+ });
65011
+ return EXIT.no;
65012
+ }
65013
+ const took = Math.max(1, Math.round((Date.now() - started) / 1000));
65014
+ await out.line(`#${queued.number} is live in ${took} s · ${server.url ?? server.slug}`, "ok");
65015
+ await out.line("Calls can reach the previous deploy for up to a minute while the edges catch up.", "dim");
65016
+ await out.result({
65017
+ ok: true,
65018
+ server: server.slug,
65019
+ deploy: { number: queued.number, restoreOf: n, status: done.status },
65020
+ pinned: queued.pinned
65021
+ });
65022
+ return EXIT.ok;
65023
+ } catch (error62) {
65024
+ const handled = refused2(out, error62, n);
65025
+ if (handled)
65026
+ return handled;
65027
+ throw error62;
65028
+ }
65029
+ }
65030
+ async function resumeDeploys(out, client, server, options, deps) {
65031
+ const serverId = server.serverId;
65032
+ try {
65033
+ const page = await client.query(fn.server, { serverId });
65034
+ const pin = page.pin;
65035
+ if (!pin)
65036
+ return fail(out, "not_pinned", "Production already follows the default branch.", EXIT.no);
65037
+ const pushes = pin.skippedPushes === 1 ? "1 push" : `${pin.skippedPushes} pushes`;
65038
+ const newest = pin.lastSkipped ? `: ${pin.lastSkipped.sha.slice(0, 7)} ${pin.lastSkipped.title}` : "";
65039
+ await out.line(`${pushes} since the restore of #${pin.restoreOf}${newest}`);
65040
+ const answer = await agreed(out, "Deploy the default branch and follow it again?", options.yes, deps);
65041
+ if (answer !== true)
65042
+ return answer;
65043
+ const resumed = await client.mutation(fn.resume, { serverId });
65044
+ await out.line(resumed.deploying ? "Production follows the default branch again. Its newest commit is deploying; sokie deploys shows it." : "Production follows the default branch again; the next push deploys.", "ok");
65045
+ await out.result({ ok: true, server: server.slug, deploying: resumed.deploying });
65046
+ return EXIT.ok;
65047
+ } catch (error62) {
65048
+ const handled = refused2(out, error62, 0);
65049
+ if (handled)
65050
+ return handled;
65051
+ throw error62;
65052
+ }
65053
+ }
65054
+
64732
65055
  // src/commands/deploys.ts
65056
+ var VERBS = ["diff", "restore", "resume", "list"];
65057
+ var PAGE = 100;
64733
65058
  var REFUSALS = {
64734
65059
  DEPLOY_NOT_FOUND: (to, from) => `There is no deploy #${from !== undefined ? `${from} or #${to}` : to} on this server.`,
64735
65060
  NOT_BUILT: (to) => `#${to} has no bundle: it failed or is still building. sokie logs or the Deploys tab say why.`,
@@ -64743,22 +65068,82 @@ function deployNumber(raw, what) {
64743
65068
  }
64744
65069
  return number4;
64745
65070
  }
65071
+ async function newest(client, serverId, limit) {
65072
+ const deploys = [];
65073
+ let cursor = null;
65074
+ for (;; ) {
65075
+ const page = await client.query(fn.deployments, {
65076
+ serverId,
65077
+ paginationOpts: { numItems: Math.min(PAGE, limit - deploys.length), cursor }
65078
+ });
65079
+ deploys.push(...page.page);
65080
+ if (page.isDone)
65081
+ return { deploys, more: false };
65082
+ if (deploys.length >= limit)
65083
+ return { deploys, more: true };
65084
+ cursor = page.continueCursor;
65085
+ }
65086
+ }
65087
+ async function listDeploys(out, client, server, limit, now) {
65088
+ const { deploys, more } = await newest(client, server.serverId, limit);
65089
+ const page = await client.query(fn.server, { serverId: server.serverId }).catch(() => null);
65090
+ const link = await client.query(fn.link, { serverId: server.serverId }).catch(() => null);
65091
+ const facts = {
65092
+ ...link && !link.broken ? { branch: link.defaultBranch } : {},
65093
+ ...page?.pin ? { pin: page.pin } : {},
65094
+ now,
65095
+ more,
65096
+ limit
65097
+ };
65098
+ for (const line of listLines2(server.slug, deploys, facts))
65099
+ await out.line(line.text, line.tone);
65100
+ await out.result({
65101
+ ok: true,
65102
+ server: server.slug,
65103
+ deploys,
65104
+ more,
65105
+ ...page?.pin ? { pin: page.pin } : {}
65106
+ });
65107
+ return EXIT.ok;
65108
+ }
64746
65109
  async function runDeploys(argv, out, deps) {
64747
65110
  const { values, positionals } = parseCommandArgs(argv, {
64748
65111
  ...SITE_OPTION,
64749
65112
  server: { type: "string" },
64750
- dir: { type: "string" }
64751
- });
64752
- const [verb, ...numbers] = positionals;
64753
- if (verb !== "diff")
64754
- throw new UsageError("Say diff: sokie deploys diff [<from>] <to>.");
64755
- if (numbers.length < 1 || numbers.length > 2) {
64756
- throw new UsageError("Give the deploy to show, and optionally one to compare it with first.");
65113
+ dir: { type: "string" },
65114
+ limit: { type: "string" },
65115
+ yes: { type: "boolean", default: false }
65116
+ });
65117
+ const [verb = "list", ...numbers] = positionals;
65118
+ if (!VERBS.includes(verb)) {
65119
+ throw new UsageError(`No "${verb}": say diff, restore or resume, or nothing to list deploys.`);
65120
+ }
65121
+ const limit = values.limit === undefined ? 10 : Number(values.limit);
65122
+ if (!Number.isInteger(limit) || limit < 1 || limit > 500) {
65123
+ throw new UsageError("--limit is how many deploys to list, from 1 to 500.");
65124
+ }
65125
+ let to = 0;
65126
+ let from;
65127
+ if (verb === "diff") {
65128
+ if (numbers.length < 1 || numbers.length > 2) {
65129
+ throw new UsageError("Give the deploy to show, and optionally one to compare it with first.");
65130
+ }
65131
+ const [first = "", second] = numbers;
65132
+ to = deployNumber(second ?? first, "<to>");
65133
+ from = second === undefined ? undefined : deployNumber(first, "<from>");
65134
+ } else if (verb === "restore") {
65135
+ if (numbers.length !== 1)
65136
+ throw new UsageError("Give the deploy to restore: sokie deploys restore 11.");
65137
+ to = deployNumber(numbers[0] ?? "", "<n>");
65138
+ } else if (numbers.length > 0) {
65139
+ throw new UsageError(`sokie deploys ${verb === "list" ? "" : `${verb} `}takes no deploy number.`);
64757
65140
  }
64758
- const [first = "", second] = numbers;
64759
- const to = deployNumber(second ?? first, "<to>");
64760
- const from = second === undefined ? undefined : deployNumber(first, "<from>");
64761
65141
  const root = resolve4(values.dir ?? ".");
65142
+ const ask = {
65143
+ interactive: deps.interactive ?? stdin3.isTTY === true,
65144
+ confirm: deps.confirm ?? confirm,
65145
+ sleep: deps.sleep ?? ((ms) => new Promise((done) => setTimeout(done, ms)))
65146
+ };
64762
65147
  return deps.signedIn(out, values.site, async (info2, client) => {
64763
65148
  try {
64764
65149
  const slug = values.server ?? readLink(root, info2.site)?.slug;
@@ -64766,13 +65151,20 @@ async function runDeploys(argv, out, deps) {
64766
65151
  return fail(out, "not_linked", `No server is linked here for ${info2.site}. Pass --server <slug>, or deploy first.`, EXIT.no);
64767
65152
  }
64768
65153
  const server = await serverBySlug(client, slug);
65154
+ if (verb === "list")
65155
+ return await listDeploys(out, client, server, limit, (deps.now ?? Date.now)());
65156
+ if (verb === "restore")
65157
+ return await restoreDeploy(out, client, server, to, { yes: values.yes }, ask);
65158
+ if (verb === "resume")
65159
+ return await resumeDeploys(out, client, server, { yes: values.yes }, ask);
64769
65160
  const view = await client.action(fn.compareDeploys, {
64770
65161
  serverId: server.serverId,
64771
65162
  to,
64772
65163
  ...from === undefined ? {} : { from }
64773
65164
  });
64774
- for (const line of diffLines(view))
64775
- await out.line(line);
65165
+ for (const [index, line] of diffLines(view).entries()) {
65166
+ await out.line(line, diffTone(line, index));
65167
+ }
64776
65168
  await out.result({ ok: true, server: server.slug, ...view });
64777
65169
  return EXIT.ok;
64778
65170
  } catch (error62) {
@@ -64788,17 +65180,31 @@ async function runDeploys(argv, out, deps) {
64788
65180
  }
64789
65181
  var deploysCommand = {
64790
65182
  name: "deploys",
64791
- synopsis: "sokie deploys diff [<from>] <to> [--server <slug>] [--dir <dir>] [--site <url>]",
64792
- summary: "Show what a deploy changed for agents, tool by tool.",
64793
- help: `Compares two deploys' bundles, by deploy number, and prints what an agent
64794
- sees differently: tools added, removed or renamed, descriptions, effects
64795
- raised or lowered, input schemas, response projections, operations, the
64796
- server's settings, prompts, resources and the runtime version.
65183
+ synopsis: "sokie deploys [diff [<from>] <to> | restore <n> | resume] [--yes] [--limit <n>] [--server <slug>] [--dir <dir>] [--site <url>]",
65184
+ summary: "List a server's deploys, compare two, or restore an earlier one.",
65185
+ help: `With no verb, lists the newest deploys (--limit, default 10): each one's
65186
+ number, status, where its files came from and when, under what production
65187
+ follows now.
65188
+
65189
+ diff [<from>] <to>
65190
+ Compares two deploys' bundles and prints what an agent sees differently:
65191
+ tools added, removed or renamed, descriptions, effects raised or lowered,
65192
+ input schemas, response projections, operations, the server's settings,
65193
+ prompts, resources and the runtime version. With only <to>, a production
65194
+ deploy is compared with the one that went live before it, a preview with
65195
+ production now, and a first deploy lists every tool it added.
64797
65196
 
64798
- With only <to>, a production deploy is compared with the production deploy
64799
- that went live before it, a preview with production as it is now, and a
64800
- first deploy lists every tool it added. Give <from> to compare any two.
65197
+ restore <n>
65198
+ Rebuilds deploy n's files as a new deploy on today's runtime and secrets,
65199
+ after showing what agents would see change and asking. Only a deploy that
65200
+ went live and was replaced can come back. On a server linked to GitHub,
65201
+ production then stops following the default branch: pushes are checked
65202
+ but don't deploy until resume.
64801
65203
 
65204
+ resume
65205
+ Deploys the default branch's newest commit and follows it again.
65206
+
65207
+ --yes Restore or resume without asking, for scripts.
64802
65208
  --server <s> A server by slug, instead of the one this repository is linked to.
64803
65209
  --dir <dir> The repository (default .), for its link.
64804
65210
  ${SITE_HELP}`,
@@ -64814,7 +65220,7 @@ import { join as join8, resolve as resolve5 } from "node:path";
64814
65220
  import { readFileSync as readFileSync8 } from "node:fs";
64815
65221
  import { createServer } from "node:http";
64816
65222
  import { fileURLToPath } from "node:url";
64817
- var file2 = (name2) => fileURLToPath(new URL(`./inspector/${name2}`, import.meta.url));
65223
+ var file2 = (name3) => fileURLToPath(new URL(`./inspector/${name3}`, import.meta.url));
64818
65224
  var STATIC = {
64819
65225
  "/": { file: file2("index.html"), type: "text/html" },
64820
65226
  "/inspector.css": { file: file2("inspector.css"), type: "text/css" },
@@ -64859,13 +65265,13 @@ async function call(req, res, session) {
64859
65265
  if (!fromOwnPage(req))
64860
65266
  return json2(res, 403, { error: "Calls come from the inspector page." });
64861
65267
  const body = await readJson2(req);
64862
- const name2 = body?.name;
65268
+ const name3 = body?.name;
64863
65269
  const args = body?.arguments ?? {};
64864
- if (typeof name2 !== "string" || typeof args !== "object" || args === null || Array.isArray(args)) {
65270
+ if (typeof name3 !== "string" || typeof args !== "object" || args === null || Array.isArray(args)) {
64865
65271
  return json2(res, 400, { error: "Send { name, arguments } with arguments as an object." });
64866
65272
  }
64867
65273
  const started = performance.now();
64868
- const result = await callTool(session.state.serverUrl, session.token, name2, args);
65274
+ const result = await callTool(session.state.serverUrl, session.token, name3, args);
64869
65275
  json2(res, 200, { result, ms: Math.round(performance.now() - started) });
64870
65276
  }
64871
65277
  async function route(req, res, session, port) {
@@ -64905,41 +65311,43 @@ function startInspector(session, host, port) {
64905
65311
  }
64906
65312
 
64907
65313
  // src/dev/report.ts
64908
- function findingLines(findings) {
65314
+ function findingLines(findings, tint = plain) {
64909
65315
  const shown = findings.filter((f) => f.level !== "info");
64910
- const lines = shown.map(findingLine);
65316
+ const lines = shown.map((finding3) => findingLine(finding3, tint));
64911
65317
  const info2 = findings.length - shown.length;
64912
- if (info2 > 0)
64913
- lines.push(`· ${plural2(info2, "note")} from the build; sokie check lists them.`);
65318
+ if (info2 > 0) {
65319
+ lines.push(tint("dim", `· ${plural2(info2, "note")} from the build; sokie check lists them.`));
65320
+ }
64914
65321
  return lines;
64915
65322
  }
64916
- function secretLines(state) {
65323
+ function secretLines(state, tint = plain) {
64917
65324
  const report = state.secrets;
64918
65325
  if (!report)
64919
65326
  return [];
64920
- return [
65327
+ const lines = [
64921
65328
  ...report.missing.map((s) => `! ${s.name} has no value in ${DEV_SECRETS_FILE}. ${s.description}`.trim()),
64922
- ...report.standInsMissing.map((name2) => `! ${name2} is not set in ${DEV_SECRETS_FILE}; tools that call the upstream need it.`),
64923
- ...report.unknown.map((name2) => `! ${name2} in ${DEV_SECRETS_FILE} is not declared in sokie.json, so it is not bound.`)
65329
+ ...report.standInsMissing.map((name3) => `! ${name3} is not set in ${DEV_SECRETS_FILE}; tools that call the upstream need it.`),
65330
+ ...report.unknown.map((name3) => `! ${name3} in ${DEV_SECRETS_FILE} is not declared in sokie.json, so it is not bound.`)
64924
65331
  ];
65332
+ return lines.map((line) => tint("warn", line));
64925
65333
  }
64926
- function createReporter(write) {
65334
+ function createReporter(write, tint = plain) {
64927
65335
  let lastNotes = "";
64928
65336
  let lastRevision = 0;
64929
65337
  return (state) => {
64930
- const notes = [...findingLines(state.findings), ...secretLines(state)].join(`
65338
+ const notes = [...findingLines(state.findings, tint), ...secretLines(state, tint)].join(`
64931
65339
  `);
64932
65340
  if (notes && notes !== lastNotes)
64933
65341
  write(notes);
64934
65342
  lastNotes = notes;
64935
65343
  if (state.status === "failed") {
64936
- write(lastRevision > 0 ? "✗ Build failed; the last good build is still serving." : "✗ Build failed; fix the errors above and save.");
65344
+ write(tint("fail", lastRevision > 0 ? "✗ Build failed; the last good build is still serving." : "✗ Build failed; fix the errors above and save."));
64937
65345
  return;
64938
65346
  }
64939
65347
  const first = lastRevision === 0;
64940
65348
  lastRevision = state.revision;
64941
65349
  const what = `${state.name}: ${plural2(state.toolCount, "tool")}, ${state.accessMode}`;
64942
- write(`${first ? "✓ Running" : "↻ Reloaded"} ${what} (${state.reloadMs}ms)`);
65350
+ write(tint("ok", `${first ? "✓ Running" : "↻ Reloaded"} ${what} (${state.reloadMs}ms)`));
64943
65351
  };
64944
65352
  }
64945
65353
 
@@ -64955,18 +65363,18 @@ async function body(req) {
64955
65363
  }
64956
65364
  function headersOf(req) {
64957
65365
  const headers = new Headers;
64958
- for (const [name2, value] of Object.entries(req.headers)) {
65366
+ for (const [name3, value] of Object.entries(req.headers)) {
64959
65367
  if (value === undefined)
64960
65368
  continue;
64961
65369
  for (const item of Array.isArray(value) ? value : [value])
64962
- headers.append(name2, item);
65370
+ headers.append(name3, item);
64963
65371
  }
64964
65372
  return headers;
64965
65373
  }
64966
65374
  async function relay(response, res) {
64967
65375
  const headers = {};
64968
- response.headers.forEach((value, name2) => {
64969
- headers[name2] = value;
65376
+ response.headers.forEach((value, name3) => {
65377
+ headers[name3] = value;
64970
65378
  });
64971
65379
  const cookies = response.headers.getSetCookie();
64972
65380
  if (cookies.length > 0)
@@ -65078,7 +65486,7 @@ function answerPlatform(request, path, options) {
65078
65486
  if (path === "/caller-key") {
65079
65487
  const apiKey = options.secret(CALLER_KEY);
65080
65488
  if (!apiKey) {
65081
- options.log(`! a tool needs your upstream key: set ${CALLER_KEY} in ${DEV_SECRETS_FILE}`);
65489
+ options.log(`! a tool needs your upstream key: set ${CALLER_KEY} in ${DEV_SECRETS_FILE}`, "warn");
65082
65490
  return platformError(404, "caller_key_missing");
65083
65491
  }
65084
65492
  return Response.json({ apiKey });
@@ -65086,7 +65494,7 @@ function answerPlatform(request, path, options) {
65086
65494
  if (path === "/oauth-token") {
65087
65495
  const accessToken2 = options.secret(OAUTH_TOKEN);
65088
65496
  if (!accessToken2) {
65089
- options.log(`! a tool needs an upstream token: set ${OAUTH_TOKEN} in ${DEV_SECRETS_FILE}`);
65497
+ options.log(`! a tool needs an upstream token: set ${OAUTH_TOKEN} in ${DEV_SECRETS_FILE}`, "warn");
65090
65498
  return platformError(404, "oauth_token_missing");
65091
65499
  }
65092
65500
  return Response.json({ accessToken: accessToken2, tokenType: "Bearer" });
@@ -65102,6 +65510,11 @@ async function forward(request) {
65102
65510
  redirect: "manual"
65103
65511
  });
65104
65512
  }
65513
+ function upstreamTone(status) {
65514
+ if (status >= 500)
65515
+ return "fail";
65516
+ return status >= 400 ? "warn" : undefined;
65517
+ }
65105
65518
  function outboundHandler(options) {
65106
65519
  return async (request) => {
65107
65520
  const url2 = new URL(request.url);
@@ -65111,11 +65524,11 @@ function outboundHandler(options) {
65111
65524
  const where = `${request.method} ${url2.origin}${url2.pathname}`;
65112
65525
  try {
65113
65526
  const response = await forward(request);
65114
- options.log(`→ ${where} ${response.status} ${Math.round(performance.now() - started)}ms`);
65527
+ options.log(`→ ${where} ${response.status} ${Math.round(performance.now() - started)}ms`, upstreamTone(response.status));
65115
65528
  return response;
65116
65529
  } catch (error62) {
65117
65530
  const reason = error62 instanceof Error ? error62.message : String(error62);
65118
- options.log(`✗ ${where} failed: ${reason}`);
65531
+ options.log(`✗ ${where} failed: ${reason}`, "fail");
65119
65532
  throw error62;
65120
65533
  }
65121
65534
  };
@@ -65337,7 +65750,7 @@ class DevSession {
65337
65750
  bindings: this.#bindings(config2, auth2),
65338
65751
  outbound: outboundHandler({
65339
65752
  platformToken: this.#platformToken,
65340
- secret: (name2) => this.#secrets.values.get(name2) || null,
65753
+ secret: (name3) => this.#secrets.values.get(name3) || null,
65341
65754
  log: this.#options.log
65342
65755
  })
65343
65756
  });
@@ -65419,9 +65832,9 @@ async function run5(argv, out) {
65419
65832
  const message = `${DEV_SECRETS_FILE} is not gitignored, so its secrets could be committed. Add .sokie/ to .gitignore and run sokie dev again.`;
65420
65833
  return fail(out, "secrets_tracked", message, EXIT.no);
65421
65834
  }
65422
- const log = (line) => void (out.json ? out.event({ type: "log", line }) : out.line(line));
65835
+ const log = (line, tone) => void (out.json ? out.event({ type: "log", line }) : out.line(line, tone));
65423
65836
  const session = new DevSession({ root, host: values.host, port, log });
65424
- const report = createReporter((text5) => void out.line(text5));
65837
+ const report = createReporter((text5) => void out.line(text5), out.tint);
65425
65838
  session.subscribe((state) => out.json ? void out.event({ type: "build", state }) : report(state));
65426
65839
  const server = await serveWorker(session.fetch, values.host, port);
65427
65840
  await session.start();
@@ -65437,7 +65850,7 @@ async function run5(argv, out) {
65437
65850
  if (session.token)
65438
65851
  await out.line(` Token Bearer ${session.token}`);
65439
65852
  await out.line();
65440
- await out.line(" Watching for edits. Ctrl+C stops.");
65853
+ await out.line(" Watching for edits. Ctrl+C stops.", "dim");
65441
65854
  if (!values["no-open"])
65442
65855
  openInBrowser(urls.inspector);
65443
65856
  let recorded;
@@ -65521,10 +65934,10 @@ function resolveEditor(choice, folder, facts) {
65521
65934
  const words2 = envEditor(facts.env);
65522
65935
  const [command, ...rest] = words2 ?? [];
65523
65936
  if (command) {
65524
- const name2 = basename(command).replace(/\.(exe|cmd|bat)$/i, "");
65937
+ const name3 = basename(command).replace(/\.(exe|cmd|bat)$/i, "");
65525
65938
  const path = /[\\/]/.test(command) ? command : facts.which(command) ?? command;
65526
65939
  return {
65527
- kind: WINDOWED.has(name2) ? "window" : "terminal",
65940
+ kind: WINDOWED.has(name3) ? "window" : "terminal",
65528
65941
  label: command,
65529
65942
  command: path,
65530
65943
  args: [...rest, folder]
@@ -65569,8 +65982,8 @@ function planCheckout(options, facts) {
65569
65982
  const here = cloneOf(options.cwd);
65570
65983
  if (here)
65571
65984
  return { kind: "reuse", root: here };
65572
- const name2 = options.repo.split("/")[1] ?? options.repo;
65573
- return into(join9(options.cwd, name2), "exists but");
65985
+ const name3 = options.repo.split("/")[1] ?? options.repo;
65986
+ return into(join9(options.cwd, name3), "exists but");
65574
65987
  }
65575
65988
  function serverFolder(root, path) {
65576
65989
  const inside = path.replace(/^\.?\/*|\/+$/g, "");
@@ -65652,6 +66065,77 @@ function cloneRepo(url2, root) {
65652
66065
  });
65653
66066
  }
65654
66067
 
66068
+ // src/hosted.ts
66069
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, readdirSync as readdirSync3, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
66070
+ import { dirname as dirname6, join as join11 } from "node:path";
66071
+ function safePath(path) {
66072
+ return path !== "" && !path.startsWith("/") && !path.includes("\\") && !path.split("/").some((part) => part === "" || part === "." || part === "..");
66073
+ }
66074
+ async function downloadFiles(client, serverId, number4, fetchFn = (url2) => fetch(url2)) {
66075
+ const signed = await client.query(fn.serverFiles, {
66076
+ serverId,
66077
+ ...number4 === undefined ? {} : { number: number4 }
66078
+ });
66079
+ if (!signed)
66080
+ return null;
66081
+ const response = await fetchFn(signed.url);
66082
+ if (!response.ok) {
66083
+ throw new DeployError("download_failed", `The files couldn't be downloaded (${response.status}).`);
66084
+ }
66085
+ const parsed = await response.json();
66086
+ const files = new Map;
66087
+ for (const [path, text5] of Object.entries(parsed.files ?? {})) {
66088
+ if (typeof text5 === "string" && safePath(path))
66089
+ files.set(path, text5);
66090
+ }
66091
+ return { files, ...signed.number === undefined ? {} : { number: signed.number } };
66092
+ }
66093
+ function writeFiles(root, files) {
66094
+ for (const [path, text5] of files) {
66095
+ if (!safePath(path))
66096
+ continue;
66097
+ const full = join11(root, path);
66098
+ if (text5 === null) {
66099
+ rmSync2(full, { force: true });
66100
+ continue;
66101
+ }
66102
+ mkdirSync6(dirname6(full), { recursive: true });
66103
+ writeFileSync7(full, text5);
66104
+ }
66105
+ }
66106
+ function isEmptyDir(path) {
66107
+ return !existsSync10(path) || readdirSync3(path).length === 0;
66108
+ }
66109
+ function mergeFiles(base, mine, theirs) {
66110
+ const writes = new Map;
66111
+ const merged = [];
66112
+ const paths = [...new Set([...base.keys(), ...mine.keys(), ...theirs.keys()])].sort();
66113
+ for (const path of paths) {
66114
+ const [b, m, t] = [base.get(path), mine.get(path), theirs.get(path)];
66115
+ if (m === t)
66116
+ continue;
66117
+ if (m === b) {
66118
+ writes.set(path, t ?? null);
66119
+ merged.push({ path, how: t === undefined ? "removed" : "theirs" });
66120
+ } else if (t === b) {
66121
+ merged.push({ path, how: "mine" });
66122
+ } else {
66123
+ writes.set(path, t ?? null);
66124
+ if (m !== undefined)
66125
+ writes.set(`${path}.mine`, m);
66126
+ merged.push({ path, how: "both" });
66127
+ }
66128
+ }
66129
+ return { writes, merged };
66130
+ }
66131
+ function describeFiles(files) {
66132
+ const paths = [...files.keys()];
66133
+ const tools = paths.filter((path) => path.startsWith("tools/")).length;
66134
+ const rest = paths.filter((path) => !path.includes("/"));
66135
+ const parts = [...rest, ...tools > 0 ? [`${tools} ${tools === 1 ? "tool" : "tools"}`] : []];
66136
+ return parts.length <= 1 ? parts[0] ?? "no files" : `${parts.slice(0, -1).join(", ")} and ${parts.at(-1)}`;
66137
+ }
66138
+
65655
66139
  // src/commands/edit.ts
65656
66140
  var TERMINAL2 = () => ({
65657
66141
  cwd: process.cwd(),
@@ -65702,39 +66186,66 @@ async function runEdit(argv, out, deps) {
65702
66186
  }
65703
66187
  slug = server.slug;
65704
66188
  const link = await client.query(fn.link, { serverId: server.serverId });
66189
+ let root;
66190
+ let folder;
66191
+ let cloned = false;
65705
66192
  if (!link) {
65706
- return fail(out, "no_repository", `${slug} isn't linked to a repository, so there's nothing to clone. Its files came from an upload; from the folder you deployed, run \`sokie link <owner/repo> --server ${slug}\` and edit there.`, EXIT.no);
65707
- }
65708
- if (link.broken)
65709
- await out.problem(`Note: the link to ${link.repo} is broken: ${link.broken}`);
65710
- const checkout = planCheckout({ repo: link.repo, cwd, dir: values.dir }, deps.repo);
65711
- if (checkout.kind === "conflict") {
65712
- return fail(out, "dir_in_use", `${checkout.message} Pass --dir <path>.`, EXIT.no);
65713
- }
65714
- if (checkout.kind === "clone") {
65715
- await out.line(`Cloning ${link.repo} into ${checkout.root}…`);
65716
- if (!await deps.clone(checkout.url, checkout.root)) {
65717
- return fail(out, "clone_failed", `git couldn't clone ${checkout.url}. Check you can read it on GitHub, or clone it yourself and pass --dir.`, EXIT.no);
66193
+ root = folder = resolve7(cwd, values.dir ?? slug);
66194
+ const here = readLink(folder, info2.site);
66195
+ if (here?.slug === slug) {
66196
+ await out.line(`Using your copy in ${folder}, from #${here.base ?? "?"}. sokie pull brings in what changed since.`);
66197
+ } else {
66198
+ if (!isEmptyDir(folder)) {
66199
+ return fail(out, "dir_in_use", `${folder} isn't empty. Pass --dir <path>.`, EXIT.no);
66200
+ }
66201
+ const got = await (deps.download ?? downloadFiles)(client, server.serverId);
66202
+ if (!got) {
66203
+ return fail(out, "nothing_deployed", `${slug} has no deploy yet, so no files.`, EXIT.no);
66204
+ }
66205
+ writeFiles(folder, got.files);
66206
+ writeLink(folder, info2.site, {
66207
+ serverId: server.serverId,
66208
+ slug,
66209
+ ...got.number === undefined ? {} : { base: got.number }
66210
+ });
66211
+ cloned = true;
66212
+ await out.line(`Downloaded production's files (#${got.number ?? "?"}) to ${folder}: ${describeFiles(got.files)}.`, "ok");
66213
+ await out.line("sokie deploy puts your edits live; sokie link moves the server to GitHub.", "dim");
65718
66214
  }
65719
66215
  } else {
65720
- await out.line(`Using your clone of ${link.repo} in ${checkout.root}.`);
66216
+ if (link.broken)
66217
+ await out.problem(`Note: the link to ${link.repo} is broken: ${link.broken}`);
66218
+ const checkout = planCheckout({ repo: link.repo, cwd, dir: values.dir }, deps.repo);
66219
+ if (checkout.kind === "conflict") {
66220
+ return fail(out, "dir_in_use", `${checkout.message} Pass --dir <path>.`, EXIT.no);
66221
+ }
66222
+ if (checkout.kind === "clone") {
66223
+ await out.line(`Cloning ${link.repo} into ${checkout.root}…`);
66224
+ if (!await deps.clone(checkout.url, checkout.root)) {
66225
+ return fail(out, "clone_failed", `git couldn't clone ${checkout.url}. Check you can read it on GitHub, or clone it yourself and pass --dir.`, EXIT.no);
66226
+ }
66227
+ } else {
66228
+ await out.line(`Using your clone of ${link.repo} in ${checkout.root}.`);
66229
+ }
66230
+ root = checkout.root;
66231
+ folder = serverFolder(checkout.root, link.path);
66232
+ cloned = checkout.kind === "clone";
66233
+ writeLink(folder, info2.site, { serverId: server.serverId, slug });
65721
66234
  }
65722
- const folder = serverFolder(checkout.root, link.path);
65723
- writeLink(folder, info2.site, { serverId: server.serverId, slug });
65724
66235
  ensureIgnored(folder, ".sokie/");
65725
- const launch = resolveEditor(editor, checkout.root, deps.editors);
65726
- const opened = launch.kind === "none" ? false : await openEditor(launch, checkout.root, dev, out, deps);
66236
+ const launch = resolveEditor(editor, root, deps.editors);
66237
+ const opened = launch.kind === "none" ? false : await openEditor(launch, root, dev, out, deps);
65727
66238
  if (launch.kind === "none") {
65728
66239
  await out.problem(launch.reason);
65729
- await out.line(`The folder is ${checkout.root}.`);
66240
+ await out.line(`The folder is ${root}.`);
65730
66241
  }
65731
66242
  const summary = {
65732
66243
  ok: true,
65733
66244
  server: slug,
65734
- repo: link.repo,
65735
- dir: checkout.root,
66245
+ repo: link?.repo ?? null,
66246
+ dir: root,
65736
66247
  serverDir: folder,
65737
- cloned: checkout.kind === "clone",
66248
+ cloned,
65738
66249
  editor: launch.kind === "none" ? null : { kind: launch.kind, command: launch.command, opened },
65739
66250
  dev
65740
66251
  };
@@ -65750,13 +66261,18 @@ async function runEdit(argv, out, deps) {
65750
66261
  var editCommand = {
65751
66262
  name: "edit",
65752
66263
  synopsis: "sokie edit [<server-slug>] [--editor vscode|cursor|zed] [--dir <path>] [--no-dev] [--site <url>]",
65753
- summary: "Open a server's repository in your editor, with sokie dev running.",
66264
+ summary: "Open a server's files in your editor, with sokie dev running.",
65754
66265
  help: `Finds the repository the server is linked to and uses your clone of it:
65755
66266
  the folder you're in, or --dir. With neither, it clones into ./<name>, as
65756
66267
  git clone would. Then it opens the folder in your editor and runs sokie dev
65757
66268
  in it, reloading on every save. Open a pull request for a preview; merge
65758
66269
  it to the default branch to deploy.
65759
66270
 
66271
+ A server with no repository keeps its files on Sokie: they're downloaded
66272
+ into ./<slug> (or --dir, which must be empty), and sokie deploy from there
66273
+ puts edits live. It won't deploy over a change made in the app since the
66274
+ download; sokie pull brings that in first.
66275
+
65760
66276
  With no slug, the server this folder is linked to.
65761
66277
 
65762
66278
  --editor <e> vscode, cursor or zed, through its command on PATH. Without it,
@@ -65768,15 +66284,15 @@ ${SITE_HELP}`,
65768
66284
  };
65769
66285
 
65770
66286
  // src/commands/fmt.ts
65771
- import { existsSync as existsSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "node:fs";
65772
- import { join as join11, resolve as resolve8 } from "node:path";
66287
+ import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync8 } from "node:fs";
66288
+ import { join as join12, resolve as resolve8 } from "node:path";
65773
66289
  async function run6(argv, out) {
65774
66290
  const { values, positionals } = parseCommandArgs(argv, {
65775
66291
  check: { type: "boolean", default: false }
65776
66292
  });
65777
66293
  const root = resolve8(positionals[0] ?? ".");
65778
- const path = join11(root, SERVER_CONFIG_FILE);
65779
- if (!existsSync10(path)) {
66294
+ const path = join12(root, SERVER_CONFIG_FILE);
66295
+ if (!existsSync11(path)) {
65780
66296
  return fail(out, "no_server", `No ${SERVER_CONFIG_FILE} in ${root}.`, EXIT.no);
65781
66297
  }
65782
66298
  const content = readFileSync9(path, "utf8");
@@ -65790,13 +66306,16 @@ async function run6(argv, out) {
65790
66306
  const canonical = canonicalServerJson(raw);
65791
66307
  const formatted = canonical === content;
65792
66308
  if (values.check) {
65793
- await out.line(formatted ? `${SERVER_CONFIG_FILE} is formatted.` : `${SERVER_CONFIG_FILE} is not formatted. Run sokie fmt.`);
66309
+ if (formatted)
66310
+ await out.line(`${SERVER_CONFIG_FILE} is formatted.`, "ok");
66311
+ else
66312
+ await out.line(`${SERVER_CONFIG_FILE} is not formatted. Run sokie fmt.`, "fail");
65794
66313
  await out.result({ ok: formatted, file: SERVER_CONFIG_FILE, changed: false });
65795
66314
  return formatted ? EXIT.ok : EXIT.no;
65796
66315
  }
65797
66316
  if (!formatted)
65798
- writeFileSync7(path, canonical);
65799
- await out.line(formatted ? `${SERVER_CONFIG_FILE} is already formatted.` : `Formatted ${SERVER_CONFIG_FILE}.`);
66317
+ writeFileSync8(path, canonical);
66318
+ await out.line(formatted ? `${SERVER_CONFIG_FILE} is already formatted.` : `Formatted ${SERVER_CONFIG_FILE}.`, "ok");
65800
66319
  await out.result({ ok: true, file: SERVER_CONFIG_FILE, changed: !formatted });
65801
66320
  return EXIT.ok;
65802
66321
  }
@@ -65811,33 +66330,33 @@ the file would change.`,
65811
66330
  };
65812
66331
 
65813
66332
  // src/commands/init.ts
65814
- import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "node:fs";
65815
- import { basename as basename2, dirname as dirname6, extname, join as join12, relative as relative2, resolve as resolve9, sep as sep3 } from "node:path";
65816
- import { stdin as stdin3, stdout } from "node:process";
66333
+ import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "node:fs";
66334
+ import { basename as basename2, dirname as dirname7, extname, join as join13, relative as relative2, resolve as resolve9, sep as sep3 } from "node:path";
66335
+ import { stdin as stdin4, stdout } from "node:process";
65817
66336
  var FETCH_TIMEOUT_MS = 30000;
65818
66337
  var TERMINAL3 = {
65819
- interactive: stdin3.isTTY === true && stdout.isTTY === true,
66338
+ interactive: stdin4.isTTY === true && stdout.isTTY === true,
65820
66339
  askSecret: readSecretValue
65821
66340
  };
65822
66341
  function perCaller(auth2) {
65823
66342
  return auth2?.type === "apiKey" && auth2.key === "perCaller";
65824
66343
  }
65825
- async function offerCallerKey(root, name2, out, deps) {
66344
+ async function offerCallerKey(root, name3, out, deps) {
65826
66345
  if (readDevSecrets(root).values.get(CALLER_KEY)) {
65827
- await out.line(`Your key is already in ${DEV_SECRETS_FILE}, so sokie dev has it.`);
66346
+ await out.line(`Your key is already in ${DEV_SECRETS_FILE}, so sokie dev has it.`, "ok");
65828
66347
  return "already_set";
65829
66348
  }
65830
66349
  if (secretsFileTracked(root) === true) {
65831
- await out.line(`! ${DEV_SECRETS_FILE} is not gitignored, so init didn't ask for your key. Add .sokie/ to .gitignore, then set ${CALLER_KEY} in ${DEV_SECRETS_FILE} for sokie dev.`);
66350
+ await out.line(`! ${DEV_SECRETS_FILE} is not gitignored, so init didn't ask for your key. Add .sokie/ to .gitignore, then set ${CALLER_KEY} in ${DEV_SECRETS_FILE} for sokie dev.`, "warn");
65832
66351
  return "not_set";
65833
66352
  }
65834
- const key = deps.interactive && !out.json ? (await deps.askSecret(`Your key for ${name2}, for sokie dev (Enter to skip)`)).trim() : "";
66353
+ const key = deps.interactive && !out.json ? (await deps.askSecret(`Your key for ${name3}, for sokie dev (Enter to skip)`)).trim() : "";
65835
66354
  if (!key) {
65836
- await out.line(`! sokie dev needs your key for ${name2}: set ${CALLER_KEY} in ${DEV_SECRETS_FILE}, which git ignores.`);
66355
+ await out.line(`! sokie dev needs your key for ${name3}: set ${CALLER_KEY} in ${DEV_SECRETS_FILE}, which git ignores.`, "warn");
65837
66356
  return "not_set";
65838
66357
  }
65839
66358
  writeDevSecret(root, CALLER_KEY, key);
65840
- await out.line(`Saved your key to ${DEV_SECRETS_FILE} for sokie dev (ignored by git).`);
66359
+ await out.line(`Saved your key to ${DEV_SECRETS_FILE} for sokie dev (ignored by git).`, "ok");
65841
66360
  return "saved";
65842
66361
  }
65843
66362
  async function loadSpec(spec) {
@@ -65848,7 +66367,7 @@ async function loadSpec(spec) {
65848
66367
  return { content: await response.text(), url: spec };
65849
66368
  }
65850
66369
  const local = resolve9(spec);
65851
- if (!existsSync11(local))
66370
+ if (!existsSync12(local))
65852
66371
  throw new Error(`There is no file at ${spec}.`);
65853
66372
  return { content: readFileSync10(local, "utf8"), local };
65854
66373
  }
@@ -65867,8 +66386,8 @@ async function runInit(argv, out, deps) {
65867
66386
  if (!spec)
65868
66387
  throw new UsageError("Name the spec: a file path or an https URL.");
65869
66388
  const root = resolve9(dir);
65870
- if (existsSync11(join12(root, SERVER_CONFIG_FILE))) {
65871
- const message = `${join12(dir, SERVER_CONFIG_FILE)} already exists; this is already a server. sokie check reviews it.`;
66389
+ if (existsSync12(join13(root, SERVER_CONFIG_FILE))) {
66390
+ const message = `${join13(dir, SERVER_CONFIG_FILE)} already exists; this is already a server. sokie check reviews it.`;
65872
66391
  return fail(out, "already_initialised", message, EXIT.no);
65873
66392
  }
65874
66393
  let loaded;
@@ -65897,20 +66416,20 @@ async function runInit(argv, out, deps) {
65897
66416
  const copySpec = !loaded.local || relative2(root, loaded.local).startsWith("..");
65898
66417
  if (copySpec)
65899
66418
  plan.files.set(specPath, loaded.content);
65900
- const taken = [...plan.files.keys()].filter((path) => existsSync11(join12(root, path)));
66419
+ const taken = [...plan.files.keys()].filter((path) => existsSync12(join13(root, path)));
65901
66420
  if (taken.length > 0) {
65902
66421
  const message = `Not overwriting ${taken.slice(0, 3).join(", ")}${taken.length > 3 ? ` and ${taken.length - 3} more` : ""}. Move them aside, or init into an empty directory.`;
65903
66422
  return fail(out, "files_exist", message, EXIT.no);
65904
66423
  }
65905
66424
  const build2 = buildFromFiles(new Map([...plan.files, [specPath, loaded.content]]));
65906
66425
  for (const [path, content] of plan.files) {
65907
- mkdirSync6(dirname6(join12(root, path)), { recursive: true });
65908
- writeFileSync8(join12(root, path), content);
66426
+ mkdirSync7(dirname7(join13(root, path)), { recursive: true });
66427
+ writeFileSync9(join13(root, path), content);
65909
66428
  }
65910
66429
  const ignored = ensureIgnored(root, ".sokie/");
65911
66430
  const findings = sortFindings(build2.findings);
65912
- const name2 = build2.config?.name ?? values.name ?? basename2(root);
65913
- await out.line(`Created ${name2} in ${dir}:`);
66431
+ const name3 = build2.config?.name ?? values.name ?? basename2(root);
66432
+ await out.line(`Created ${name3} in ${dir}:`, "ok");
65914
66433
  await out.line(` ${SERVER_CONFIG_FILE}`);
65915
66434
  if (copySpec)
65916
66435
  await out.line(` ${specPath}${loaded.url ? ` (from ${loaded.url})` : ""}`);
@@ -65918,16 +66437,20 @@ async function runInit(argv, out, deps) {
65918
66437
  if (ignored)
65919
66438
  await out.line(" .gitignore added .sokie/, where sokie dev keeps local secrets");
65920
66439
  for (const note of plan.notes)
65921
- await out.line(`! ${note}`);
66440
+ await out.line(`! ${note}`, "warn");
65922
66441
  await out.line();
65923
66442
  for (const finding3 of findings)
65924
- await out.line(findingLine(finding3));
65925
- const callerKey = perCaller(read.facts.auth) ? await offerCallerKey(root, name2, out, deps) : undefined;
65926
- await out.line(build2.bundle ? "Next: read each tool's description and set its risk, then run sokie dev." : "Fix the errors above, then run sokie check.");
66443
+ await out.line(findingLine(finding3, out.tint));
66444
+ const callerKey = perCaller(read.facts.auth) ? await offerCallerKey(root, name3, out, deps) : undefined;
66445
+ if (build2.bundle) {
66446
+ await out.line("Next: read each tool's description and set its risk, then run sokie dev.");
66447
+ } else {
66448
+ await out.line("Fix the errors above, then run sokie check.", "fail");
66449
+ }
65927
66450
  await out.result({
65928
66451
  ok: build2.bundle !== null,
65929
66452
  dir: root,
65930
- name: name2,
66453
+ name: name3,
65931
66454
  files: [...plan.files.keys(), ...ignored ? [".gitignore"] : []],
65932
66455
  tools: plan.tools,
65933
66456
  notes: plan.notes,
@@ -66132,8 +66655,8 @@ async function run7(argv, out) {
66132
66655
  if (values["no-browser"]) {
66133
66656
  redirectUri = REGISTERED_REDIRECT.replace("127.0.0.1", `127.0.0.1:${PASTE_PORT}`);
66134
66657
  await out.line("Open this address in a browser and approve:");
66135
- await out.line(authorizeUrl(info2, { clientId, redirectUri, challenge, state }));
66136
- await out.line("The browser then fails to load a 127.0.0.1 page. That's expected.");
66658
+ await out.line(authorizeUrl(info2, { clientId, redirectUri, challenge, state }), "dim");
66659
+ await out.line("The browser then fails to load a 127.0.0.1 page. That's expected.", "dim");
66137
66660
  const pasted = readCallback(await readLine("Paste the address it landed on:"), state);
66138
66661
  if (!pasted.ok)
66139
66662
  return fail(out, "login_refused", pasted.message, EXIT.no);
@@ -66143,7 +66666,7 @@ async function run7(argv, out) {
66143
66666
  redirectUri = server.redirectUri;
66144
66667
  const url2 = authorizeUrl(info2, { clientId, redirectUri, challenge, state });
66145
66668
  await out.line("Opening your browser to sign in. If it doesn't open, go to:");
66146
- await out.line(url2);
66669
+ await out.line(url2, "dim");
66147
66670
  openBrowser(url2);
66148
66671
  try {
66149
66672
  ({ code: code2, iss } = await server.wait(state, WAIT_MS3));
@@ -66160,7 +66683,7 @@ async function run7(argv, out) {
66160
66683
  writeCredentials(info2.site, { clientId, ...tokens });
66161
66684
  const me = await (await signedIn(info2)).query(fn.me, {});
66162
66685
  writeCredentials(info2.site, { clientId, ...tokens, email: me.email });
66163
- await out.line(`Signed in to ${info2.site} as ${me.email}.`);
66686
+ await out.line(`Signed in to ${info2.site} as ${me.email}.`, "ok");
66164
66687
  await out.result({ ok: true, site: info2.site, email: me.email });
66165
66688
  return EXIT.ok;
66166
66689
  }
@@ -66198,7 +66721,7 @@ async function run8(argv, out) {
66198
66721
  revoked = false;
66199
66722
  }
66200
66723
  writeCredentials(site, { clientId: stored.clientId });
66201
- await out.line(revoked ? `Signed out of ${site}.` : `Signed out here, but ${site} couldn't be reached to end the sign-in. Disconnect it in Settings › Connected apps.`);
66724
+ await out.line(revoked ? `Signed out of ${site}.` : `Signed out here, but ${site} couldn't be reached to end the sign-in. Disconnect it in Settings › Connected apps.`, revoked ? "ok" : "warn");
66202
66725
  await out.result({ ok: true, site, signedOut: true, revoked });
66203
66726
  return EXIT.ok;
66204
66727
  }
@@ -66261,13 +66784,13 @@ async function run9(argv, out) {
66261
66784
  const current = live ? liveLine(live) : null;
66262
66785
  if (!values.follow) {
66263
66786
  for (const entry of [...first].reverse())
66264
- await out.line(logLine(entry));
66787
+ await out.line(logLine(entry, out.tint));
66265
66788
  if (first.length === 0) {
66266
66789
  const { days: days2 } = await client.query(fn.logRetention, { serverId: server.serverId });
66267
66790
  await out.line(`${server.slug} has no calls in ${lastDays(days2)}.`);
66268
66791
  }
66269
66792
  if (current)
66270
- await out.line(current);
66793
+ await out.line(current, "dim");
66271
66794
  await out.result({
66272
66795
  ok: true,
66273
66796
  server: server.slug,
@@ -66278,9 +66801,9 @@ async function run9(argv, out) {
66278
66801
  }
66279
66802
  let since = { at: 0, ids: new Set };
66280
66803
  let batch = first;
66281
- await out.line(`Following ${server.slug}. Ctrl+C stops.`);
66804
+ await out.line(`Following ${server.slug}. Ctrl+C stops.`, "dim");
66282
66805
  if (current)
66283
- await out.line(current);
66806
+ await out.line(current, "dim");
66284
66807
  for (;; ) {
66285
66808
  const next = unseen(batch, since);
66286
66809
  since = next.since;
@@ -66288,7 +66811,7 @@ async function run9(argv, out) {
66288
66811
  if (out.json)
66289
66812
  await out.event({ type: "call", ...entry });
66290
66813
  else
66291
- await out.line(logLine(entry));
66814
+ await out.line(logLine(entry, out.tint));
66292
66815
  }
66293
66816
  await sleep2(FOLLOW_EVERY_MS);
66294
66817
  batch = await read(MAX_LIMIT2);
@@ -66321,8 +66844,97 @@ ${SITE_HELP}`,
66321
66844
  run: run9
66322
66845
  };
66323
66846
 
66324
- // src/commands/secrets.ts
66847
+ // src/commands/pull.ts
66325
66848
  import { resolve as resolve12 } from "node:path";
66849
+ function mergedLine(entry, to) {
66850
+ const path = ` ${entry.path.padEnd(28)}`;
66851
+ switch (entry.how) {
66852
+ case "theirs":
66853
+ return { text: `${path} taken from #${to}` };
66854
+ case "removed":
66855
+ return { text: `${path} removed, as in #${to}` };
66856
+ case "mine":
66857
+ return { text: `${path} yours kept: you changed it, #${to} didn't`, tone: "dim" };
66858
+ case "both":
66859
+ return {
66860
+ text: `${path} changed on both sides, so yours is kept as ${entry.path}.mine`,
66861
+ tone: "warn"
66862
+ };
66863
+ }
66864
+ }
66865
+ async function runPull(argv, out, deps) {
66866
+ const { values, positionals } = parseCommandArgs(argv, { ...SITE_OPTION });
66867
+ const root = resolve12(positionals[0] ?? ".");
66868
+ const download = deps.download ?? downloadFiles;
66869
+ return deps.signedIn(out, values.site, async (info2, client) => {
66870
+ try {
66871
+ const link = readLink(root, info2.site);
66872
+ if (!link) {
66873
+ return fail(out, "not_linked", `No server is linked here for ${info2.site}. sokie edit <slug> makes a folder to pull into.`, EXIT.no);
66874
+ }
66875
+ const github = await client.query(fn.link, { serverId: link.serverId });
66876
+ if (github) {
66877
+ return fail(out, "has_repository", `${link.slug} deploys from ${github.repo}; git pull brings in its changes.`, EXIT.no);
66878
+ }
66879
+ if (link.base === undefined) {
66880
+ return fail(out, "no_base", `This folder doesn't say which deploy its files came from, so there's nothing to compare. sokie edit ${link.slug} --dir <empty folder> makes a fresh copy.`, EXIT.no);
66881
+ }
66882
+ const theirs = await download(client, link.serverId);
66883
+ if (!theirs || theirs.number === undefined) {
66884
+ return fail(out, "nothing_deployed", `${link.slug} has no deploy to pull.`, EXIT.no);
66885
+ }
66886
+ const to = theirs.number;
66887
+ if (to === link.base) {
66888
+ await out.line(`Up to date with #${to}, production.`, "ok");
66889
+ await out.result({ ok: true, server: link.slug, from: link.base, to, files: [] });
66890
+ return EXIT.ok;
66891
+ }
66892
+ const base = await download(client, link.serverId, link.base);
66893
+ if (!base) {
66894
+ return fail(out, "base_gone", `#${link.base}'s files aren't on Sokie any more.`, EXIT.no);
66895
+ }
66896
+ const mine = (deps.readFiles ?? readRepoFiles)(root);
66897
+ const { writes, merged } = mergeFiles(base.files, mine, theirs.files);
66898
+ writeFiles(root, writes);
66899
+ writeLink(root, info2.site, { ...link, base: to });
66900
+ await out.line(`#${link.base} → #${to}, production`, "strong");
66901
+ for (const entry of merged) {
66902
+ const line = mergedLine(entry, to);
66903
+ await out.line(line.text, line.tone);
66904
+ }
66905
+ const both = merged.filter((entry) => entry.how === "both").length;
66906
+ const yours = merged.some((entry) => entry.how === "mine" || entry.how === "both");
66907
+ await out.line(both > 0 ? `Up to date with #${to}. Compare each .mine file with its file and delete it (sokie check warns while one is left), then sokie deploy.` : `Up to date with #${to}.${yours ? " sokie deploy puts your changes live." : ""}`, both > 0 ? "warn" : "ok");
66908
+ await out.result({ ok: true, server: link.slug, from: link.base, to, files: merged });
66909
+ return EXIT.ok;
66910
+ } catch (error62) {
66911
+ if (error62 instanceof DeployError)
66912
+ return fail(out, error62.code, error62.message, EXIT.no);
66913
+ throw error62;
66914
+ }
66915
+ });
66916
+ }
66917
+ var pullCommand = {
66918
+ name: "pull",
66919
+ synopsis: "sokie pull [dir] [--site <url>]",
66920
+ summary: "Bring a folder from sokie edit up to date with production.",
66921
+ help: `For a server with no repository, whose files Sokie keeps: brings the
66922
+ folder sokie edit made (default .) up to date with what production runs
66923
+ now, such as an edit made in the app or a restore, without losing yours.
66924
+
66925
+ File by file, from the deploy the folder's files came from: a file only
66926
+ production changed is taken, a file only you changed is kept, and a file
66927
+ both changed takes production's, with yours kept beside it as <file>.mine.
66928
+ sokie deploy refuses files older than production until they're pulled.
66929
+
66930
+ A server linked to a repository gets its changes with git pull instead.
66931
+
66932
+ ${SITE_HELP}`,
66933
+ run: (argv, out) => runPull(argv, out, { signedIn: withSignedIn })
66934
+ };
66935
+
66936
+ // src/commands/secrets.ts
66937
+ import { resolve as resolve13 } from "node:path";
66326
66938
  var LIVE = {
66327
66939
  updated: "The running server has it now.",
66328
66940
  not_deployed: "It's bound at the first deploy.",
@@ -66334,14 +66946,14 @@ async function run10(argv, out) {
66334
66946
  server: { type: "string" },
66335
66947
  dir: { type: "string" }
66336
66948
  });
66337
- const [verb, name2] = positionals;
66949
+ const [verb, name3] = positionals;
66338
66950
  if (verb !== "list" && verb !== "set" && verb !== "unset") {
66339
66951
  throw new UsageError("Say list, set NAME or unset NAME.");
66340
66952
  }
66341
- if (verb !== "list" && (!name2 || !SECRET_NAME.test(name2) || name2.startsWith("SOKIE_"))) {
66953
+ if (verb !== "list" && (!name3 || !SECRET_NAME.test(name3) || name3.startsWith("SOKIE_"))) {
66342
66954
  throw new UsageError("Give the secret's name as sokie.json declares it, e.g. TASKS_API_KEY.");
66343
66955
  }
66344
- const root = resolve12(values.dir ?? ".");
66956
+ const root = resolve13(values.dir ?? ".");
66345
66957
  return withSignedIn(out, values.site, async (info2, client) => {
66346
66958
  try {
66347
66959
  const slug = values.server ?? readLink(root, info2.site)?.slug;
@@ -66363,20 +66975,21 @@ async function run10(argv, out) {
66363
66975
  cursor = page2.continueCursor;
66364
66976
  }
66365
66977
  for (const secret of secrets) {
66366
- await out.line(`${secret.name} set ${new Date(secret.updatedAt).toISOString().slice(0, 10)}`);
66978
+ const day = new Date(secret.updatedAt).toISOString().slice(0, 10);
66979
+ await out.line(`${secret.name} ${out.tint("dim", `set ${day}`)}`);
66367
66980
  }
66368
66981
  if (secrets.length === 0)
66369
66982
  await out.line(`${server.slug} has no secrets set.`);
66370
66983
  await out.result({ ok: true, server: server.slug, secrets });
66371
66984
  return EXIT.ok;
66372
66985
  }
66373
- const secretName2 = name2 ?? "";
66986
+ const secretName2 = name3 ?? "";
66374
66987
  const result = verb === "set" ? await client.action(fn.setSecret, {
66375
66988
  serverId: server.serverId,
66376
66989
  name: secretName2,
66377
66990
  value: await readSecretValue(`${secretName2} for ${server.slug}`)
66378
66991
  }) : await client.action(fn.removeSecret, { serverId: server.serverId, name: secretName2 });
66379
- await out.line(`${verb === "set" ? "Set" : "Removed"} ${secretName2} on ${server.slug}. ${LIVE[result.live]}`);
66992
+ await out.line(`${verb === "set" ? "Set" : "Removed"} ${secretName2} on ${server.slug}. ${LIVE[result.live]}`, result.live === "failed" ? "warn" : "ok");
66380
66993
  await out.result({ ok: true, server: server.slug, name: secretName2, live: result.live });
66381
66994
  return EXIT.ok;
66382
66995
  } catch (error62) {
@@ -66401,7 +67014,7 @@ ${SITE_HELP}`,
66401
67014
  };
66402
67015
 
66403
67016
  // src/commands/test.ts
66404
- import { resolve as resolve13 } from "node:path";
67017
+ import { resolve as resolve14 } from "node:path";
66405
67018
 
66406
67019
  // src/test-board.ts
66407
67020
  var PASSES_SHOWN = 10;
@@ -66413,15 +67026,15 @@ function columnsFor(cases) {
66413
67026
  tool: Math.min(TOOL_MAX, Math.max(4, ...cases.map((c) => c.tool.length)))
66414
67027
  };
66415
67028
  }
66416
- function caseLines(run11, columns) {
67029
+ function caseLines(run11, columns, tint = plain) {
66417
67030
  const mark = run11.verdict.passed ? "✓" : "✕";
66418
67031
  const ms = `${run11.ms} ms`.padStart(8);
66419
67032
  const head = ` ${mark} ${run11.testCase.name.padEnd(columns.name)} ${run11.testCase.tool.padEnd(columns.tool)}${ms}`;
66420
67033
  if (run11.verdict.passed)
66421
- return [head];
66422
- return [head, ...run11.verdict.failures.map((failure) => ` ${failure}`)];
67034
+ return [tint("ok", head)];
67035
+ return [tint("fail", head), ...run11.verdict.failures.map((failure) => ` ${failure}`)];
66423
67036
  }
66424
- function headerLine(running, where, notHere, target) {
67037
+ function headerLine2(running, where, notHere, target) {
66425
67038
  const cases = `${running} ${running === 1 ? "case" : "cases"} against ${where}`;
66426
67039
  if (notHere === 0)
66427
67040
  return cases;
@@ -66457,7 +67070,7 @@ function caseTarget(target) {
66457
67070
  async function runCases(out, deps, plan, target, endpointFor, all) {
66458
67071
  const first = await endpointFor();
66459
67072
  const where = target.kind === "dev" ? `sokie dev (${first.url})` : new URL(first.url).host;
66460
- await out.line(headerLine(plan.cases.length, where, plan.notHere, targetName(target)));
67073
+ await out.line(headerLine2(plan.cases.length, where, plan.notHere, targetName(target)), "dim");
66461
67074
  await out.line();
66462
67075
  const columns = columnsFor(plan.cases);
66463
67076
  const runs = [];
@@ -66483,16 +67096,16 @@ async function runCases(out, deps, plan, target, endpointFor, all) {
66483
67096
  if (run11.verdict.passed && show)
66484
67097
  shownPasses += 1;
66485
67098
  if (show)
66486
- for (const line of caseLines(run11, columns))
67099
+ for (const line of caseLines(run11, columns, out.tint))
66487
67100
  await out.line(line);
66488
67101
  }
66489
67102
  const passed = runs.filter((run11) => run11.verdict.passed).length;
66490
67103
  const failed = runs.length - passed;
66491
67104
  const hidden = hiddenLine(passed - shownPasses);
66492
67105
  if (hidden)
66493
- await out.line(hidden);
67106
+ await out.line(hidden, "dim");
66494
67107
  await out.line();
66495
- await out.line(summaryLine2(passed, failed));
67108
+ await out.line(summaryLine2(passed, failed), failed === 0 ? "ok" : "fail");
66496
67109
  await out.result({
66497
67110
  ok: failed === 0,
66498
67111
  target: targetName(target),
@@ -66520,7 +67133,7 @@ async function runTest(argv, out, deps) {
66520
67133
  if (target.kind === "dev" && values.server !== undefined) {
66521
67134
  throw new UsageError("--server picks a deploy: add --preview <n> or --production.");
66522
67135
  }
66523
- const root = resolve13(values.dir ?? ".");
67136
+ const root = resolve14(values.dir ?? ".");
66524
67137
  const { definition } = buildFromFiles(readRepoFiles(root));
66525
67138
  if (!definition) {
66526
67139
  const message = "This repository has errors, so its cases can't be read. sokie check lists them.";
@@ -66599,35 +67212,35 @@ ${SITE_HELP}`,
66599
67212
  };
66600
67213
 
66601
67214
  // src/commands/tools.ts
66602
- import { resolve as resolve14 } from "node:path";
67215
+ import { resolve as resolve15 } from "node:path";
66603
67216
  async function run11(argv, out) {
66604
67217
  const { values, positionals } = parseCommandArgs(argv, {
66605
67218
  dir: { type: "string" },
66606
67219
  all: { type: "boolean", default: false },
66607
67220
  unexposed: { type: "boolean", default: false }
66608
67221
  });
66609
- const [verb, name2, ...extra] = positionals;
67222
+ const [verb, name3, ...extra] = positionals;
66610
67223
  if (verb !== undefined && verb !== "show") {
66611
67224
  throw new UsageError(`Say show <name>, or nothing to list them; "${verb}" isn't one.`);
66612
67225
  }
66613
- if (verb === "show" && (!name2 || extra.length > 0)) {
67226
+ if (verb === "show" && (!name3 || extra.length > 0)) {
66614
67227
  throw new UsageError("Give one tool's name: sokie tools show list_invoices.");
66615
67228
  }
66616
67229
  if (verb === "show" && (values.all || values.unexposed)) {
66617
67230
  throw new UsageError("--all and --unexposed are for the list, not show.");
66618
67231
  }
66619
- const files = readRepoFiles(resolve14(values.dir ?? "."));
67232
+ const files = readRepoFiles(resolve15(values.dir ?? "."));
66620
67233
  const build2 = buildFromFiles(files);
66621
67234
  const { bundle, config: config2, definition } = build2;
66622
67235
  if (!bundle || !config2 || !definition)
66623
67236
  return notBuildable(out, build2);
66624
67237
  const rows = toolRows(definition, build2.findings);
66625
67238
  const { unexposed } = build2;
66626
- if (name2 !== undefined)
66627
- return show(out, rows, name2, definition, bundle);
67239
+ if (name3 !== undefined)
67240
+ return show(out, rows, name3, definition, bundle);
66628
67241
  if (values.unexposed)
66629
67242
  return listUnexposed(out, unexposed);
66630
- for (const line of listLines(rows, unexposed.length, values.all))
67243
+ for (const line of listLines(rows, unexposed.length, values.all, out.tint))
66631
67244
  await out.line(line);
66632
67245
  await out.result({ ok: true, server: bundle.name, tools: rows, unexposed: unexposed.length });
66633
67246
  return EXIT.ok;
@@ -66635,20 +67248,20 @@ async function run11(argv, out) {
66635
67248
  async function notBuildable(out, build2) {
66636
67249
  const errors5 = sortFindings(build2.findings).filter((finding3) => finding3.level === "error");
66637
67250
  for (const finding3 of errors5)
66638
- await out.line(findingLine(finding3));
67251
+ await out.line(findingLine(finding3, out.tint));
66639
67252
  if (errors5.length > 0)
66640
67253
  await out.line();
66641
67254
  return fail(out, "not_buildable", `${plural2(errors5.length, "error")} ${errors5.length === 1 ? "stops" : "stop"} this repository from building, so its tools can't be read. sokie check lists everything.`, EXIT.no);
66642
67255
  }
66643
- async function show(out, rows, name2, definition, bundle) {
66644
- const row = rows.find((candidate) => candidate.name === name2);
67256
+ async function show(out, rows, name3, definition, bundle) {
67257
+ const row = rows.find((candidate) => candidate.name === name3);
66645
67258
  if (!row) {
66646
- const near = rows.find((candidate) => candidate.name.toLowerCase() === name2.toLowerCase());
67259
+ const near = rows.find((candidate) => candidate.name.toLowerCase() === name3.toLowerCase());
66647
67260
  const hint = near ? ` Did you mean ${near.name}?` : " sokie tools lists them.";
66648
- return fail(out, "unknown_tool", `No tool named ${name2} in tools/.${hint}`, EXIT.no);
67261
+ return fail(out, "unknown_tool", `No tool named ${name3} in tools/.${hint}`, EXIT.no);
66649
67262
  }
66650
67263
  const tool = toolDetail(row, definition, bundle);
66651
- for (const line of detailLines(tool))
67264
+ for (const line of detailLines(tool, out.tint))
66652
67265
  await out.line(line);
66653
67266
  await out.result({ ok: true, tool });
66654
67267
  return EXIT.ok;
@@ -66656,7 +67269,7 @@ async function show(out, rows, name2, definition, bundle) {
66656
67269
  async function listUnexposed(out, unexposed) {
66657
67270
  const graphql = unexposed.length > 0 && unexposed.every((op) => /^(?:query|mutation) /.test(op.operation));
66658
67271
  if (unexposed.length === 0) {
66659
- await out.line("Every operation in the spec has a tool, or is marked x-mcp: false.");
67272
+ await out.line("Every operation in the spec has a tool, or is marked x-mcp: false.", "ok");
66660
67273
  } else {
66661
67274
  await out.line(`${plural2(unexposed.length, "operation")} in the spec with no tool:`);
66662
67275
  await out.line();
@@ -66665,7 +67278,7 @@ async function listUnexposed(out, unexposed) {
66665
67278
  await out.line(` ${op.operation.padEnd(width)}tools/${op.name}.md`);
66666
67279
  }
66667
67280
  await out.line();
66668
- await out.line(graphql ? "Add the file to expose one. A GraphQL field without a file stays out of the server." : "Add the file to expose one, or mark it x-mcp: false in the spec.");
67281
+ await out.line(graphql ? "Add the file to expose one. A GraphQL field without a file stays out of the server." : "Add the file to expose one, or mark it x-mcp: false in the spec.", "dim");
66669
67282
  }
66670
67283
  await out.result({ ok: true, unexposed });
66671
67284
  return EXIT.ok;
@@ -66686,12 +67299,251 @@ show <name> One tool: its annotations, its inputs from the spec, and each
66686
67299
  run: run11
66687
67300
  };
66688
67301
 
67302
+ // src/commands/update.ts
67303
+ import { spawn as spawn4 } from "node:child_process";
67304
+
67305
+ // src/update/install.ts
67306
+ import { realpathSync } from "node:fs";
67307
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
67308
+
67309
+ // src/update/version.ts
67310
+ function channelFor(version4) {
67311
+ return version4.includes("-staging.") ? "staging" : "latest";
67312
+ }
67313
+ var SEMVER = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
67314
+ function parseVersion(version4) {
67315
+ const match = SEMVER.exec(version4.trim());
67316
+ if (!match)
67317
+ return null;
67318
+ const [, major, minor, patch, pre] = match;
67319
+ return {
67320
+ core: [Number(major), Number(minor), Number(patch)],
67321
+ pre: pre ? pre.split(".").map((part) => /^\d+$/.test(part) ? Number(part) : part) : []
67322
+ };
67323
+ }
67324
+ function compareIdentifiers(a, b) {
67325
+ if (typeof a === "number" && typeof b === "number")
67326
+ return Math.sign(a - b);
67327
+ if (typeof a === "number")
67328
+ return -1;
67329
+ if (typeof b === "number")
67330
+ return 1;
67331
+ return a < b ? -1 : a > b ? 1 : 0;
67332
+ }
67333
+ function compareVersions(a, b) {
67334
+ for (let i2 = 0;i2 < 3; i2++) {
67335
+ const diff2 = Math.sign((a.core[i2] ?? 0) - (b.core[i2] ?? 0));
67336
+ if (diff2 !== 0)
67337
+ return diff2;
67338
+ }
67339
+ if (a.pre.length === 0 || b.pre.length === 0)
67340
+ return Math.sign(b.pre.length - a.pre.length);
67341
+ for (let i2 = 0;i2 < Math.min(a.pre.length, b.pre.length); i2++) {
67342
+ const diff2 = compareIdentifiers(a.pre[i2] ?? 0, b.pre[i2] ?? 0);
67343
+ if (diff2 !== 0)
67344
+ return diff2;
67345
+ }
67346
+ return Math.sign(a.pre.length - b.pre.length);
67347
+ }
67348
+ function isNewer(candidate, current) {
67349
+ const a = parseVersion(candidate);
67350
+ const b = parseVersion(current);
67351
+ return a !== null && b !== null && compareVersions(a, b) > 0;
67352
+ }
67353
+
67354
+ // src/update/install.ts
67355
+ function bundlePath(url2 = import.meta.url) {
67356
+ const path = fileURLToPath2(url2);
67357
+ try {
67358
+ return realpathSync(path);
67359
+ } catch {
67360
+ return path;
67361
+ }
67362
+ }
67363
+ function installerFor(path) {
67364
+ const at2 = path.replaceAll("\\", "/");
67365
+ if (at2.includes("/_npx/"))
67366
+ return "npx";
67367
+ if (at2.includes("/.bun/install/cache/") || /\/bunx-[^/]*\//.test(at2))
67368
+ return "bunx";
67369
+ if (at2.includes("/.bun/"))
67370
+ return "bun";
67371
+ if (/\/\.?pnpm\//.test(at2))
67372
+ return "pnpm";
67373
+ if (/\/yarn\/(data\/)?global\//i.test(at2))
67374
+ return "yarn";
67375
+ return "npm";
67376
+ }
67377
+ function isRunner(installer) {
67378
+ return installer === "npx" || installer === "bunx";
67379
+ }
67380
+ function installCommand(manager, tag) {
67381
+ const spec = tag ? `${name}@${tag}` : name;
67382
+ switch (manager) {
67383
+ case "bun":
67384
+ return ["bun", "add", "--global", spec];
67385
+ case "pnpm":
67386
+ return ["pnpm", "add", "--global", spec];
67387
+ case "yarn":
67388
+ return ["yarn", "global", "add", spec];
67389
+ case "npm":
67390
+ return ["npm", "install", "--global", spec];
67391
+ }
67392
+ }
67393
+ function runnerCommand(runner, tag) {
67394
+ return `${runner} ${name}@${tag}`;
67395
+ }
67396
+ function changelogUrl(site) {
67397
+ return `${site.replace(/\/+$/, "")}/changelog`;
67398
+ }
67399
+ var REGISTRY = "https://registry.npmjs.org";
67400
+ async function fetchLatest(channel, fetchFn, signal) {
67401
+ const url2 = `${REGISTRY}/-/package/${name.replace("/", "%2f")}/dist-tags`;
67402
+ const response = await fetchFn(url2, { signal, headers: { accept: "application/json" } });
67403
+ if (!response.ok)
67404
+ throw new Error(`npm answered ${response.status}.`);
67405
+ const tags = await response.json();
67406
+ const latest = typeof tags === "object" && tags !== null ? tags[channel] : null;
67407
+ if (typeof latest !== "string" || !parseVersion(latest)) {
67408
+ throw new Error(`npm has no ${channel} version of ${name}.`);
67409
+ }
67410
+ return latest;
67411
+ }
67412
+
67413
+ // src/commands/update.ts
67414
+ var FETCH_MS = 5000;
67415
+ function runInstall(command, args, json3) {
67416
+ return new Promise((resolve16, reject) => {
67417
+ const child = spawn4(command, args, {
67418
+ stdio: ["inherit", json3 ? 2 : "inherit", "inherit"],
67419
+ shell: process.platform === "win32"
67420
+ });
67421
+ child.on("error", reject);
67422
+ child.on("close", (code2) => resolve16(code2 ?? 1));
67423
+ });
67424
+ }
67425
+ var TERMINAL5 = {
67426
+ current: version,
67427
+ site: DEFAULT_SITE,
67428
+ bundlePath: () => bundlePath(),
67429
+ fetch,
67430
+ spawn: runInstall
67431
+ };
67432
+ async function failWith(out, facts, code2, message) {
67433
+ await out.problem(`✗ ${message}`, "fail");
67434
+ await out.result({ ok: false, ...facts, updated: false, error: { code: code2, message } });
67435
+ return EXIT.no;
67436
+ }
67437
+ async function fromRunner(out, facts, runner, check3) {
67438
+ const { channel, current } = facts;
67439
+ const manager = runner === "bunx" ? "bun" : "npm";
67440
+ const install = installCommand(manager, channel === "latest" ? undefined : channel).join(" ");
67441
+ const message = `${runner} runs a cached copy of sokie (${current}), so there's nothing to update in place.`;
67442
+ await out.line(`sokie ${facts.latest} is out. ${message}`, "warn");
67443
+ await out.line("To run the newest:");
67444
+ await out.line(` ${runnerCommand(runner, channel)}`, "dim");
67445
+ await out.line("To install it, so sokie is the newest from then on:");
67446
+ await out.line(` ${install}`, "dim");
67447
+ if (check3) {
67448
+ await out.result({ ok: true, ...facts, updated: false });
67449
+ return EXIT.ok;
67450
+ }
67451
+ await out.result({
67452
+ ok: false,
67453
+ ...facts,
67454
+ updated: false,
67455
+ error: { code: "cached_copy", message }
67456
+ });
67457
+ return EXIT.no;
67458
+ }
67459
+ async function install(out, deps, facts, manager) {
67460
+ const [command = manager, ...args] = installCommand(manager, facts.channel);
67461
+ const typed = [command, ...args].join(" ");
67462
+ await out.line(`sokie ${facts.current} → ${facts.latest}. It was installed with ${manager}, so this runs:`);
67463
+ await out.line(` ${typed}`, "dim");
67464
+ let failure;
67465
+ try {
67466
+ const code2 = await deps.spawn(command, args, out.json);
67467
+ if (code2 === 0) {
67468
+ await out.line(`Updated to ${facts.latest}. What's new: ${changelogUrl(deps.site)}`, "ok");
67469
+ await out.result({ ok: true, ...facts, updated: true });
67470
+ return EXIT.ok;
67471
+ }
67472
+ failure = `${manager} didn't finish (exit code ${code2})`;
67473
+ } catch (error62) {
67474
+ failure = `Couldn't run ${manager} (${error62 instanceof Error ? error62.message : String(error62)})`;
67475
+ }
67476
+ const message = `${failure}, so sokie is still ${facts.current}. Run it yourself: ${typed}`;
67477
+ return failWith(out, facts, "install_failed", message);
67478
+ }
67479
+ function registryProblem(error62) {
67480
+ if (!(error62 instanceof Error))
67481
+ return String(error62);
67482
+ if (error62.name === "TimeoutError")
67483
+ return `npm didn't answer within ${FETCH_MS / 1000} seconds.`;
67484
+ const code2 = error62.cause?.code;
67485
+ return code2 ? `${error62.message} (${code2})` : error62.message;
67486
+ }
67487
+ async function runUpdate(argv, out, deps) {
67488
+ const { values, positionals } = parseCommandArgs(argv, {
67489
+ check: { type: "boolean", default: false }
67490
+ });
67491
+ if (positionals.length > 0) {
67492
+ throw new UsageError("sokie update takes no names; --check only says what it would do.");
67493
+ }
67494
+ const { current } = deps;
67495
+ const channel = channelFor(current);
67496
+ const installer = installerFor(deps.bundlePath());
67497
+ let latest;
67498
+ try {
67499
+ latest = await fetchLatest(channel, deps.fetch, AbortSignal.timeout(FETCH_MS));
67500
+ } catch (error62) {
67501
+ const message = `Couldn't ask npm for the newest sokie: ${registryProblem(error62)}`;
67502
+ return failWith(out, { current, latest: null, channel, installer }, "registry_unreachable", message);
67503
+ }
67504
+ const facts = { current, latest, channel, installer };
67505
+ if (!isNewer(latest, current)) {
67506
+ await out.line(`${current} is the newest. Nothing to do.`, "ok");
67507
+ await out.result({ ok: true, ...facts, updated: false });
67508
+ return EXIT.ok;
67509
+ }
67510
+ if (isRunner(installer))
67511
+ return fromRunner(out, facts, installer, values.check);
67512
+ if (values.check) {
67513
+ await out.line(`sokie ${current} → ${latest} is out. It was installed with ${installer}, so sokie update runs:`, "warn");
67514
+ await out.line(` ${installCommand(installer, channel).join(" ")}`, "dim");
67515
+ await out.result({ ok: true, ...facts, updated: false });
67516
+ return EXIT.ok;
67517
+ }
67518
+ return install(out, deps, facts, installer);
67519
+ }
67520
+ var updateCommand = {
67521
+ name: "update",
67522
+ synopsis: "sokie update [--check]",
67523
+ summary: "Install the newest sokie, the way this one was installed.",
67524
+ help: `Asks npm for the newest sokie and installs it with the package manager that
67525
+ installed this one (npm, bun, pnpm or yarn), as the same global install you
67526
+ would type. It never adds sudo: when the install fails, it prints the command
67527
+ to run yourself. A copy npx or bunx ran is a cached one, so there is nothing
67528
+ to update in place; it says how to get the newest instead. A staging build
67529
+ follows npm's staging tag rather than latest.
67530
+
67531
+ After a command at a terminal, sokie says when a newer version is out, at
67532
+ most once per terminal session. It waits on npm for a moment at most, and
67533
+ stays quiet in CI, when stderr isn't a terminal, and under --json, which
67534
+ gets one {"update": {...}} line on stderr instead.
67535
+ SOKIE_NO_UPDATE_NOTIFIER=1 turns it off.
67536
+
67537
+ --check Only say whether there is a newer version; install nothing.`,
67538
+ run: (argv, out) => runUpdate(argv, out, TERMINAL5)
67539
+ };
67540
+
66689
67541
  // src/commands/whoami.ts
66690
67542
  async function run12(argv, out) {
66691
67543
  const { values } = parseCommandArgs(argv, SITE_OPTION);
66692
67544
  return withSignedIn(out, values.site, async (info2, client) => {
66693
67545
  const me = await client.query(fn.me, {});
66694
- await out.line(`${me.email} on ${info2.site}`);
67546
+ await out.line(`${me.email} on ${info2.site}`, "ok");
66695
67547
  await out.result({ ok: true, site: info2.site, email: me.email, userId: me.userId });
66696
67548
  return EXIT.ok;
66697
67549
  });
@@ -66716,6 +67568,7 @@ var COMMANDS = [
66716
67568
  fmtCommand,
66717
67569
  devCommand,
66718
67570
  editCommand,
67571
+ pullCommand,
66719
67572
  loginCommand,
66720
67573
  logoutCommand,
66721
67574
  whoamiCommand,
@@ -66725,15 +67578,16 @@ var COMMANDS = [
66725
67578
  secretsCommand,
66726
67579
  logsCommand,
66727
67580
  auditCommand,
66728
- configCommand
67581
+ configCommand,
67582
+ updateCommand
66729
67583
  ];
66730
67584
 
66731
67585
  // src/output.ts
66732
67586
  function writeAll(stream, text5) {
66733
67587
  if (stream.destroyed || stream.writableEnded)
66734
67588
  return Promise.resolve();
66735
- return new Promise((resolve15) => {
66736
- stream.write(text5, () => resolve15());
67589
+ return new Promise((resolve16) => {
67590
+ stream.write(text5, () => resolve16());
66737
67591
  });
66738
67592
  }
66739
67593
  function ignoreClosedPipe(stream) {
@@ -66747,12 +67601,15 @@ function ignoreClosedPipe(stream) {
66747
67601
  function createOutput(json3, stdout2 = process.stdout, stderr2 = process.stderr) {
66748
67602
  ignoreClosedPipe(stdout2);
66749
67603
  ignoreClosedPipe(stderr2);
67604
+ const outColor = !json3 && colorFor(stdout2);
67605
+ const errColor = !json3 && colorFor(stderr2);
66750
67606
  return {
66751
67607
  json: json3,
66752
- line: (text5 = "") => json3 ? Promise.resolve() : writeAll(stdout2, `${text5}
67608
+ line: (text5 = "", tone) => json3 ? Promise.resolve() : writeAll(stdout2, `${paint(outColor, tone, text5)}
66753
67609
  `),
66754
- problem: (text5) => json3 ? Promise.resolve() : writeAll(stderr2, `${text5}
67610
+ problem: (text5, tone) => json3 ? Promise.resolve() : writeAll(stderr2, `${paint(errColor, tone, text5)}
66755
67611
  `),
67612
+ tint: (tone, text5) => paint(outColor, tone, text5),
66756
67613
  result: (value) => json3 ? writeAll(stdout2, `${JSON.stringify(value, null, 2)}
66757
67614
  `) : Promise.resolve(),
66758
67615
  event: (value) => json3 ? writeAll(stdout2, `${JSON.stringify(value)}
@@ -66762,6 +67619,176 @@ function createOutput(json3, stdout2 = process.stdout, stderr2 = process.stderr)
66762
67619
  };
66763
67620
  }
66764
67621
 
67622
+ // src/update/notice.ts
67623
+ import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "node:fs";
67624
+ import { dirname as dirname8, join as join14 } from "node:path";
67625
+
67626
+ // src/update/session.ts
67627
+ import { execFile } from "node:child_process";
67628
+ import { basename as basename3 } from "node:path";
67629
+ var RUNNER_PROCESSES = new Set(["node", "npm", "npx", "bun", "bunx", "sh"]);
67630
+ var MAX_HOPS = 4;
67631
+ function shellAbove(ppid, table) {
67632
+ const parents = new Map;
67633
+ for (const line of table.split(`
67634
+ `)) {
67635
+ const match = /^\s*(\d+)\s+(\d+)\s+(\S+)/.exec(line);
67636
+ if (match) {
67637
+ parents.set(Number(match[1]), { parent: Number(match[2]), name: basename3(match[3] ?? "") });
67638
+ }
67639
+ }
67640
+ let pid = ppid;
67641
+ for (let hop = 0;hop < MAX_HOPS; hop++) {
67642
+ const row = parents.get(pid);
67643
+ if (!row || !RUNNER_PROCESSES.has(row.name) || row.parent <= 1)
67644
+ return pid;
67645
+ pid = row.parent;
67646
+ }
67647
+ return pid;
67648
+ }
67649
+ function processTable() {
67650
+ return new Promise((resolve16, reject) => {
67651
+ execFile("ps", ["-A", "-o", "pid=,ppid=,comm="], { timeout: 300 }, (error62, stdout2) => error62 ? reject(error62) : resolve16(stdout2));
67652
+ });
67653
+ }
67654
+ async function terminalSession(runner, ppid = process.ppid, table = processTable) {
67655
+ if (runner === null || process.platform === "win32")
67656
+ return ppid;
67657
+ try {
67658
+ return shellAbove(ppid, await table());
67659
+ } catch {
67660
+ return ppid;
67661
+ }
67662
+ }
67663
+
67664
+ // src/update/notice.ts
67665
+ var HOUR_MS = 60 * 60 * 1000;
67666
+ function fileStore2(path = join14(configDir(), "update-check.json")) {
67667
+ return {
67668
+ read: () => {
67669
+ try {
67670
+ if (!existsSync13(path))
67671
+ return null;
67672
+ const raw = JSON.parse(readFileSync11(path, "utf8"));
67673
+ if (typeof raw.latest !== "string" || typeof raw.checkedAt !== "number")
67674
+ return null;
67675
+ return {
67676
+ checkedAt: raw.checkedAt,
67677
+ channel: raw.channel === "staging" ? "staging" : "latest",
67678
+ latest: raw.latest,
67679
+ shownForSession: typeof raw.shownForSession === "number" ? raw.shownForSession : null
67680
+ };
67681
+ } catch {
67682
+ return null;
67683
+ }
67684
+ },
67685
+ write: (cache) => {
67686
+ mkdirSync8(dirname8(path), { recursive: true });
67687
+ writeFileSync10(path, JSON.stringify(cache));
67688
+ }
67689
+ };
67690
+ }
67691
+ function terminalDeps() {
67692
+ const installer = installerFor(bundlePath());
67693
+ const runner = isRunner(installer) ? installer : null;
67694
+ return {
67695
+ current: version,
67696
+ site: DEFAULT_SITE,
67697
+ env: process.env,
67698
+ stderrIsTTY: process.stderr.isTTY === true,
67699
+ runner,
67700
+ session: () => terminalSession(runner),
67701
+ now: Date.now,
67702
+ fetch,
67703
+ store: fileStore2(),
67704
+ graceMs: 400,
67705
+ budgetMs: 1500
67706
+ };
67707
+ }
67708
+ var set2 = (value) => value !== undefined && value !== "";
67709
+ function checkWanted(command, json3, deps) {
67710
+ if (command === "update")
67711
+ return false;
67712
+ const ci = deps.env.CI;
67713
+ if (set2(ci) && ci !== "false" && ci !== "0")
67714
+ return false;
67715
+ if (set2(deps.env.SOKIE_NO_UPDATE_NOTIFIER))
67716
+ return false;
67717
+ return json3 || deps.stderrIsTTY;
67718
+ }
67719
+ function noticeLines2(latest, deps) {
67720
+ const whatsNew = changelogUrl(deps.site);
67721
+ if (deps.runner) {
67722
+ const get = runnerCommand(deps.runner, channelFor(deps.current));
67723
+ return [
67724
+ {
67725
+ text: `sokie ${latest} is out; ${deps.runner} ran a cached ${deps.current}.`,
67726
+ tone: "warn"
67727
+ },
67728
+ { text: `${get} gets it · what's new: ${whatsNew}`, tone: "dim" }
67729
+ ];
67730
+ }
67731
+ return [
67732
+ { text: `sokie ${latest} is out; you have ${deps.current}. Run sokie update.`, tone: "warn" },
67733
+ { text: `What's new: ${whatsNew}`, tone: "dim" }
67734
+ ];
67735
+ }
67736
+ async function look(json3, deps, signal) {
67737
+ const channel = channelFor(deps.current);
67738
+ const cached2 = deps.store.read();
67739
+ const session = await deps.session();
67740
+ if (!json3 && cached2?.shownForSession === session)
67741
+ return null;
67742
+ if (cached2 && cached2.channel === channel && deps.now() - cached2.checkedAt < HOUR_MS) {
67743
+ return { latest: cached2.latest, session, cache: cached2 };
67744
+ }
67745
+ const budget = AbortSignal.any([signal, AbortSignal.timeout(deps.budgetMs)]);
67746
+ const latest = await fetchLatest(channel, deps.fetch, budget);
67747
+ const cache = {
67748
+ checkedAt: deps.now(),
67749
+ channel,
67750
+ latest,
67751
+ shownForSession: cached2?.shownForSession ?? null
67752
+ };
67753
+ deps.store.write(cache);
67754
+ return { latest, session, cache };
67755
+ }
67756
+ function within(answer, ms) {
67757
+ return new Promise((resolve16) => {
67758
+ const timer = setTimeout(() => resolve16(null), ms);
67759
+ answer.then((value) => {
67760
+ clearTimeout(timer);
67761
+ resolve16(value);
67762
+ });
67763
+ });
67764
+ }
67765
+ var IDLE = { finish: async () => {}, cancel: () => {} };
67766
+ function startUpdateCheck(command, json3, deps = terminalDeps()) {
67767
+ if (!checkWanted(command, json3, deps))
67768
+ return IDLE;
67769
+ const controller = new AbortController;
67770
+ const answer = look(json3, deps, controller.signal).catch(() => null);
67771
+ return {
67772
+ cancel: () => controller.abort(),
67773
+ finish: async (out) => {
67774
+ const found = await within(answer, deps.graceMs);
67775
+ controller.abort();
67776
+ if (!found || !isNewer(found.latest, deps.current))
67777
+ return;
67778
+ try {
67779
+ if (out.json) {
67780
+ const update = { current: deps.current, latest: found.latest, command: "sokie update" };
67781
+ await out.aside({ update });
67782
+ return;
67783
+ }
67784
+ for (const line of noticeLines2(found.latest, deps))
67785
+ await out.problem(line.text, line.tone);
67786
+ deps.store.write({ ...found.cache, shownForSession: found.session });
67787
+ } catch {}
67788
+ }
67789
+ };
67790
+ }
67791
+
66765
67792
  // src/main.ts
66766
67793
  var usage = () => [
66767
67794
  "Usage: sokie <command> [--json]",
@@ -66779,25 +67806,26 @@ ${command.help}`;
66779
67806
  async function main(argv) {
66780
67807
  const { json: json3, rest } = splitGlobalFlags(argv);
66781
67808
  const out = createOutput(json3);
66782
- const [name2, ...args] = rest;
66783
- if (name2 === "--version" || name2 === "-v") {
67809
+ const red = (text5) => paint(!json3 && colorFor(process.stderr), "fail", text5);
67810
+ const [name3, ...args] = rest;
67811
+ if (name3 === "--version" || name3 === "-v") {
66784
67812
  await out.line(version);
66785
67813
  await out.result({ ok: true, version });
66786
67814
  return EXIT.ok;
66787
67815
  }
66788
- if (!name2 || name2 === "help" || name2 === "--help" || name2 === "-h") {
67816
+ if (!name3 || name3 === "help" || name3 === "--help" || name3 === "-h") {
66789
67817
  const target = COMMANDS.find((command2) => command2.name === args[0]);
66790
67818
  await writeAll(process.stdout, `${target ? helpFor(target) : usage()}
66791
67819
  `);
66792
- return name2 ? EXIT.ok : EXIT.usage;
67820
+ return name3 ? EXIT.ok : EXIT.usage;
66793
67821
  }
66794
- const command = COMMANDS.find((candidate) => candidate.name === name2);
67822
+ const command = COMMANDS.find((candidate) => candidate.name === name3);
66795
67823
  if (!command) {
66796
- await writeAll(process.stderr, `sokie: no command "${name2}".
67824
+ await writeAll(process.stderr, `${red(`sokie: no command "${name3}".`)}
66797
67825
 
66798
67826
  ${usage()}
66799
67827
  `);
66800
- await out.result({ ok: false, error: { code: "usage", message: `No command "${name2}".` } });
67828
+ await out.result({ ok: false, error: { code: "usage", message: `No command "${name3}".` } });
66801
67829
  return EXIT.usage;
66802
67830
  }
66803
67831
  if (args.includes("--help") || args.includes("-h")) {
@@ -66805,12 +67833,16 @@ ${usage()}
66805
67833
  `);
66806
67834
  return EXIT.ok;
66807
67835
  }
67836
+ const update = startUpdateCheck(command.name, json3);
66808
67837
  try {
66809
- return await command.run(args, out);
67838
+ const code2 = await command.run(args, out);
67839
+ await update.finish(out);
67840
+ return code2;
66810
67841
  } catch (error62) {
67842
+ update.cancel();
66811
67843
  if (!(error62 instanceof UsageError))
66812
67844
  throw error62;
66813
- await writeAll(process.stderr, `sokie ${command.name}: ${error62.message}
67845
+ await writeAll(process.stderr, `${red(`sokie ${command.name}: ${error62.message}`)}
66814
67846
 
66815
67847
  Usage: ${command.synopsis}
66816
67848
  `);