beplus-mcp 0.27.0 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7678,15 +7678,15 @@ var $ZodCheckLessThan = /* @__PURE__ */ $constructor("$ZodCheckLessThan", (inst,
7678
7678
  bag.exclusiveMaximum = def.value;
7679
7679
  }
7680
7680
  });
7681
- inst._zod.check = (payload) => {
7682
- if (def.inclusive ? payload.value <= def.value : payload.value < def.value) {
7681
+ inst._zod.check = (payload2) => {
7682
+ if (def.inclusive ? payload2.value <= def.value : payload2.value < def.value) {
7683
7683
  return;
7684
7684
  }
7685
- payload.issues.push({
7685
+ payload2.issues.push({
7686
7686
  origin,
7687
7687
  code: "too_big",
7688
7688
  maximum: def.value,
7689
- input: payload.value,
7689
+ input: payload2.value,
7690
7690
  inclusive: def.inclusive,
7691
7691
  inst,
7692
7692
  continue: !def.abort
@@ -7706,15 +7706,15 @@ var $ZodCheckGreaterThan = /* @__PURE__ */ $constructor("$ZodCheckGreaterThan",
7706
7706
  bag.exclusiveMinimum = def.value;
7707
7707
  }
7708
7708
  });
7709
- inst._zod.check = (payload) => {
7710
- if (def.inclusive ? payload.value >= def.value : payload.value > def.value) {
7709
+ inst._zod.check = (payload2) => {
7710
+ if (def.inclusive ? payload2.value >= def.value : payload2.value > def.value) {
7711
7711
  return;
7712
7712
  }
7713
- payload.issues.push({
7713
+ payload2.issues.push({
7714
7714
  origin,
7715
7715
  code: "too_small",
7716
7716
  minimum: def.value,
7717
- input: payload.value,
7717
+ input: payload2.value,
7718
7718
  inclusive: def.inclusive,
7719
7719
  inst,
7720
7720
  continue: !def.abort
@@ -7727,17 +7727,17 @@ var $ZodCheckMultipleOf = /* @__PURE__ */ $constructor("$ZodCheckMultipleOf", (i
7727
7727
  var _a;
7728
7728
  (_a = inst2._zod.bag).multipleOf ?? (_a.multipleOf = def.value);
7729
7729
  });
7730
- inst._zod.check = (payload) => {
7731
- if (typeof payload.value !== typeof def.value)
7730
+ inst._zod.check = (payload2) => {
7731
+ if (typeof payload2.value !== typeof def.value)
7732
7732
  throw new Error("Cannot mix number and bigint in multiple_of check.");
7733
- const isMultiple = typeof payload.value === "bigint" ? payload.value % def.value === BigInt(0) : floatSafeRemainder(payload.value, def.value) === 0;
7733
+ const isMultiple = typeof payload2.value === "bigint" ? payload2.value % def.value === BigInt(0) : floatSafeRemainder(payload2.value, def.value) === 0;
7734
7734
  if (isMultiple)
7735
7735
  return;
7736
- payload.issues.push({
7737
- origin: typeof payload.value,
7736
+ payload2.issues.push({
7737
+ origin: typeof payload2.value,
7738
7738
  code: "not_multiple_of",
7739
7739
  divisor: def.value,
7740
- input: payload.value,
7740
+ input: payload2.value,
7741
7741
  inst,
7742
7742
  continue: !def.abort
7743
7743
  });
@@ -7757,11 +7757,11 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
7757
7757
  if (isInt)
7758
7758
  bag.pattern = integer;
7759
7759
  });
7760
- inst._zod.check = (payload) => {
7761
- const input = payload.value;
7760
+ inst._zod.check = (payload2) => {
7761
+ const input = payload2.value;
7762
7762
  if (isInt) {
7763
7763
  if (!Number.isInteger(input)) {
7764
- payload.issues.push({
7764
+ payload2.issues.push({
7765
7765
  expected: origin,
7766
7766
  format: def.format,
7767
7767
  code: "invalid_type",
@@ -7772,7 +7772,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
7772
7772
  }
7773
7773
  if (!Number.isSafeInteger(input)) {
7774
7774
  if (input > 0) {
7775
- payload.issues.push({
7775
+ payload2.issues.push({
7776
7776
  input,
7777
7777
  code: "too_big",
7778
7778
  maximum: Number.MAX_SAFE_INTEGER,
@@ -7782,7 +7782,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
7782
7782
  continue: !def.abort
7783
7783
  });
7784
7784
  } else {
7785
- payload.issues.push({
7785
+ payload2.issues.push({
7786
7786
  input,
7787
7787
  code: "too_small",
7788
7788
  minimum: Number.MIN_SAFE_INTEGER,
@@ -7796,7 +7796,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
7796
7796
  }
7797
7797
  }
7798
7798
  if (input < minimum) {
7799
- payload.issues.push({
7799
+ payload2.issues.push({
7800
7800
  origin: "number",
7801
7801
  input,
7802
7802
  code: "too_small",
@@ -7807,7 +7807,7 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
7807
7807
  });
7808
7808
  }
7809
7809
  if (input > maximum) {
7810
- payload.issues.push({
7810
+ payload2.issues.push({
7811
7811
  origin: "number",
7812
7812
  input,
7813
7813
  code: "too_big",
@@ -7820,8 +7820,8 @@ var $ZodCheckNumberFormat = /* @__PURE__ */ $constructor("$ZodCheckNumberFormat"
7820
7820
  var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (inst, def) => {
7821
7821
  var _a;
7822
7822
  $ZodCheck.init(inst, def);
7823
- (_a = inst._zod.def).when ?? (_a.when = (payload) => {
7824
- const val = payload.value;
7823
+ (_a = inst._zod.def).when ?? (_a.when = (payload2) => {
7824
+ const val = payload2.value;
7825
7825
  return !nullish(val) && val.length !== void 0;
7826
7826
  });
7827
7827
  inst._zod.onattach.push((inst2) => {
@@ -7829,13 +7829,13 @@ var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (ins
7829
7829
  if (def.maximum < curr)
7830
7830
  inst2._zod.bag.maximum = def.maximum;
7831
7831
  });
7832
- inst._zod.check = (payload) => {
7833
- const input = payload.value;
7832
+ inst._zod.check = (payload2) => {
7833
+ const input = payload2.value;
7834
7834
  const length = input.length;
7835
7835
  if (length <= def.maximum)
7836
7836
  return;
7837
7837
  const origin = getLengthableOrigin(input);
7838
- payload.issues.push({
7838
+ payload2.issues.push({
7839
7839
  origin,
7840
7840
  code: "too_big",
7841
7841
  maximum: def.maximum,
@@ -7849,8 +7849,8 @@ var $ZodCheckMaxLength = /* @__PURE__ */ $constructor("$ZodCheckMaxLength", (ins
7849
7849
  var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (inst, def) => {
7850
7850
  var _a;
7851
7851
  $ZodCheck.init(inst, def);
7852
- (_a = inst._zod.def).when ?? (_a.when = (payload) => {
7853
- const val = payload.value;
7852
+ (_a = inst._zod.def).when ?? (_a.when = (payload2) => {
7853
+ const val = payload2.value;
7854
7854
  return !nullish(val) && val.length !== void 0;
7855
7855
  });
7856
7856
  inst._zod.onattach.push((inst2) => {
@@ -7858,13 +7858,13 @@ var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (ins
7858
7858
  if (def.minimum > curr)
7859
7859
  inst2._zod.bag.minimum = def.minimum;
7860
7860
  });
7861
- inst._zod.check = (payload) => {
7862
- const input = payload.value;
7861
+ inst._zod.check = (payload2) => {
7862
+ const input = payload2.value;
7863
7863
  const length = input.length;
7864
7864
  if (length >= def.minimum)
7865
7865
  return;
7866
7866
  const origin = getLengthableOrigin(input);
7867
- payload.issues.push({
7867
+ payload2.issues.push({
7868
7868
  origin,
7869
7869
  code: "too_small",
7870
7870
  minimum: def.minimum,
@@ -7878,8 +7878,8 @@ var $ZodCheckMinLength = /* @__PURE__ */ $constructor("$ZodCheckMinLength", (ins
7878
7878
  var $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEquals", (inst, def) => {
7879
7879
  var _a;
7880
7880
  $ZodCheck.init(inst, def);
7881
- (_a = inst._zod.def).when ?? (_a.when = (payload) => {
7882
- const val = payload.value;
7881
+ (_a = inst._zod.def).when ?? (_a.when = (payload2) => {
7882
+ const val = payload2.value;
7883
7883
  return !nullish(val) && val.length !== void 0;
7884
7884
  });
7885
7885
  inst._zod.onattach.push((inst2) => {
@@ -7888,19 +7888,19 @@ var $ZodCheckLengthEquals = /* @__PURE__ */ $constructor("$ZodCheckLengthEquals"
7888
7888
  bag.maximum = def.length;
7889
7889
  bag.length = def.length;
7890
7890
  });
7891
- inst._zod.check = (payload) => {
7892
- const input = payload.value;
7891
+ inst._zod.check = (payload2) => {
7892
+ const input = payload2.value;
7893
7893
  const length = input.length;
7894
7894
  if (length === def.length)
7895
7895
  return;
7896
7896
  const origin = getLengthableOrigin(input);
7897
7897
  const tooBig = length > def.length;
7898
- payload.issues.push({
7898
+ payload2.issues.push({
7899
7899
  origin,
7900
7900
  ...tooBig ? { code: "too_big", maximum: def.length } : { code: "too_small", minimum: def.length },
7901
7901
  inclusive: true,
7902
7902
  exact: true,
7903
- input: payload.value,
7903
+ input: payload2.value,
7904
7904
  inst,
7905
7905
  continue: !def.abort
7906
7906
  });
@@ -7918,15 +7918,15 @@ var $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringFormat"
7918
7918
  }
7919
7919
  });
7920
7920
  if (def.pattern)
7921
- (_a = inst._zod).check ?? (_a.check = (payload) => {
7921
+ (_a = inst._zod).check ?? (_a.check = (payload2) => {
7922
7922
  def.pattern.lastIndex = 0;
7923
- if (def.pattern.test(payload.value))
7923
+ if (def.pattern.test(payload2.value))
7924
7924
  return;
7925
- payload.issues.push({
7925
+ payload2.issues.push({
7926
7926
  origin: "string",
7927
7927
  code: "invalid_format",
7928
7928
  format: def.format,
7929
- input: payload.value,
7929
+ input: payload2.value,
7930
7930
  ...def.pattern ? { pattern: def.pattern.toString() } : {},
7931
7931
  inst,
7932
7932
  continue: !def.abort
@@ -7938,15 +7938,15 @@ var $ZodCheckStringFormat = /* @__PURE__ */ $constructor("$ZodCheckStringFormat"
7938
7938
  });
7939
7939
  var $ZodCheckRegex = /* @__PURE__ */ $constructor("$ZodCheckRegex", (inst, def) => {
7940
7940
  $ZodCheckStringFormat.init(inst, def);
7941
- inst._zod.check = (payload) => {
7941
+ inst._zod.check = (payload2) => {
7942
7942
  def.pattern.lastIndex = 0;
7943
- if (def.pattern.test(payload.value))
7943
+ if (def.pattern.test(payload2.value))
7944
7944
  return;
7945
- payload.issues.push({
7945
+ payload2.issues.push({
7946
7946
  origin: "string",
7947
7947
  code: "invalid_format",
7948
7948
  format: "regex",
7949
- input: payload.value,
7949
+ input: payload2.value,
7950
7950
  pattern: def.pattern.toString(),
7951
7951
  inst,
7952
7952
  continue: !def.abort
@@ -7971,15 +7971,15 @@ var $ZodCheckIncludes = /* @__PURE__ */ $constructor("$ZodCheckIncludes", (inst,
7971
7971
  bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
7972
7972
  bag.patterns.add(pattern);
7973
7973
  });
7974
- inst._zod.check = (payload) => {
7975
- if (payload.value.includes(def.includes, def.position))
7974
+ inst._zod.check = (payload2) => {
7975
+ if (payload2.value.includes(def.includes, def.position))
7976
7976
  return;
7977
- payload.issues.push({
7977
+ payload2.issues.push({
7978
7978
  origin: "string",
7979
7979
  code: "invalid_format",
7980
7980
  format: "includes",
7981
7981
  includes: def.includes,
7982
- input: payload.value,
7982
+ input: payload2.value,
7983
7983
  inst,
7984
7984
  continue: !def.abort
7985
7985
  });
@@ -7994,15 +7994,15 @@ var $ZodCheckStartsWith = /* @__PURE__ */ $constructor("$ZodCheckStartsWith", (i
7994
7994
  bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
7995
7995
  bag.patterns.add(pattern);
7996
7996
  });
7997
- inst._zod.check = (payload) => {
7998
- if (payload.value.startsWith(def.prefix))
7997
+ inst._zod.check = (payload2) => {
7998
+ if (payload2.value.startsWith(def.prefix))
7999
7999
  return;
8000
- payload.issues.push({
8000
+ payload2.issues.push({
8001
8001
  origin: "string",
8002
8002
  code: "invalid_format",
8003
8003
  format: "starts_with",
8004
8004
  prefix: def.prefix,
8005
- input: payload.value,
8005
+ input: payload2.value,
8006
8006
  inst,
8007
8007
  continue: !def.abort
8008
8008
  });
@@ -8017,15 +8017,15 @@ var $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst,
8017
8017
  bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
8018
8018
  bag.patterns.add(pattern);
8019
8019
  });
8020
- inst._zod.check = (payload) => {
8021
- if (payload.value.endsWith(def.suffix))
8020
+ inst._zod.check = (payload2) => {
8021
+ if (payload2.value.endsWith(def.suffix))
8022
8022
  return;
8023
- payload.issues.push({
8023
+ payload2.issues.push({
8024
8024
  origin: "string",
8025
8025
  code: "invalid_format",
8026
8026
  format: "ends_with",
8027
8027
  suffix: def.suffix,
8028
- input: payload.value,
8028
+ input: payload2.value,
8029
8029
  inst,
8030
8030
  continue: !def.abort
8031
8031
  });
@@ -8033,8 +8033,8 @@ var $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst,
8033
8033
  });
8034
8034
  var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (inst, def) => {
8035
8035
  $ZodCheck.init(inst, def);
8036
- inst._zod.check = (payload) => {
8037
- payload.value = def.tx(payload.value);
8036
+ inst._zod.check = (payload2) => {
8037
+ payload2.value = def.tx(payload2.value);
8038
8038
  };
8039
8039
  });
8040
8040
 
@@ -8103,48 +8103,48 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
8103
8103
  inst._zod.run = inst._zod.parse;
8104
8104
  });
8105
8105
  } else {
8106
- const runChecks = (payload, checks2, ctx) => {
8107
- let isAborted2 = aborted(payload);
8106
+ const runChecks = (payload2, checks2, ctx) => {
8107
+ let isAborted2 = aborted(payload2);
8108
8108
  let asyncResult;
8109
8109
  for (const ch of checks2) {
8110
8110
  if (ch._zod.def.when) {
8111
- const shouldRun = ch._zod.def.when(payload);
8111
+ const shouldRun = ch._zod.def.when(payload2);
8112
8112
  if (!shouldRun)
8113
8113
  continue;
8114
8114
  } else if (isAborted2) {
8115
8115
  continue;
8116
8116
  }
8117
- const currLen = payload.issues.length;
8118
- const _ = ch._zod.check(payload);
8117
+ const currLen = payload2.issues.length;
8118
+ const _ = ch._zod.check(payload2);
8119
8119
  if (_ instanceof Promise && ctx?.async === false) {
8120
8120
  throw new $ZodAsyncError();
8121
8121
  }
8122
8122
  if (asyncResult || _ instanceof Promise) {
8123
8123
  asyncResult = (asyncResult ?? Promise.resolve()).then(async () => {
8124
8124
  await _;
8125
- const nextLen = payload.issues.length;
8125
+ const nextLen = payload2.issues.length;
8126
8126
  if (nextLen === currLen)
8127
8127
  return;
8128
8128
  if (!isAborted2)
8129
- isAborted2 = aborted(payload, currLen);
8129
+ isAborted2 = aborted(payload2, currLen);
8130
8130
  });
8131
8131
  } else {
8132
- const nextLen = payload.issues.length;
8132
+ const nextLen = payload2.issues.length;
8133
8133
  if (nextLen === currLen)
8134
8134
  continue;
8135
8135
  if (!isAborted2)
8136
- isAborted2 = aborted(payload, currLen);
8136
+ isAborted2 = aborted(payload2, currLen);
8137
8137
  }
8138
8138
  }
8139
8139
  if (asyncResult) {
8140
8140
  return asyncResult.then(() => {
8141
- return payload;
8141
+ return payload2;
8142
8142
  });
8143
8143
  }
8144
- return payload;
8144
+ return payload2;
8145
8145
  };
8146
- inst._zod.run = (payload, ctx) => {
8147
- const result = inst._zod.parse(payload, ctx);
8146
+ inst._zod.run = (payload2, ctx) => {
8147
+ const result = inst._zod.parse(payload2, ctx);
8148
8148
  if (result instanceof Promise) {
8149
8149
  if (ctx.async === false)
8150
8150
  throw new $ZodAsyncError();
@@ -8169,21 +8169,21 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
8169
8169
  var $ZodString = /* @__PURE__ */ $constructor("$ZodString", (inst, def) => {
8170
8170
  $ZodType.init(inst, def);
8171
8171
  inst._zod.pattern = [...inst?._zod.bag?.patterns ?? []].pop() ?? string(inst._zod.bag);
8172
- inst._zod.parse = (payload, _) => {
8172
+ inst._zod.parse = (payload2, _) => {
8173
8173
  if (def.coerce)
8174
8174
  try {
8175
- payload.value = String(payload.value);
8175
+ payload2.value = String(payload2.value);
8176
8176
  } catch (_2) {
8177
8177
  }
8178
- if (typeof payload.value === "string")
8179
- return payload;
8180
- payload.issues.push({
8178
+ if (typeof payload2.value === "string")
8179
+ return payload2;
8180
+ payload2.issues.push({
8181
8181
  expected: "string",
8182
8182
  code: "invalid_type",
8183
- input: payload.value,
8183
+ input: payload2.value,
8184
8184
  inst
8185
8185
  });
8186
- return payload;
8186
+ return payload2;
8187
8187
  };
8188
8188
  });
8189
8189
  var $ZodStringFormat = /* @__PURE__ */ $constructor("$ZodStringFormat", (inst, def) => {
@@ -8220,20 +8220,20 @@ var $ZodEmail = /* @__PURE__ */ $constructor("$ZodEmail", (inst, def) => {
8220
8220
  });
8221
8221
  var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
8222
8222
  $ZodStringFormat.init(inst, def);
8223
- inst._zod.check = (payload) => {
8223
+ inst._zod.check = (payload2) => {
8224
8224
  try {
8225
- const orig = payload.value;
8225
+ const orig = payload2.value;
8226
8226
  const url = new URL(orig);
8227
8227
  const href = url.href;
8228
8228
  if (def.hostname) {
8229
8229
  def.hostname.lastIndex = 0;
8230
8230
  if (!def.hostname.test(url.hostname)) {
8231
- payload.issues.push({
8231
+ payload2.issues.push({
8232
8232
  code: "invalid_format",
8233
8233
  format: "url",
8234
8234
  note: "Invalid hostname",
8235
8235
  pattern: hostname.source,
8236
- input: payload.value,
8236
+ input: payload2.value,
8237
8237
  inst,
8238
8238
  continue: !def.abort
8239
8239
  });
@@ -8242,28 +8242,28 @@ var $ZodURL = /* @__PURE__ */ $constructor("$ZodURL", (inst, def) => {
8242
8242
  if (def.protocol) {
8243
8243
  def.protocol.lastIndex = 0;
8244
8244
  if (!def.protocol.test(url.protocol.endsWith(":") ? url.protocol.slice(0, -1) : url.protocol)) {
8245
- payload.issues.push({
8245
+ payload2.issues.push({
8246
8246
  code: "invalid_format",
8247
8247
  format: "url",
8248
8248
  note: "Invalid protocol",
8249
8249
  pattern: def.protocol.source,
8250
- input: payload.value,
8250
+ input: payload2.value,
8251
8251
  inst,
8252
8252
  continue: !def.abort
8253
8253
  });
8254
8254
  }
8255
8255
  }
8256
8256
  if (!orig.endsWith("/") && href.endsWith("/")) {
8257
- payload.value = href.slice(0, -1);
8257
+ payload2.value = href.slice(0, -1);
8258
8258
  } else {
8259
- payload.value = href;
8259
+ payload2.value = href;
8260
8260
  }
8261
8261
  return;
8262
8262
  } catch (_) {
8263
- payload.issues.push({
8263
+ payload2.issues.push({
8264
8264
  code: "invalid_format",
8265
8265
  format: "url",
8266
- input: payload.value,
8266
+ input: payload2.value,
8267
8267
  inst,
8268
8268
  continue: !def.abort
8269
8269
  });
@@ -8329,14 +8329,14 @@ var $ZodIPv6 = /* @__PURE__ */ $constructor("$ZodIPv6", (inst, def) => {
8329
8329
  const bag = inst2._zod.bag;
8330
8330
  bag.format = `ipv6`;
8331
8331
  });
8332
- inst._zod.check = (payload) => {
8332
+ inst._zod.check = (payload2) => {
8333
8333
  try {
8334
- new URL(`http://[${payload.value}]`);
8334
+ new URL(`http://[${payload2.value}]`);
8335
8335
  } catch {
8336
- payload.issues.push({
8336
+ payload2.issues.push({
8337
8337
  code: "invalid_format",
8338
8338
  format: "ipv6",
8339
- input: payload.value,
8339
+ input: payload2.value,
8340
8340
  inst,
8341
8341
  continue: !def.abort
8342
8342
  });
@@ -8350,8 +8350,8 @@ var $ZodCIDRv4 = /* @__PURE__ */ $constructor("$ZodCIDRv4", (inst, def) => {
8350
8350
  var $ZodCIDRv6 = /* @__PURE__ */ $constructor("$ZodCIDRv6", (inst, def) => {
8351
8351
  def.pattern ?? (def.pattern = cidrv6);
8352
8352
  $ZodStringFormat.init(inst, def);
8353
- inst._zod.check = (payload) => {
8354
- const [address, prefix] = payload.value.split("/");
8353
+ inst._zod.check = (payload2) => {
8354
+ const [address, prefix] = payload2.value.split("/");
8355
8355
  try {
8356
8356
  if (!prefix)
8357
8357
  throw new Error();
@@ -8362,10 +8362,10 @@ var $ZodCIDRv6 = /* @__PURE__ */ $constructor("$ZodCIDRv6", (inst, def) => {
8362
8362
  throw new Error();
8363
8363
  new URL(`http://[${address}]`);
8364
8364
  } catch {
8365
- payload.issues.push({
8365
+ payload2.issues.push({
8366
8366
  code: "invalid_format",
8367
8367
  format: "cidrv6",
8368
- input: payload.value,
8368
+ input: payload2.value,
8369
8369
  inst,
8370
8370
  continue: !def.abort
8371
8371
  });
@@ -8390,13 +8390,13 @@ var $ZodBase64 = /* @__PURE__ */ $constructor("$ZodBase64", (inst, def) => {
8390
8390
  inst._zod.onattach.push((inst2) => {
8391
8391
  inst2._zod.bag.contentEncoding = "base64";
8392
8392
  });
8393
- inst._zod.check = (payload) => {
8394
- if (isValidBase64(payload.value))
8393
+ inst._zod.check = (payload2) => {
8394
+ if (isValidBase64(payload2.value))
8395
8395
  return;
8396
- payload.issues.push({
8396
+ payload2.issues.push({
8397
8397
  code: "invalid_format",
8398
8398
  format: "base64",
8399
- input: payload.value,
8399
+ input: payload2.value,
8400
8400
  inst,
8401
8401
  continue: !def.abort
8402
8402
  });
@@ -8415,13 +8415,13 @@ var $ZodBase64URL = /* @__PURE__ */ $constructor("$ZodBase64URL", (inst, def) =>
8415
8415
  inst._zod.onattach.push((inst2) => {
8416
8416
  inst2._zod.bag.contentEncoding = "base64url";
8417
8417
  });
8418
- inst._zod.check = (payload) => {
8419
- if (isValidBase64URL(payload.value))
8418
+ inst._zod.check = (payload2) => {
8419
+ if (isValidBase64URL(payload2.value))
8420
8420
  return;
8421
- payload.issues.push({
8421
+ payload2.issues.push({
8422
8422
  code: "invalid_format",
8423
8423
  format: "base64url",
8424
- input: payload.value,
8424
+ input: payload2.value,
8425
8425
  inst,
8426
8426
  continue: !def.abort
8427
8427
  });
@@ -8453,13 +8453,13 @@ function isValidJWT(token, algorithm = null) {
8453
8453
  }
8454
8454
  var $ZodJWT = /* @__PURE__ */ $constructor("$ZodJWT", (inst, def) => {
8455
8455
  $ZodStringFormat.init(inst, def);
8456
- inst._zod.check = (payload) => {
8457
- if (isValidJWT(payload.value, def.alg))
8456
+ inst._zod.check = (payload2) => {
8457
+ if (isValidJWT(payload2.value, def.alg))
8458
8458
  return;
8459
- payload.issues.push({
8459
+ payload2.issues.push({
8460
8460
  code: "invalid_format",
8461
8461
  format: "jwt",
8462
- input: payload.value,
8462
+ input: payload2.value,
8463
8463
  inst,
8464
8464
  continue: !def.abort
8465
8465
  });
@@ -8468,25 +8468,25 @@ var $ZodJWT = /* @__PURE__ */ $constructor("$ZodJWT", (inst, def) => {
8468
8468
  var $ZodNumber = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
8469
8469
  $ZodType.init(inst, def);
8470
8470
  inst._zod.pattern = inst._zod.bag.pattern ?? number;
8471
- inst._zod.parse = (payload, _ctx) => {
8471
+ inst._zod.parse = (payload2, _ctx) => {
8472
8472
  if (def.coerce)
8473
8473
  try {
8474
- payload.value = Number(payload.value);
8474
+ payload2.value = Number(payload2.value);
8475
8475
  } catch (_) {
8476
8476
  }
8477
- const input = payload.value;
8477
+ const input = payload2.value;
8478
8478
  if (typeof input === "number" && !Number.isNaN(input) && Number.isFinite(input)) {
8479
- return payload;
8479
+ return payload2;
8480
8480
  }
8481
8481
  const received = typeof input === "number" ? Number.isNaN(input) ? "NaN" : !Number.isFinite(input) ? "Infinity" : void 0 : void 0;
8482
- payload.issues.push({
8482
+ payload2.issues.push({
8483
8483
  expected: "number",
8484
8484
  code: "invalid_type",
8485
8485
  input,
8486
8486
  inst,
8487
8487
  ...received ? { received } : {}
8488
8488
  });
8489
- return payload;
8489
+ return payload2;
8490
8490
  };
8491
8491
  });
8492
8492
  var $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) => {
@@ -8496,55 +8496,55 @@ var $ZodNumberFormat = /* @__PURE__ */ $constructor("$ZodNumber", (inst, def) =>
8496
8496
  var $ZodBoolean = /* @__PURE__ */ $constructor("$ZodBoolean", (inst, def) => {
8497
8497
  $ZodType.init(inst, def);
8498
8498
  inst._zod.pattern = boolean;
8499
- inst._zod.parse = (payload, _ctx) => {
8499
+ inst._zod.parse = (payload2, _ctx) => {
8500
8500
  if (def.coerce)
8501
8501
  try {
8502
- payload.value = Boolean(payload.value);
8502
+ payload2.value = Boolean(payload2.value);
8503
8503
  } catch (_) {
8504
8504
  }
8505
- const input = payload.value;
8505
+ const input = payload2.value;
8506
8506
  if (typeof input === "boolean")
8507
- return payload;
8508
- payload.issues.push({
8507
+ return payload2;
8508
+ payload2.issues.push({
8509
8509
  expected: "boolean",
8510
8510
  code: "invalid_type",
8511
8511
  input,
8512
8512
  inst
8513
8513
  });
8514
- return payload;
8514
+ return payload2;
8515
8515
  };
8516
8516
  });
8517
8517
  var $ZodNull = /* @__PURE__ */ $constructor("$ZodNull", (inst, def) => {
8518
8518
  $ZodType.init(inst, def);
8519
8519
  inst._zod.pattern = _null;
8520
8520
  inst._zod.values = /* @__PURE__ */ new Set([null]);
8521
- inst._zod.parse = (payload, _ctx) => {
8522
- const input = payload.value;
8521
+ inst._zod.parse = (payload2, _ctx) => {
8522
+ const input = payload2.value;
8523
8523
  if (input === null)
8524
- return payload;
8525
- payload.issues.push({
8524
+ return payload2;
8525
+ payload2.issues.push({
8526
8526
  expected: "null",
8527
8527
  code: "invalid_type",
8528
8528
  input,
8529
8529
  inst
8530
8530
  });
8531
- return payload;
8531
+ return payload2;
8532
8532
  };
8533
8533
  });
8534
8534
  var $ZodUnknown = /* @__PURE__ */ $constructor("$ZodUnknown", (inst, def) => {
8535
8535
  $ZodType.init(inst, def);
8536
- inst._zod.parse = (payload) => payload;
8536
+ inst._zod.parse = (payload2) => payload2;
8537
8537
  });
8538
8538
  var $ZodNever = /* @__PURE__ */ $constructor("$ZodNever", (inst, def) => {
8539
8539
  $ZodType.init(inst, def);
8540
- inst._zod.parse = (payload, _ctx) => {
8541
- payload.issues.push({
8540
+ inst._zod.parse = (payload2, _ctx) => {
8541
+ payload2.issues.push({
8542
8542
  expected: "never",
8543
8543
  code: "invalid_type",
8544
- input: payload.value,
8544
+ input: payload2.value,
8545
8545
  inst
8546
8546
  });
8547
- return payload;
8547
+ return payload2;
8548
8548
  };
8549
8549
  });
8550
8550
  function handleArrayResult(result, final, index) {
@@ -8555,18 +8555,18 @@ function handleArrayResult(result, final, index) {
8555
8555
  }
8556
8556
  var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
8557
8557
  $ZodType.init(inst, def);
8558
- inst._zod.parse = (payload, ctx) => {
8559
- const input = payload.value;
8558
+ inst._zod.parse = (payload2, ctx) => {
8559
+ const input = payload2.value;
8560
8560
  if (!Array.isArray(input)) {
8561
- payload.issues.push({
8561
+ payload2.issues.push({
8562
8562
  expected: "array",
8563
8563
  code: "invalid_type",
8564
8564
  input,
8565
8565
  inst
8566
8566
  });
8567
- return payload;
8567
+ return payload2;
8568
8568
  }
8569
- payload.value = Array(input.length);
8569
+ payload2.value = Array(input.length);
8570
8570
  const proms = [];
8571
8571
  for (let i = 0; i < input.length; i++) {
8572
8572
  const item = input[i];
@@ -8575,15 +8575,15 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
8575
8575
  issues: []
8576
8576
  }, ctx);
8577
8577
  if (result instanceof Promise) {
8578
- proms.push(result.then((result2) => handleArrayResult(result2, payload, i)));
8578
+ proms.push(result.then((result2) => handleArrayResult(result2, payload2, i)));
8579
8579
  } else {
8580
- handleArrayResult(result, payload, i);
8580
+ handleArrayResult(result, payload2, i);
8581
8581
  }
8582
8582
  }
8583
8583
  if (proms.length) {
8584
- return Promise.all(proms).then(() => payload);
8584
+ return Promise.all(proms).then(() => payload2);
8585
8585
  }
8586
- return payload;
8586
+ return payload2;
8587
8587
  };
8588
8588
  });
8589
8589
  function handleObjectResult(result, final, key) {
@@ -8694,7 +8694,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
8694
8694
  doc.write(`payload.value = newResult;`);
8695
8695
  doc.write(`return payload;`);
8696
8696
  const fn = doc.compile();
8697
- return (payload, ctx) => fn(shape, payload, ctx);
8697
+ return (payload2, ctx) => fn(shape, payload2, ctx);
8698
8698
  };
8699
8699
  let fastpass;
8700
8700
  const isObject2 = isObject;
@@ -8703,41 +8703,41 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
8703
8703
  const fastEnabled = jit && allowsEval2.value;
8704
8704
  const catchall = def.catchall;
8705
8705
  let value;
8706
- inst._zod.parse = (payload, ctx) => {
8706
+ inst._zod.parse = (payload2, ctx) => {
8707
8707
  value ?? (value = _normalized.value);
8708
- const input = payload.value;
8708
+ const input = payload2.value;
8709
8709
  if (!isObject2(input)) {
8710
- payload.issues.push({
8710
+ payload2.issues.push({
8711
8711
  expected: "object",
8712
8712
  code: "invalid_type",
8713
8713
  input,
8714
8714
  inst
8715
8715
  });
8716
- return payload;
8716
+ return payload2;
8717
8717
  }
8718
8718
  const proms = [];
8719
8719
  if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {
8720
8720
  if (!fastpass)
8721
8721
  fastpass = generateFastpass(def.shape);
8722
- payload = fastpass(payload, ctx);
8722
+ payload2 = fastpass(payload2, ctx);
8723
8723
  } else {
8724
- payload.value = {};
8724
+ payload2.value = {};
8725
8725
  const shape = value.shape;
8726
8726
  for (const key of value.keys) {
8727
8727
  const el = shape[key];
8728
8728
  const r = el._zod.run({ value: input[key], issues: [] }, ctx);
8729
8729
  const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
8730
8730
  if (r instanceof Promise) {
8731
- proms.push(r.then((r2) => isOptional ? handleOptionalObjectResult(r2, payload, key, input) : handleObjectResult(r2, payload, key)));
8731
+ proms.push(r.then((r2) => isOptional ? handleOptionalObjectResult(r2, payload2, key, input) : handleObjectResult(r2, payload2, key)));
8732
8732
  } else if (isOptional) {
8733
- handleOptionalObjectResult(r, payload, key, input);
8733
+ handleOptionalObjectResult(r, payload2, key, input);
8734
8734
  } else {
8735
- handleObjectResult(r, payload, key);
8735
+ handleObjectResult(r, payload2, key);
8736
8736
  }
8737
8737
  }
8738
8738
  }
8739
8739
  if (!catchall) {
8740
- return proms.length ? Promise.all(proms).then(() => payload) : payload;
8740
+ return proms.length ? Promise.all(proms).then(() => payload2) : payload2;
8741
8741
  }
8742
8742
  const unrecognized = [];
8743
8743
  const keySet = value.keySet;
@@ -8752,13 +8752,13 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
8752
8752
  }
8753
8753
  const r = _catchall.run({ value: input[key], issues: [] }, ctx);
8754
8754
  if (r instanceof Promise) {
8755
- proms.push(r.then((r2) => handleObjectResult(r2, payload, key)));
8755
+ proms.push(r.then((r2) => handleObjectResult(r2, payload2, key)));
8756
8756
  } else {
8757
- handleObjectResult(r, payload, key);
8757
+ handleObjectResult(r, payload2, key);
8758
8758
  }
8759
8759
  }
8760
8760
  if (unrecognized.length) {
8761
- payload.issues.push({
8761
+ payload2.issues.push({
8762
8762
  code: "unrecognized_keys",
8763
8763
  keys: unrecognized,
8764
8764
  input,
@@ -8766,9 +8766,9 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
8766
8766
  });
8767
8767
  }
8768
8768
  if (!proms.length)
8769
- return payload;
8769
+ return payload2;
8770
8770
  return Promise.all(proms).then(() => {
8771
- return payload;
8771
+ return payload2;
8772
8772
  });
8773
8773
  };
8774
8774
  });
@@ -8804,12 +8804,12 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
8804
8804
  }
8805
8805
  return void 0;
8806
8806
  });
8807
- inst._zod.parse = (payload, ctx) => {
8807
+ inst._zod.parse = (payload2, ctx) => {
8808
8808
  let async = false;
8809
8809
  const results = [];
8810
8810
  for (const option of def.options) {
8811
8811
  const result = option._zod.run({
8812
- value: payload.value,
8812
+ value: payload2.value,
8813
8813
  issues: []
8814
8814
  }, ctx);
8815
8815
  if (result instanceof Promise) {
@@ -8822,9 +8822,9 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
8822
8822
  }
8823
8823
  }
8824
8824
  if (!async)
8825
- return handleUnionResults(results, payload, inst, ctx);
8825
+ return handleUnionResults(results, payload2, inst, ctx);
8826
8826
  return Promise.all(results).then((results2) => {
8827
- return handleUnionResults(results2, payload, inst, ctx);
8827
+ return handleUnionResults(results2, payload2, inst, ctx);
8828
8828
  });
8829
8829
  };
8830
8830
  });
@@ -8863,25 +8863,25 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
8863
8863
  }
8864
8864
  return map;
8865
8865
  });
8866
- inst._zod.parse = (payload, ctx) => {
8867
- const input = payload.value;
8866
+ inst._zod.parse = (payload2, ctx) => {
8867
+ const input = payload2.value;
8868
8868
  if (!isObject(input)) {
8869
- payload.issues.push({
8869
+ payload2.issues.push({
8870
8870
  code: "invalid_type",
8871
8871
  expected: "object",
8872
8872
  input,
8873
8873
  inst
8874
8874
  });
8875
- return payload;
8875
+ return payload2;
8876
8876
  }
8877
8877
  const opt = disc.value.get(input?.[def.discriminator]);
8878
8878
  if (opt) {
8879
- return opt._zod.run(payload, ctx);
8879
+ return opt._zod.run(payload2, ctx);
8880
8880
  }
8881
8881
  if (def.unionFallback) {
8882
- return _super(payload, ctx);
8882
+ return _super(payload2, ctx);
8883
8883
  }
8884
- payload.issues.push({
8884
+ payload2.issues.push({
8885
8885
  code: "invalid_union",
8886
8886
  errors: [],
8887
8887
  note: "No matching discriminator",
@@ -8889,22 +8889,22 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
8889
8889
  path: [def.discriminator],
8890
8890
  inst
8891
8891
  });
8892
- return payload;
8892
+ return payload2;
8893
8893
  };
8894
8894
  });
8895
8895
  var $ZodIntersection = /* @__PURE__ */ $constructor("$ZodIntersection", (inst, def) => {
8896
8896
  $ZodType.init(inst, def);
8897
- inst._zod.parse = (payload, ctx) => {
8898
- const input = payload.value;
8897
+ inst._zod.parse = (payload2, ctx) => {
8898
+ const input = payload2.value;
8899
8899
  const left = def.left._zod.run({ value: input, issues: [] }, ctx);
8900
8900
  const right = def.right._zod.run({ value: input, issues: [] }, ctx);
8901
8901
  const async = left instanceof Promise || right instanceof Promise;
8902
8902
  if (async) {
8903
8903
  return Promise.all([left, right]).then(([left2, right2]) => {
8904
- return handleIntersectionResults(payload, left2, right2);
8904
+ return handleIntersectionResults(payload2, left2, right2);
8905
8905
  });
8906
8906
  }
8907
- return handleIntersectionResults(payload, left, right);
8907
+ return handleIntersectionResults(payload2, left, right);
8908
8908
  };
8909
8909
  });
8910
8910
  function mergeValues(a, b) {
@@ -8969,36 +8969,36 @@ function handleIntersectionResults(result, left, right) {
8969
8969
  }
8970
8970
  var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
8971
8971
  $ZodType.init(inst, def);
8972
- inst._zod.parse = (payload, ctx) => {
8973
- const input = payload.value;
8972
+ inst._zod.parse = (payload2, ctx) => {
8973
+ const input = payload2.value;
8974
8974
  if (!isPlainObject(input)) {
8975
- payload.issues.push({
8975
+ payload2.issues.push({
8976
8976
  expected: "record",
8977
8977
  code: "invalid_type",
8978
8978
  input,
8979
8979
  inst
8980
8980
  });
8981
- return payload;
8981
+ return payload2;
8982
8982
  }
8983
8983
  const proms = [];
8984
8984
  if (def.keyType._zod.values) {
8985
8985
  const values = def.keyType._zod.values;
8986
- payload.value = {};
8986
+ payload2.value = {};
8987
8987
  for (const key of values) {
8988
8988
  if (typeof key === "string" || typeof key === "number" || typeof key === "symbol") {
8989
8989
  const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
8990
8990
  if (result instanceof Promise) {
8991
8991
  proms.push(result.then((result2) => {
8992
8992
  if (result2.issues.length) {
8993
- payload.issues.push(...prefixIssues(key, result2.issues));
8993
+ payload2.issues.push(...prefixIssues(key, result2.issues));
8994
8994
  }
8995
- payload.value[key] = result2.value;
8995
+ payload2.value[key] = result2.value;
8996
8996
  }));
8997
8997
  } else {
8998
8998
  if (result.issues.length) {
8999
- payload.issues.push(...prefixIssues(key, result.issues));
8999
+ payload2.issues.push(...prefixIssues(key, result.issues));
9000
9000
  }
9001
- payload.value[key] = result.value;
9001
+ payload2.value[key] = result.value;
9002
9002
  }
9003
9003
  }
9004
9004
  }
@@ -9010,7 +9010,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
9010
9010
  }
9011
9011
  }
9012
9012
  if (unrecognized && unrecognized.length > 0) {
9013
- payload.issues.push({
9013
+ payload2.issues.push({
9014
9014
  code: "unrecognized_keys",
9015
9015
  input,
9016
9016
  inst,
@@ -9018,7 +9018,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
9018
9018
  });
9019
9019
  }
9020
9020
  } else {
9021
- payload.value = {};
9021
+ payload2.value = {};
9022
9022
  for (const key of Reflect.ownKeys(input)) {
9023
9023
  if (key === "__proto__")
9024
9024
  continue;
@@ -9027,7 +9027,7 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
9027
9027
  throw new Error("Async schemas not supported in object keys currently");
9028
9028
  }
9029
9029
  if (keyResult.issues.length) {
9030
- payload.issues.push({
9030
+ payload2.issues.push({
9031
9031
  origin: "record",
9032
9032
  code: "invalid_key",
9033
9033
  issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
@@ -9035,29 +9035,29 @@ var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
9035
9035
  path: [key],
9036
9036
  inst
9037
9037
  });
9038
- payload.value[keyResult.value] = keyResult.value;
9038
+ payload2.value[keyResult.value] = keyResult.value;
9039
9039
  continue;
9040
9040
  }
9041
9041
  const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);
9042
9042
  if (result instanceof Promise) {
9043
9043
  proms.push(result.then((result2) => {
9044
9044
  if (result2.issues.length) {
9045
- payload.issues.push(...prefixIssues(key, result2.issues));
9045
+ payload2.issues.push(...prefixIssues(key, result2.issues));
9046
9046
  }
9047
- payload.value[keyResult.value] = result2.value;
9047
+ payload2.value[keyResult.value] = result2.value;
9048
9048
  }));
9049
9049
  } else {
9050
9050
  if (result.issues.length) {
9051
- payload.issues.push(...prefixIssues(key, result.issues));
9051
+ payload2.issues.push(...prefixIssues(key, result.issues));
9052
9052
  }
9053
- payload.value[keyResult.value] = result.value;
9053
+ payload2.value[keyResult.value] = result.value;
9054
9054
  }
9055
9055
  }
9056
9056
  }
9057
9057
  if (proms.length) {
9058
- return Promise.all(proms).then(() => payload);
9058
+ return Promise.all(proms).then(() => payload2);
9059
9059
  }
9060
- return payload;
9060
+ return payload2;
9061
9061
  };
9062
9062
  });
9063
9063
  var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
@@ -9065,54 +9065,54 @@ var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
9065
9065
  const values = getEnumValues(def.entries);
9066
9066
  inst._zod.values = new Set(values);
9067
9067
  inst._zod.pattern = new RegExp(`^(${values.filter((k) => propertyKeyTypes.has(typeof k)).map((o) => typeof o === "string" ? escapeRegex(o) : o.toString()).join("|")})$`);
9068
- inst._zod.parse = (payload, _ctx) => {
9069
- const input = payload.value;
9068
+ inst._zod.parse = (payload2, _ctx) => {
9069
+ const input = payload2.value;
9070
9070
  if (inst._zod.values.has(input)) {
9071
- return payload;
9071
+ return payload2;
9072
9072
  }
9073
- payload.issues.push({
9073
+ payload2.issues.push({
9074
9074
  code: "invalid_value",
9075
9075
  values,
9076
9076
  input,
9077
9077
  inst
9078
9078
  });
9079
- return payload;
9079
+ return payload2;
9080
9080
  };
9081
9081
  });
9082
9082
  var $ZodLiteral = /* @__PURE__ */ $constructor("$ZodLiteral", (inst, def) => {
9083
9083
  $ZodType.init(inst, def);
9084
9084
  inst._zod.values = new Set(def.values);
9085
9085
  inst._zod.pattern = new RegExp(`^(${def.values.map((o) => typeof o === "string" ? escapeRegex(o) : o ? o.toString() : String(o)).join("|")})$`);
9086
- inst._zod.parse = (payload, _ctx) => {
9087
- const input = payload.value;
9086
+ inst._zod.parse = (payload2, _ctx) => {
9087
+ const input = payload2.value;
9088
9088
  if (inst._zod.values.has(input)) {
9089
- return payload;
9089
+ return payload2;
9090
9090
  }
9091
- payload.issues.push({
9091
+ payload2.issues.push({
9092
9092
  code: "invalid_value",
9093
9093
  values: def.values,
9094
9094
  input,
9095
9095
  inst
9096
9096
  });
9097
- return payload;
9097
+ return payload2;
9098
9098
  };
9099
9099
  });
9100
9100
  var $ZodTransform = /* @__PURE__ */ $constructor("$ZodTransform", (inst, def) => {
9101
9101
  $ZodType.init(inst, def);
9102
- inst._zod.parse = (payload, _ctx) => {
9103
- const _out = def.transform(payload.value, payload);
9102
+ inst._zod.parse = (payload2, _ctx) => {
9103
+ const _out = def.transform(payload2.value, payload2);
9104
9104
  if (_ctx.async) {
9105
9105
  const output = _out instanceof Promise ? _out : Promise.resolve(_out);
9106
9106
  return output.then((output2) => {
9107
- payload.value = output2;
9108
- return payload;
9107
+ payload2.value = output2;
9108
+ return payload2;
9109
9109
  });
9110
9110
  }
9111
9111
  if (_out instanceof Promise) {
9112
9112
  throw new $ZodAsyncError();
9113
9113
  }
9114
- payload.value = _out;
9115
- return payload;
9114
+ payload2.value = _out;
9115
+ return payload2;
9116
9116
  };
9117
9117
  });
9118
9118
  var $ZodOptional = /* @__PURE__ */ $constructor("$ZodOptional", (inst, def) => {
@@ -9126,14 +9126,14 @@ var $ZodOptional = /* @__PURE__ */ $constructor("$ZodOptional", (inst, def) => {
9126
9126
  const pattern = def.innerType._zod.pattern;
9127
9127
  return pattern ? new RegExp(`^(${cleanRegex(pattern.source)})?$`) : void 0;
9128
9128
  });
9129
- inst._zod.parse = (payload, ctx) => {
9129
+ inst._zod.parse = (payload2, ctx) => {
9130
9130
  if (def.innerType._zod.optin === "optional") {
9131
- return def.innerType._zod.run(payload, ctx);
9131
+ return def.innerType._zod.run(payload2, ctx);
9132
9132
  }
9133
- if (payload.value === void 0) {
9134
- return payload;
9133
+ if (payload2.value === void 0) {
9134
+ return payload2;
9135
9135
  }
9136
- return def.innerType._zod.run(payload, ctx);
9136
+ return def.innerType._zod.run(payload2, ctx);
9137
9137
  };
9138
9138
  });
9139
9139
  var $ZodNullable = /* @__PURE__ */ $constructor("$ZodNullable", (inst, def) => {
@@ -9147,43 +9147,43 @@ var $ZodNullable = /* @__PURE__ */ $constructor("$ZodNullable", (inst, def) => {
9147
9147
  defineLazy(inst._zod, "values", () => {
9148
9148
  return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, null]) : void 0;
9149
9149
  });
9150
- inst._zod.parse = (payload, ctx) => {
9151
- if (payload.value === null)
9152
- return payload;
9153
- return def.innerType._zod.run(payload, ctx);
9150
+ inst._zod.parse = (payload2, ctx) => {
9151
+ if (payload2.value === null)
9152
+ return payload2;
9153
+ return def.innerType._zod.run(payload2, ctx);
9154
9154
  };
9155
9155
  });
9156
9156
  var $ZodDefault = /* @__PURE__ */ $constructor("$ZodDefault", (inst, def) => {
9157
9157
  $ZodType.init(inst, def);
9158
9158
  inst._zod.optin = "optional";
9159
9159
  defineLazy(inst._zod, "values", () => def.innerType._zod.values);
9160
- inst._zod.parse = (payload, ctx) => {
9161
- if (payload.value === void 0) {
9162
- payload.value = def.defaultValue;
9163
- return payload;
9160
+ inst._zod.parse = (payload2, ctx) => {
9161
+ if (payload2.value === void 0) {
9162
+ payload2.value = def.defaultValue;
9163
+ return payload2;
9164
9164
  }
9165
- const result = def.innerType._zod.run(payload, ctx);
9165
+ const result = def.innerType._zod.run(payload2, ctx);
9166
9166
  if (result instanceof Promise) {
9167
9167
  return result.then((result2) => handleDefaultResult(result2, def));
9168
9168
  }
9169
9169
  return handleDefaultResult(result, def);
9170
9170
  };
9171
9171
  });
9172
- function handleDefaultResult(payload, def) {
9173
- if (payload.value === void 0) {
9174
- payload.value = def.defaultValue;
9172
+ function handleDefaultResult(payload2, def) {
9173
+ if (payload2.value === void 0) {
9174
+ payload2.value = def.defaultValue;
9175
9175
  }
9176
- return payload;
9176
+ return payload2;
9177
9177
  }
9178
9178
  var $ZodPrefault = /* @__PURE__ */ $constructor("$ZodPrefault", (inst, def) => {
9179
9179
  $ZodType.init(inst, def);
9180
9180
  inst._zod.optin = "optional";
9181
9181
  defineLazy(inst._zod, "values", () => def.innerType._zod.values);
9182
- inst._zod.parse = (payload, ctx) => {
9183
- if (payload.value === void 0) {
9184
- payload.value = def.defaultValue;
9182
+ inst._zod.parse = (payload2, ctx) => {
9183
+ if (payload2.value === void 0) {
9184
+ payload2.value = def.defaultValue;
9185
9185
  }
9186
- return def.innerType._zod.run(payload, ctx);
9186
+ return def.innerType._zod.run(payload2, ctx);
9187
9187
  };
9188
9188
  });
9189
9189
  var $ZodNonOptional = /* @__PURE__ */ $constructor("$ZodNonOptional", (inst, def) => {
@@ -9192,60 +9192,60 @@ var $ZodNonOptional = /* @__PURE__ */ $constructor("$ZodNonOptional", (inst, def
9192
9192
  const v = def.innerType._zod.values;
9193
9193
  return v ? new Set([...v].filter((x) => x !== void 0)) : void 0;
9194
9194
  });
9195
- inst._zod.parse = (payload, ctx) => {
9196
- const result = def.innerType._zod.run(payload, ctx);
9195
+ inst._zod.parse = (payload2, ctx) => {
9196
+ const result = def.innerType._zod.run(payload2, ctx);
9197
9197
  if (result instanceof Promise) {
9198
9198
  return result.then((result2) => handleNonOptionalResult(result2, inst));
9199
9199
  }
9200
9200
  return handleNonOptionalResult(result, inst);
9201
9201
  };
9202
9202
  });
9203
- function handleNonOptionalResult(payload, inst) {
9204
- if (!payload.issues.length && payload.value === void 0) {
9205
- payload.issues.push({
9203
+ function handleNonOptionalResult(payload2, inst) {
9204
+ if (!payload2.issues.length && payload2.value === void 0) {
9205
+ payload2.issues.push({
9206
9206
  code: "invalid_type",
9207
9207
  expected: "nonoptional",
9208
- input: payload.value,
9208
+ input: payload2.value,
9209
9209
  inst
9210
9210
  });
9211
9211
  }
9212
- return payload;
9212
+ return payload2;
9213
9213
  }
9214
9214
  var $ZodCatch = /* @__PURE__ */ $constructor("$ZodCatch", (inst, def) => {
9215
9215
  $ZodType.init(inst, def);
9216
9216
  inst._zod.optin = "optional";
9217
9217
  defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
9218
9218
  defineLazy(inst._zod, "values", () => def.innerType._zod.values);
9219
- inst._zod.parse = (payload, ctx) => {
9220
- const result = def.innerType._zod.run(payload, ctx);
9219
+ inst._zod.parse = (payload2, ctx) => {
9220
+ const result = def.innerType._zod.run(payload2, ctx);
9221
9221
  if (result instanceof Promise) {
9222
9222
  return result.then((result2) => {
9223
- payload.value = result2.value;
9223
+ payload2.value = result2.value;
9224
9224
  if (result2.issues.length) {
9225
- payload.value = def.catchValue({
9226
- ...payload,
9225
+ payload2.value = def.catchValue({
9226
+ ...payload2,
9227
9227
  error: {
9228
9228
  issues: result2.issues.map((iss) => finalizeIssue(iss, ctx, config()))
9229
9229
  },
9230
- input: payload.value
9230
+ input: payload2.value
9231
9231
  });
9232
- payload.issues = [];
9232
+ payload2.issues = [];
9233
9233
  }
9234
- return payload;
9234
+ return payload2;
9235
9235
  });
9236
9236
  }
9237
- payload.value = result.value;
9237
+ payload2.value = result.value;
9238
9238
  if (result.issues.length) {
9239
- payload.value = def.catchValue({
9240
- ...payload,
9239
+ payload2.value = def.catchValue({
9240
+ ...payload2,
9241
9241
  error: {
9242
9242
  issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config()))
9243
9243
  },
9244
- input: payload.value
9244
+ input: payload2.value
9245
9245
  });
9246
- payload.issues = [];
9246
+ payload2.issues = [];
9247
9247
  }
9248
- return payload;
9248
+ return payload2;
9249
9249
  };
9250
9250
  });
9251
9251
  var $ZodPipe = /* @__PURE__ */ $constructor("$ZodPipe", (inst, def) => {
@@ -9253,8 +9253,8 @@ var $ZodPipe = /* @__PURE__ */ $constructor("$ZodPipe", (inst, def) => {
9253
9253
  defineLazy(inst._zod, "values", () => def.in._zod.values);
9254
9254
  defineLazy(inst._zod, "optin", () => def.in._zod.optin);
9255
9255
  defineLazy(inst._zod, "optout", () => def.out._zod.optout);
9256
- inst._zod.parse = (payload, ctx) => {
9257
- const left = def.in._zod.run(payload, ctx);
9256
+ inst._zod.parse = (payload2, ctx) => {
9257
+ const left = def.in._zod.run(payload2, ctx);
9258
9258
  if (left instanceof Promise) {
9259
9259
  return left.then((left2) => handlePipeResult(left2, def, ctx));
9260
9260
  }
@@ -9273,35 +9273,35 @@ var $ZodReadonly = /* @__PURE__ */ $constructor("$ZodReadonly", (inst, def) => {
9273
9273
  defineLazy(inst._zod, "values", () => def.innerType._zod.values);
9274
9274
  defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
9275
9275
  defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
9276
- inst._zod.parse = (payload, ctx) => {
9277
- const result = def.innerType._zod.run(payload, ctx);
9276
+ inst._zod.parse = (payload2, ctx) => {
9277
+ const result = def.innerType._zod.run(payload2, ctx);
9278
9278
  if (result instanceof Promise) {
9279
9279
  return result.then(handleReadonlyResult);
9280
9280
  }
9281
9281
  return handleReadonlyResult(result);
9282
9282
  };
9283
9283
  });
9284
- function handleReadonlyResult(payload) {
9285
- payload.value = Object.freeze(payload.value);
9286
- return payload;
9284
+ function handleReadonlyResult(payload2) {
9285
+ payload2.value = Object.freeze(payload2.value);
9286
+ return payload2;
9287
9287
  }
9288
9288
  var $ZodCustom = /* @__PURE__ */ $constructor("$ZodCustom", (inst, def) => {
9289
9289
  $ZodCheck.init(inst, def);
9290
9290
  $ZodType.init(inst, def);
9291
- inst._zod.parse = (payload, _) => {
9292
- return payload;
9291
+ inst._zod.parse = (payload2, _) => {
9292
+ return payload2;
9293
9293
  };
9294
- inst._zod.check = (payload) => {
9295
- const input = payload.value;
9294
+ inst._zod.check = (payload2) => {
9295
+ const input = payload2.value;
9296
9296
  const r = def.fn(input);
9297
9297
  if (r instanceof Promise) {
9298
- return r.then((r2) => handleRefineResult(r2, payload, input, inst));
9298
+ return r.then((r2) => handleRefineResult(r2, payload2, input, inst));
9299
9299
  }
9300
- handleRefineResult(r, payload, input, inst);
9300
+ handleRefineResult(r, payload2, input, inst);
9301
9301
  return;
9302
9302
  };
9303
9303
  });
9304
- function handleRefineResult(result, payload, input, inst) {
9304
+ function handleRefineResult(result, payload2, input, inst) {
9305
9305
  if (!result) {
9306
9306
  const _iss = {
9307
9307
  code: "custom",
@@ -9315,7 +9315,7 @@ function handleRefineResult(result, payload, input, inst) {
9315
9315
  };
9316
9316
  if (inst._zod.def.params)
9317
9317
  _iss.params = inst._zod.def.params;
9318
- payload.issues.push(issue(_iss));
9318
+ payload2.issues.push(issue(_iss));
9319
9319
  }
9320
9320
  }
9321
9321
 
@@ -11209,30 +11209,30 @@ function literal(value, params) {
11209
11209
  var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
11210
11210
  $ZodTransform.init(inst, def);
11211
11211
  ZodType.init(inst, def);
11212
- inst._zod.parse = (payload, _ctx) => {
11213
- payload.addIssue = (issue2) => {
11212
+ inst._zod.parse = (payload2, _ctx) => {
11213
+ payload2.addIssue = (issue2) => {
11214
11214
  if (typeof issue2 === "string") {
11215
- payload.issues.push(util_exports.issue(issue2, payload.value, def));
11215
+ payload2.issues.push(util_exports.issue(issue2, payload2.value, def));
11216
11216
  } else {
11217
11217
  const _issue = issue2;
11218
11218
  if (_issue.fatal)
11219
11219
  _issue.continue = false;
11220
11220
  _issue.code ?? (_issue.code = "custom");
11221
- _issue.input ?? (_issue.input = payload.value);
11221
+ _issue.input ?? (_issue.input = payload2.value);
11222
11222
  _issue.inst ?? (_issue.inst = inst);
11223
11223
  _issue.continue ?? (_issue.continue = true);
11224
- payload.issues.push(util_exports.issue(_issue));
11224
+ payload2.issues.push(util_exports.issue(_issue));
11225
11225
  }
11226
11226
  };
11227
- const output = def.transform(payload.value, payload);
11227
+ const output = def.transform(payload2.value, payload2);
11228
11228
  if (output instanceof Promise) {
11229
11229
  return output.then((output2) => {
11230
- payload.value = output2;
11231
- return payload;
11230
+ payload2.value = output2;
11231
+ return payload2;
11232
11232
  });
11233
11233
  }
11234
- payload.value = output;
11235
- return payload;
11234
+ payload2.value = output;
11235
+ return payload2;
11236
11236
  };
11237
11237
  });
11238
11238
  function transform(fn) {
@@ -11360,22 +11360,22 @@ function refine(fn, _params = {}) {
11360
11360
  return _refine(ZodCustom, fn, _params);
11361
11361
  }
11362
11362
  function superRefine(fn) {
11363
- const ch = check((payload) => {
11364
- payload.addIssue = (issue2) => {
11363
+ const ch = check((payload2) => {
11364
+ payload2.addIssue = (issue2) => {
11365
11365
  if (typeof issue2 === "string") {
11366
- payload.issues.push(util_exports.issue(issue2, payload.value, ch._zod.def));
11366
+ payload2.issues.push(util_exports.issue(issue2, payload2.value, ch._zod.def));
11367
11367
  } else {
11368
11368
  const _issue = issue2;
11369
11369
  if (_issue.fatal)
11370
11370
  _issue.continue = false;
11371
11371
  _issue.code ?? (_issue.code = "custom");
11372
- _issue.input ?? (_issue.input = payload.value);
11372
+ _issue.input ?? (_issue.input = payload2.value);
11373
11373
  _issue.inst ?? (_issue.inst = ch);
11374
11374
  _issue.continue ?? (_issue.continue = !ch._zod.def.abort);
11375
- payload.issues.push(util_exports.issue(_issue));
11375
+ payload2.issues.push(util_exports.issue(_issue));
11376
11376
  }
11377
11377
  };
11378
- return fn(payload.value, payload);
11378
+ return fn(payload2.value, payload2);
11379
11379
  });
11380
11380
  return ch;
11381
11381
  }
@@ -21163,7 +21163,17 @@ var ApiError = class extends Error {
21163
21163
  this.body = body2;
21164
21164
  }
21165
21165
  };
21166
+ var LoginExpiredError = class extends ApiError {
21167
+ constructor() {
21168
+ super(
21169
+ 401,
21170
+ "O acesso pelo navegador expirou e n\xE3o deu para renovar sozinho. Rode `beplus-mcp login` de novo e autorize; n\xE3o precisa reiniciar o agente, a pr\xF3xima chamada j\xE1 usa o login novo."
21171
+ );
21172
+ this.name = "LoginExpiredError";
21173
+ }
21174
+ };
21166
21175
  function apiErrorToUserMessage(err) {
21176
+ if (err instanceof LoginExpiredError) return err.message;
21167
21177
  if (err instanceof ApiError) {
21168
21178
  const detail = err.message || "";
21169
21179
  switch (err.httpStatus) {
@@ -21195,6 +21205,333 @@ function apiErrorToUserMessage(err) {
21195
21205
  return String(err);
21196
21206
  }
21197
21207
 
21208
+ // src/credentials.ts
21209
+ import { chmod, mkdir, open, readFile, rename, stat, unlink, writeFile } from "fs/promises";
21210
+ import { homedir } from "os";
21211
+ import { dirname, join } from "path";
21212
+ function credentialsPath() {
21213
+ const base = process.env.XDG_CONFIG_HOME?.trim() || join(homedir(), ".config");
21214
+ return join(base, "beplus-mcp", "credentials.json");
21215
+ }
21216
+ async function readCredentials() {
21217
+ try {
21218
+ const raw = await readFile(credentialsPath(), "utf8");
21219
+ const parsed = JSON.parse(raw);
21220
+ if (!parsed.accessToken || !parsed.apiUrl) return null;
21221
+ return parsed;
21222
+ } catch {
21223
+ return null;
21224
+ }
21225
+ }
21226
+ async function writeCredentials(creds) {
21227
+ const path = credentialsPath();
21228
+ await mkdir(dirname(path), { recursive: true, mode: 448 });
21229
+ const tmp = `${path}.${process.pid}.tmp`;
21230
+ await writeFile(tmp, `${JSON.stringify(creds, null, 2)}
21231
+ `, { mode: 384 });
21232
+ await chmod(tmp, 384);
21233
+ await rename(tmp, path);
21234
+ return path;
21235
+ }
21236
+ async function clearCredentials() {
21237
+ try {
21238
+ await unlink(credentialsPath());
21239
+ return true;
21240
+ } catch {
21241
+ return false;
21242
+ }
21243
+ }
21244
+ var RENEW_MARGIN_MS = 6e4;
21245
+ function isExpired(creds) {
21246
+ return typeof creds.expiresAt === "number" && creds.expiresAt - RENEW_MARGIN_MS <= Date.now();
21247
+ }
21248
+ var credentialsLock = {
21249
+ staleMs: 3e4,
21250
+ waitMs: 35e3,
21251
+ pollMs: 100
21252
+ };
21253
+ async function withCredentialsLock(fn) {
21254
+ const path = credentialsPath();
21255
+ const lock = `${path}.lock`;
21256
+ await mkdir(dirname(path), { recursive: true, mode: 448 });
21257
+ const started = Date.now();
21258
+ for (; ; ) {
21259
+ try {
21260
+ const fh = await open(lock, "wx", 384);
21261
+ await fh.writeFile(String(process.pid));
21262
+ await fh.close();
21263
+ break;
21264
+ } catch (e) {
21265
+ if (e.code !== "EEXIST") throw e;
21266
+ try {
21267
+ const age = Date.now() - (await stat(lock)).mtimeMs;
21268
+ if (age > credentialsLock.staleMs) {
21269
+ await unlink(lock).catch(() => {
21270
+ });
21271
+ continue;
21272
+ }
21273
+ } catch {
21274
+ continue;
21275
+ }
21276
+ if (Date.now() - started > credentialsLock.waitMs) {
21277
+ throw new Error("Outro processo do beplus-mcp est\xE1 renovando o login h\xE1 tempo demais. Tente de novo em instantes.");
21278
+ }
21279
+ await new Promise((r) => setTimeout(r, credentialsLock.pollMs));
21280
+ }
21281
+ }
21282
+ try {
21283
+ return await fn();
21284
+ } finally {
21285
+ await unlink(lock).catch(() => {
21286
+ });
21287
+ }
21288
+ }
21289
+
21290
+ // src/oauth.ts
21291
+ import crypto from "crypto";
21292
+ import { createServer } from "http";
21293
+ import { spawn } from "child_process";
21294
+ var CALLBACK_TIMEOUT_MS = 5 * 6e4;
21295
+ var REQUEST_TIMEOUT_MS = 1e4;
21296
+ async function json(url, init) {
21297
+ let res;
21298
+ try {
21299
+ res = await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
21300
+ } catch {
21301
+ throw new Error(`Nao consegui falar com ${new URL(url).origin}. Confira a rede e o BEPLUS_API_URL.`);
21302
+ }
21303
+ const text = await res.text();
21304
+ let body2;
21305
+ try {
21306
+ body2 = text ? JSON.parse(text) : void 0;
21307
+ } catch {
21308
+ }
21309
+ if (!res.ok) {
21310
+ const msg = body2?.message ?? body2?.error_description ?? body2?.error ?? `HTTP ${res.status}`;
21311
+ throw new Error(`${msg} (${url})`);
21312
+ }
21313
+ return body2;
21314
+ }
21315
+ async function discover(apiUrl2) {
21316
+ const meta = await json(`${apiUrl2}/.well-known/oauth-authorization-server`);
21317
+ if (!meta.authorization_endpoint || !meta.token_endpoint || !meta.registration_endpoint) {
21318
+ throw new Error("O servidor respondeu a descoberta sem os endpoints obrigatorios.");
21319
+ }
21320
+ return meta;
21321
+ }
21322
+ function pkce() {
21323
+ const verifier = crypto.randomBytes(32).toString("base64url");
21324
+ return { verifier, challenge: crypto.createHash("sha256").update(verifier).digest("base64url") };
21325
+ }
21326
+ function openBrowser(url) {
21327
+ try {
21328
+ if (process.platform === "win32") {
21329
+ spawn("cmd.exe", ["/c", "start", '""', "/b", url.replace(/&/g, "^&")], {
21330
+ stdio: "ignore",
21331
+ detached: true,
21332
+ windowsVerbatimArguments: true
21333
+ }).unref();
21334
+ return;
21335
+ }
21336
+ const cmd = process.platform === "darwin" ? "open" : "xdg-open";
21337
+ spawn(cmd, [url], { stdio: "ignore", detached: true }).unref();
21338
+ } catch {
21339
+ }
21340
+ }
21341
+ var PAGINA_OK = `<!doctype html><meta charset="utf-8"><title>Pronto</title>
21342
+ <body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
21343
+ <div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Tudo certo</h1>
21344
+ <p style="margin:0;opacity:.7">Pode fechar esta aba e voltar para o seu agente.</p></div>`;
21345
+ var PAGINA_ERRO = `<!doctype html><meta charset="utf-8"><title>Nao deu</title>
21346
+ <body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
21347
+ <div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Nao foi dessa vez</h1>
21348
+ <p style="margin:0;opacity:.7">Volte ao terminal para ver o motivo.</p></div>`;
21349
+ function listenForCallback(expectedState) {
21350
+ return new Promise((resolvePort, rejectPort) => {
21351
+ let settle;
21352
+ let fail;
21353
+ const code = new Promise((res, rej) => {
21354
+ settle = res;
21355
+ fail = rej;
21356
+ });
21357
+ const server = createServer((req, res) => {
21358
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
21359
+ if (url.pathname !== "/callback") {
21360
+ res.writeHead(404).end();
21361
+ return;
21362
+ }
21363
+ const erro = url.searchParams.get("error");
21364
+ const recebido = url.searchParams.get("code");
21365
+ const state = url.searchParams.get("state") ?? "";
21366
+ const ok = !erro && recebido && state === expectedState;
21367
+ res.writeHead(ok ? 200 : 400, { "content-type": "text/html; charset=utf-8" });
21368
+ res.end(ok ? PAGINA_OK : PAGINA_ERRO);
21369
+ server.close();
21370
+ if (erro) return fail(new Error(url.searchParams.get("error_description") || erro));
21371
+ if (!recebido || state !== expectedState) return fail(new Error("Resposta de autorizacao invalida."));
21372
+ settle({ code: recebido, state });
21373
+ });
21374
+ server.on("error", rejectPort);
21375
+ server.listen(0, "127.0.0.1", () => {
21376
+ const addr = server.address();
21377
+ if (!addr || typeof addr === "string") return rejectPort(new Error("Nao consegui abrir a porta local."));
21378
+ const timer = setTimeout(() => {
21379
+ server.close();
21380
+ fail(new Error("Tempo esgotado esperando a autorizacao no navegador."));
21381
+ }, CALLBACK_TIMEOUT_MS);
21382
+ void code.finally(() => clearTimeout(timer));
21383
+ resolvePort({ port: addr.port, code });
21384
+ });
21385
+ });
21386
+ }
21387
+ function toStored(t, apiUrl2, clientId) {
21388
+ return {
21389
+ accessToken: t.access_token,
21390
+ refreshToken: t.refresh_token,
21391
+ expiresAt: t.expires_in ? Date.now() + t.expires_in * 1e3 : void 0,
21392
+ apiUrl: apiUrl2,
21393
+ clientId
21394
+ };
21395
+ }
21396
+ async function login(apiUrl2, onUrl) {
21397
+ const meta = await discover(apiUrl2);
21398
+ const state = crypto.randomBytes(24).toString("base64url");
21399
+ const { verifier, challenge } = pkce();
21400
+ const { port, code } = await listenForCallback(state);
21401
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
21402
+ const client = await json(meta.registration_endpoint, {
21403
+ method: "POST",
21404
+ headers: { "content-type": "application/json" },
21405
+ body: JSON.stringify({
21406
+ client_name: "beplus-mcp (CLI)",
21407
+ redirect_uris: [redirectUri],
21408
+ token_endpoint_auth_method: "none",
21409
+ grant_types: ["authorization_code", "refresh_token"]
21410
+ })
21411
+ });
21412
+ const authorizeUrl = new URL(meta.authorization_endpoint);
21413
+ authorizeUrl.searchParams.set("response_type", "code");
21414
+ authorizeUrl.searchParams.set("client_id", client.client_id);
21415
+ authorizeUrl.searchParams.set("redirect_uri", redirectUri);
21416
+ authorizeUrl.searchParams.set("code_challenge", challenge);
21417
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
21418
+ authorizeUrl.searchParams.set("state", state);
21419
+ onUrl(authorizeUrl.toString());
21420
+ openBrowser(authorizeUrl.toString());
21421
+ const { code: authCode } = await code;
21422
+ const token = await json(meta.token_endpoint, {
21423
+ method: "POST",
21424
+ headers: { "content-type": "application/json" },
21425
+ body: JSON.stringify({
21426
+ grant_type: "authorization_code",
21427
+ code: authCode,
21428
+ code_verifier: verifier,
21429
+ client_id: client.client_id,
21430
+ redirect_uri: redirectUri
21431
+ })
21432
+ });
21433
+ const path = await writeCredentials(toStored(token, apiUrl2, client.client_id));
21434
+ return { path, authorizeUrl: authorizeUrl.toString() };
21435
+ }
21436
+ var sameApi = (a, b) => a.replace(/\/+$/, "") === b.replace(/\/+$/, "");
21437
+ async function refreshGrant(apiUrl2, creds) {
21438
+ const meta = await discover(apiUrl2);
21439
+ const token = await json(meta.token_endpoint, {
21440
+ method: "POST",
21441
+ headers: { "content-type": "application/json" },
21442
+ body: JSON.stringify({
21443
+ grant_type: "refresh_token",
21444
+ refresh_token: creds.refreshToken,
21445
+ client_id: creds.clientId
21446
+ })
21447
+ });
21448
+ return toStored(token, apiUrl2, creds.clientId);
21449
+ }
21450
+ async function renewFromDisk(apiUrl2, rejected) {
21451
+ try {
21452
+ return await withCredentialsLock(async () => {
21453
+ const creds = await readCredentials();
21454
+ if (!creds || !sameApi(creds.apiUrl, apiUrl2)) return null;
21455
+ if (creds.accessToken !== rejected && !isExpired(creds)) return creds.accessToken;
21456
+ if (!creds.refreshToken) return null;
21457
+ const fresh = await refreshGrant(apiUrl2, creds);
21458
+ await writeCredentials(fresh);
21459
+ return fresh.accessToken;
21460
+ });
21461
+ } catch {
21462
+ return null;
21463
+ }
21464
+ }
21465
+ async function tokenFromDisk(apiUrl2) {
21466
+ const creds = await readCredentials();
21467
+ if (!creds || !sameApi(creds.apiUrl, apiUrl2)) return null;
21468
+ if (!isExpired(creds)) return creds.accessToken;
21469
+ if (!creds.refreshToken) return null;
21470
+ return renewFromDisk(apiUrl2, creds.accessToken);
21471
+ }
21472
+
21473
+ // src/auth.ts
21474
+ function staticToken(token) {
21475
+ return { renewable: false, current: async () => token, refresh: async () => null };
21476
+ }
21477
+ var LoginToken = class {
21478
+ constructor(apiUrl2, last) {
21479
+ this.apiUrl = apiUrl2;
21480
+ this.last = last;
21481
+ }
21482
+ apiUrl;
21483
+ last;
21484
+ renewable = true;
21485
+ /** Token cuja renovação antecipada acabou de falhar: o 401 dele não tenta de novo. */
21486
+ failedFor = null;
21487
+ async current() {
21488
+ const creds = await readCredentials();
21489
+ if (!creds || creds.apiUrl.replace(/\/+$/, "") !== this.apiUrl.replace(/\/+$/, "")) return this.last;
21490
+ if (isExpired(creds) && creds.refreshToken) {
21491
+ const fresh = await renewFromDisk(this.apiUrl, creds.accessToken);
21492
+ if (fresh) return this.last = fresh;
21493
+ this.failedFor = creds.accessToken;
21494
+ }
21495
+ return this.last = creds.accessToken;
21496
+ }
21497
+ async refresh(rejected) {
21498
+ if (rejected === this.failedFor) return null;
21499
+ const fresh = await renewFromDisk(this.apiUrl, rejected);
21500
+ if (fresh) this.last = fresh;
21501
+ return fresh;
21502
+ }
21503
+ };
21504
+ function tokenProvider(cfg) {
21505
+ return cfg.auth ?? staticToken(cfg.token);
21506
+ }
21507
+ async function fetchWithAuth(cfg, url, init, what) {
21508
+ const auth = tokenProvider(cfg);
21509
+ const send = async (token2) => {
21510
+ const { timeoutMs, headers, ...rest } = init;
21511
+ try {
21512
+ return await fetch(url, {
21513
+ ...rest,
21514
+ headers: { ...headers, Authorization: `Bearer ${token2}` },
21515
+ signal: AbortSignal.timeout(timeoutMs)
21516
+ });
21517
+ } catch (e) {
21518
+ const name = e?.name;
21519
+ if (name === "TimeoutError" || name === "AbortError") {
21520
+ throw new ApiError(408, `Tempo esgotado ao falar com a API BePlus (${what}).`);
21521
+ }
21522
+ throw new ApiError(0, `Falha de rede ao falar com a API BePlus (${what}). Confira BEPLUS_API_URL.`);
21523
+ }
21524
+ };
21525
+ const token = await auth.current();
21526
+ const res = await send(token);
21527
+ if (res.status !== 401 || !auth.renewable) return res;
21528
+ await res.body?.cancel().catch(() => {
21529
+ });
21530
+ const fresh = await auth.refresh(token);
21531
+ if (!fresh) throw new LoginExpiredError();
21532
+ return send(fresh);
21533
+ }
21534
+
21198
21535
  // src/api/client.ts
21199
21536
  var BeplusClient = class {
21200
21537
  constructor(cfg) {
@@ -21209,28 +21546,23 @@ var BeplusClient = class {
21209
21546
  if (v !== void 0 && v !== null && v !== "") url.searchParams.set(k, String(v));
21210
21547
  }
21211
21548
  }
21212
- const controller = new AbortController();
21213
- const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 3e4);
21214
- let res;
21215
- try {
21216
- res = await fetch(url, {
21549
+ const res = await fetchWithAuth(
21550
+ this.cfg,
21551
+ url,
21552
+ {
21217
21553
  method,
21218
- headers: {
21219
- Authorization: `Bearer ${this.cfg.token}`,
21220
- ...opts.body ? { "Content-Type": "application/json" } : {}
21221
- },
21554
+ headers: opts.body ? { "Content-Type": "application/json" } : {},
21222
21555
  body: opts.body ? JSON.stringify(opts.body) : void 0,
21223
- signal: controller.signal
21224
- });
21225
- } catch (e) {
21226
- if (e?.name === "AbortError") {
21227
- throw new ApiError(408, `Tempo esgotado ao falar com a API BePlus (${path}).`);
21228
- }
21229
- throw new ApiError(0, `Falha de rede ao falar com a API BePlus (${path}). Confira BEPLUS_API_URL.`);
21230
- } finally {
21231
- clearTimeout(timer);
21556
+ timeoutMs: opts.timeoutMs ?? 3e4
21557
+ },
21558
+ path
21559
+ );
21560
+ let text;
21561
+ try {
21562
+ text = await res.text();
21563
+ } catch {
21564
+ throw new ApiError(408, `Tempo esgotado ao falar com a API BePlus (${path}).`);
21232
21565
  }
21233
- const text = await res.text();
21234
21566
  let json2;
21235
21567
  if (text) {
21236
21568
  try {
@@ -21386,9 +21718,9 @@ async function pollUntilDone(client, generationId, budgetMs, jitterSeed = 0) {
21386
21718
  }
21387
21719
 
21388
21720
  // src/media.ts
21389
- import { readFile } from "fs/promises";
21721
+ import { readFile as readFile2, stat as stat2 } from "fs/promises";
21390
21722
  import { basename, extname, isAbsolute, resolve } from "path";
21391
- import { homedir } from "os";
21723
+ import { homedir as homedir2 } from "os";
21392
21724
  import { fileURLToPath } from "url";
21393
21725
  var MIME_BY_EXT = {
21394
21726
  ".png": "image/png",
@@ -21396,82 +21728,207 @@ var MIME_BY_EXT = {
21396
21728
  ".jpeg": "image/jpeg",
21397
21729
  ".webp": "image/webp",
21398
21730
  ".gif": "image/gif",
21731
+ ".avif": "image/avif",
21732
+ ".heic": "image/heic",
21733
+ ".heif": "image/heif",
21399
21734
  ".bmp": "image/bmp",
21735
+ ".tif": "image/tiff",
21736
+ ".tiff": "image/tiff",
21400
21737
  ".svg": "image/svg+xml",
21401
21738
  ".mp4": "video/mp4",
21402
21739
  ".mov": "video/quicktime",
21403
21740
  ".webm": "video/webm",
21404
21741
  ".m4v": "video/x-m4v",
21742
+ ".mkv": "video/x-matroska",
21743
+ ".mpeg": "video/mpeg",
21744
+ ".mpg": "video/mpeg",
21745
+ ".avi": "video/x-msvideo",
21746
+ ".3gp": "video/3gpp",
21405
21747
  ".mp3": "audio/mpeg",
21406
21748
  ".wav": "audio/wav",
21407
21749
  ".m4a": "audio/mp4",
21408
21750
  ".aac": "audio/aac",
21409
21751
  ".ogg": "audio/ogg",
21752
+ ".oga": "audio/ogg",
21753
+ ".opus": "audio/opus",
21410
21754
  ".flac": "audio/flac",
21411
- ".pdf": "application/pdf"
21755
+ ".aiff": "audio/aiff",
21756
+ ".aif": "audio/aiff",
21757
+ ".pdf": "application/pdf",
21758
+ ".md": "text/markdown",
21759
+ ".txt": "text/plain"
21412
21760
  };
21413
- var MAX_UPLOAD_BYTES = 300 * 1024 * 1024;
21761
+ var UPLOAD_EXTENSIONS = [
21762
+ "jpg",
21763
+ "jpeg",
21764
+ "png",
21765
+ "gif",
21766
+ "webp",
21767
+ "avif",
21768
+ "heic",
21769
+ "heif",
21770
+ "bmp",
21771
+ "tif",
21772
+ "tiff",
21773
+ "mp4",
21774
+ "webm",
21775
+ "mov",
21776
+ "m4v",
21777
+ "mkv",
21778
+ "mpeg",
21779
+ "mpg",
21780
+ "avi",
21781
+ "flv",
21782
+ "wmv",
21783
+ "3gp",
21784
+ "3gpp",
21785
+ "mp3",
21786
+ "wav",
21787
+ "ogg",
21788
+ "oga",
21789
+ "aac",
21790
+ "flac",
21791
+ "m4a",
21792
+ "opus",
21793
+ "wma",
21794
+ "aiff",
21795
+ "aif",
21796
+ "pdf",
21797
+ "md",
21798
+ "txt",
21799
+ "markdown"
21800
+ ];
21801
+ var MAX_UPLOAD_BYTES = 95 * 1024 * 1024;
21414
21802
  var UPLOAD_TIMEOUT_MS = 12e4;
21803
+ var DOWNLOAD_TIMEOUT_MS = 12e4;
21804
+ var BEPLUS_STORAGE_HOST = "storage.beplus.academy";
21415
21805
  function isRemoteRef(ref) {
21416
21806
  return /^https?:\/\//i.test(ref);
21417
21807
  }
21418
21808
  function toLocalPath(ref) {
21419
21809
  if (ref.startsWith("file://")) return fileURLToPath(ref);
21420
- if (ref === "~") return homedir();
21421
- if (ref.startsWith("~/")) return resolve(homedir(), ref.slice(2));
21810
+ if (ref === "~") return homedir2();
21811
+ if (ref.startsWith("~/")) return resolve(homedir2(), ref.slice(2));
21422
21812
  return isAbsolute(ref) ? ref : resolve(process.cwd(), ref);
21423
21813
  }
21424
- function mimeForPath(path) {
21425
- return MIME_BY_EXT[extname(path).toLowerCase()] ?? "application/octet-stream";
21814
+ function mimeForName(name) {
21815
+ return MIME_BY_EXT[extname(name).toLowerCase()] ?? "application/octet-stream";
21426
21816
  }
21427
- async function uploadFile(cfg, ref) {
21817
+ var extOf = (name) => extname(name).slice(1).toLowerCase();
21818
+ function mb(bytes) {
21819
+ return (bytes / 1024 / 1024).toFixed(1).replace(".", ",");
21820
+ }
21821
+ function tooLarge(name, bytes) {
21822
+ const size = bytes === null ? "passa" : `tem ${mb(bytes)} MB,`;
21823
+ return new ApiError(
21824
+ 413,
21825
+ `"${name}" ${size} acima do teto de 95 MB para subir pela API (o proxy da Cloudflare corta corpo acima de 100 MB antes de chegar no servidor). Comprima ou corte o arquivo (ex.: ffmpeg -i entrada.mp4 -crf 26 saida.mp4) e tente de novo.`
21826
+ );
21827
+ }
21828
+ async function loadLocal(ref) {
21428
21829
  const abs = toLocalPath(ref);
21429
- let buf;
21830
+ const name = basename(abs);
21831
+ let size;
21430
21832
  try {
21431
- buf = await readFile(abs);
21833
+ size = (await stat2(abs)).size;
21432
21834
  } catch {
21433
21835
  throw new ApiError(
21434
21836
  0,
21435
21837
  `Arquivo local n\xE3o encontrado: "${ref}". Passe um caminho v\xE1lido ou uma URL p\xFAblica (http/https).`
21436
21838
  );
21437
21839
  }
21438
- const name = basename(abs);
21439
- if (buf.byteLength > MAX_UPLOAD_BYTES) {
21440
- throw new ApiError(
21441
- 413,
21442
- `"${name}" tem ${(buf.byteLength / 1024 / 1024).toFixed(1)}MB \u2014 acima do limite de 300MB para upload.`
21443
- );
21444
- }
21445
- const form = new FormData();
21446
- form.append("file", new Blob([buf], { type: mimeForPath(abs) }), name);
21447
- const controller = new AbortController();
21448
- const timer = setTimeout(() => controller.abort(), UPLOAD_TIMEOUT_MS);
21840
+ if (size > MAX_UPLOAD_BYTES) throw tooLarge(name, size);
21841
+ return { buf: await readFile2(abs), name, mime: mimeForName(abs), localPath: abs };
21842
+ }
21843
+ async function loadRemote(url) {
21844
+ const u = new URL(url);
21845
+ let name = decodeURIComponent(basename(u.pathname)) || "arquivo";
21449
21846
  let res;
21450
21847
  try {
21451
- res = await fetch(`${cfg.baseUrl}/api/v1/files/upload`, {
21452
- method: "POST",
21453
- headers: { Authorization: `Bearer ${cfg.token}` },
21454
- body: form,
21455
- signal: controller.signal
21848
+ res = await fetch(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) });
21849
+ } catch {
21850
+ throw new ApiError(0, `N\xE3o consegui baixar ${url} (rede ou tempo esgotado).`);
21851
+ }
21852
+ if (!res.ok) {
21853
+ await res.body?.cancel().catch(() => {
21456
21854
  });
21855
+ throw new ApiError(res.status, `N\xE3o consegui baixar ${url}: a origem respondeu HTTP ${res.status}.`);
21856
+ }
21857
+ const declared = Number(res.headers.get("content-length") ?? NaN);
21858
+ if (Number.isFinite(declared) && declared > MAX_UPLOAD_BYTES) {
21859
+ await res.body?.cancel().catch(() => {
21860
+ });
21861
+ throw tooLarge(name, declared);
21862
+ }
21863
+ const chunks = [];
21864
+ let total = 0;
21865
+ try {
21866
+ const reader = res.body?.getReader();
21867
+ if (reader) {
21868
+ for (; ; ) {
21869
+ const { done, value } = await reader.read();
21870
+ if (done) break;
21871
+ total += value.byteLength;
21872
+ if (total > MAX_UPLOAD_BYTES) {
21873
+ await reader.cancel().catch(() => {
21874
+ });
21875
+ throw tooLarge(name, null);
21876
+ }
21877
+ chunks.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength));
21878
+ }
21879
+ }
21457
21880
  } catch (e) {
21458
- if (e?.name === "AbortError") {
21459
- throw new ApiError(408, `Tempo esgotado ao subir "${name}" para o R2.`);
21881
+ if (e instanceof ApiError) throw e;
21882
+ throw new ApiError(0, `O download de ${url} caiu no meio (rede ou tempo esgotado).`);
21883
+ }
21884
+ const buf = Buffer.concat(chunks);
21885
+ const typed = (res.headers.get("content-type") ?? "").split(";")[0].trim().toLowerCase();
21886
+ let mime = mimeForName(name);
21887
+ if (mime === "application/octet-stream" && typed) {
21888
+ const ext = Object.entries(MIME_BY_EXT).find(([, m]) => m === typed)?.[0];
21889
+ if (ext) {
21890
+ name = `${name.replace(/\.$/, "")}${ext}`;
21891
+ mime = typed;
21460
21892
  }
21461
- throw new ApiError(0, `Falha de rede ao subir "${name}" para o R2. Confira BEPLUS_API_URL.`);
21462
- } finally {
21463
- clearTimeout(timer);
21464
21893
  }
21465
- const text = await res.text();
21894
+ return { buf, name, mime };
21895
+ }
21896
+ async function uploadBytes(cfg, file) {
21897
+ const { buf, name, mime } = file;
21898
+ if (!UPLOAD_EXTENSIONS.includes(extOf(name))) {
21899
+ throw new ApiError(
21900
+ 422,
21901
+ `"${name}" n\xE3o sobe pela rota de arquivos da BePlus: a extens\xE3o n\xE3o est\xE1 na lista aceita (${UPLOAD_EXTENSIONS.join(", ")}). Converta para um desses formatos.`
21902
+ );
21903
+ }
21904
+ if (buf.byteLength > MAX_UPLOAD_BYTES) throw tooLarge(name, buf.byteLength);
21905
+ const form = new FormData();
21906
+ form.append("file", new Blob([buf], { type: mime }), name);
21907
+ const res = await fetchWithAuth(
21908
+ cfg,
21909
+ `${cfg.baseUrl}/api/v1/files/upload`,
21910
+ { method: "POST", body: form, timeoutMs: UPLOAD_TIMEOUT_MS },
21911
+ `upload de "${name}"`
21912
+ );
21466
21913
  let json2;
21467
- if (text) {
21468
- try {
21469
- json2 = JSON.parse(text);
21470
- } catch {
21471
- }
21914
+ try {
21915
+ const text = await res.text();
21916
+ json2 = text ? JSON.parse(text) : void 0;
21917
+ } catch {
21472
21918
  }
21473
21919
  if (!res.ok) {
21474
21920
  const message = json2?.message || res.statusText || `HTTP ${res.status}`;
21921
+ if (res.status === 413) throw tooLarge(name, buf.byteLength);
21922
+ if (res.status === 403) {
21923
+ throw new ApiError(
21924
+ 403,
21925
+ `Sem permiss\xE3o para subir "${name}" (${message}). No login pelo navegador, subir arquivo exige a permiss\xE3o ialab:spend: rode \`beplus-mcp login\` e autorize.`,
21926
+ json2
21927
+ );
21928
+ }
21929
+ if (res.status === 422) {
21930
+ throw new ApiError(422, `O servidor n\xE3o aceitou "${name}" (${message}). Confira o formato do arquivo.`, json2);
21931
+ }
21475
21932
  throw new ApiError(res.status, `Upload de "${name}" falhou: ${message}`, json2);
21476
21933
  }
21477
21934
  const fileUrl = json2?.result?.file_url ?? json2?.file_url;
@@ -21480,6 +21937,9 @@ async function uploadFile(cfg, ref) {
21480
21937
  }
21481
21938
  return fileUrl;
21482
21939
  }
21940
+ async function uploadFile(cfg, ref) {
21941
+ return uploadBytes(cfg, await loadLocal(ref));
21942
+ }
21483
21943
  async function resolveRef(cfg, ref) {
21484
21944
  if (!ref) return ref;
21485
21945
  return isRemoteRef(ref) ? ref : uploadFile(cfg, ref);
@@ -22395,9 +22855,9 @@ ${list}${flagsLine(status)}${draftHint}` }, ...blocks] };
22395
22855
  }
22396
22856
 
22397
22857
  // src/probe.ts
22398
- import { open, stat } from "fs/promises";
22858
+ import { open as open2, stat as stat3 } from "fs/promises";
22399
22859
  import { extname as extname2, isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
22400
- import { homedir as homedir2 } from "os";
22860
+ import { homedir as homedir3 } from "os";
22401
22861
  import { fileURLToPath as fileURLToPath2 } from "url";
22402
22862
  var IMAGE_EXT = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
22403
22863
  var VIDEO_EXT = /* @__PURE__ */ new Set([".mp4", ".mov", ".m4v"]);
@@ -22409,8 +22869,8 @@ function isRemote(ref) {
22409
22869
  }
22410
22870
  function toLocalPath2(ref) {
22411
22871
  if (ref.startsWith("file://")) return fileURLToPath2(ref);
22412
- if (ref === "~") return homedir2();
22413
- if (ref.startsWith("~/")) return resolve2(homedir2(), ref.slice(2));
22872
+ if (ref === "~") return homedir3();
22873
+ if (ref.startsWith("~/")) return resolve2(homedir3(), ref.slice(2));
22414
22874
  return isAbsolute2(ref) ? ref : resolve2(process.cwd(), ref);
22415
22875
  }
22416
22876
  function kindFromExt(ref) {
@@ -22421,7 +22881,7 @@ function kindFromExt(ref) {
22421
22881
  }
22422
22882
  async function readAt(ref, offset, len) {
22423
22883
  if (!isRemote(ref)) {
22424
- const fh = await open(toLocalPath2(ref), "r");
22884
+ const fh = await open2(toLocalPath2(ref), "r");
22425
22885
  try {
22426
22886
  const buf = Buffer.alloc(len);
22427
22887
  const { bytesRead } = await fh.read(buf, 0, len, offset);
@@ -22464,7 +22924,7 @@ async function findMoov(ref, fileSize) {
22464
22924
  }
22465
22925
  async function readHead(ref, bytes) {
22466
22926
  if (!isRemote(ref)) {
22467
- const fh = await open(toLocalPath2(ref), "r");
22927
+ const fh = await open2(toLocalPath2(ref), "r");
22468
22928
  try {
22469
22929
  const buf = Buffer.alloc(bytes);
22470
22930
  const { bytesRead } = await fh.read(buf, 0, bytes, 0);
@@ -22542,7 +23002,7 @@ function probeWebp(b) {
22542
23002
  }
22543
23003
  return null;
22544
23004
  }
22545
- function probeMp4(b) {
23005
+ function mp4Info(b) {
22546
23006
  let duration3;
22547
23007
  let width = 0;
22548
23008
  let height = 0;
@@ -22610,13 +23070,16 @@ function probeMp4(b) {
22610
23070
  }
22611
23071
  };
22612
23072
  walk(0, b.length, 0);
22613
- if (!width || !height) return null;
22614
23073
  const dur = duration3 ?? mediaDuration;
22615
- const fps = dur && frames ? Math.round(frames / dur * 100) / 100 : void 0;
23074
+ const fps = width && height && dur && frames ? Math.round(frames / dur * 100) / 100 : void 0;
22616
23075
  return { width, height, duration: dur, fps };
22617
23076
  }
23077
+ function probeMp4(b) {
23078
+ const info = mp4Info(b);
23079
+ return info.width && info.height ? info : null;
23080
+ }
22618
23081
  async function fileSizeOf(ref) {
22619
- if (!isRemote(ref)) return (await stat(toLocalPath2(ref))).size;
23082
+ if (!isRemote(ref)) return (await stat3(toLocalPath2(ref))).size;
22620
23083
  const res = await fetch(ref, { method: "HEAD" });
22621
23084
  return Number(res.headers.get("content-length") ?? 0);
22622
23085
  }
@@ -22659,6 +23122,124 @@ async function probeMedia(ref) {
22659
23122
  }
22660
23123
  return { kind, width: info.width, height: info.height, duration: info.duration, fps: info.fps };
22661
23124
  }
23125
+ function probeGif(b) {
23126
+ if (b.length < 10 || b.toString("ascii", 0, 4) !== "GIF8") return null;
23127
+ return { width: b.readUInt16LE(6), height: b.readUInt16LE(8) };
23128
+ }
23129
+ function probeWav(b) {
23130
+ if (b.length < 12 || b.toString("ascii", 0, 4) !== "RIFF" || b.toString("ascii", 8, 12) !== "WAVE") return null;
23131
+ let byteRate = 0;
23132
+ for (let i = 12; i + 8 <= b.length; ) {
23133
+ const id = b.toString("ascii", i, i + 4);
23134
+ const size = b.readUInt32LE(i + 4);
23135
+ if (id === "fmt " && i + 16 <= b.length) byteRate = b.readUInt32LE(i + 16);
23136
+ if (id === "data") {
23137
+ const bytes = size === 0 || size === 4294967295 || i + 8 + size > b.length ? b.length - i - 8 : size;
23138
+ return byteRate ? bytes / byteRate : null;
23139
+ }
23140
+ i += 8 + size + size % 2;
23141
+ }
23142
+ return null;
23143
+ }
23144
+ function probeFlac(b) {
23145
+ if (b.length < 42 || b.toString("ascii", 0, 4) !== "fLaC" || (b[4] & 127) !== 0) return null;
23146
+ const d = 8;
23147
+ const rate = b[d + 10] << 12 | b[d + 11] << 4 | b[d + 12] >> 4;
23148
+ const total = (b[d + 13] & 15) * 2 ** 32 + b.readUInt32BE(d + 14);
23149
+ return rate && total ? total / rate : null;
23150
+ }
23151
+ var MP3_KBPS = {
23152
+ v1: [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
23153
+ v2: [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160]
23154
+ };
23155
+ var MP3_RATES = { 3: [44100, 48e3, 32e3], 2: [22050, 24e3, 16e3], 0: [11025, 12e3, 8e3] };
23156
+ function probeMp3(b) {
23157
+ let i = 0;
23158
+ if (b.length > 10 && b.toString("ascii", 0, 3) === "ID3") {
23159
+ const size = (b[6] & 127) << 21 | (b[7] & 127) << 14 | (b[8] & 127) << 7 | b[9] & 127;
23160
+ i = 10 + size + (b[5] & 16 ? 10 : 0);
23161
+ }
23162
+ for (const end = Math.min(b.length - 4, i + 64 * 1024); i < end; i++) {
23163
+ if (b[i] !== 255 || (b[i + 1] & 224) !== 224) continue;
23164
+ const version2 = b[i + 1] >> 3 & 3;
23165
+ const layer = b[i + 1] >> 1 & 3;
23166
+ const kbps = MP3_KBPS[version2 === 3 ? "v1" : "v2"][b[i + 2] >> 4 & 15];
23167
+ const rate = MP3_RATES[version2]?.[b[i + 2] >> 2 & 3];
23168
+ if (version2 === 1 || layer !== 1 || !kbps || !rate) continue;
23169
+ const mono = (b[i + 3] >> 6 & 3) === 3;
23170
+ const spf = version2 === 3 ? 1152 : 576;
23171
+ const side = version2 === 3 ? mono ? 17 : 32 : mono ? 9 : 17;
23172
+ const xing = i + 4 + side;
23173
+ const tag = b.toString("ascii", xing, xing + 4);
23174
+ if ((tag === "Xing" || tag === "Info") && b[xing + 7] & 1) {
23175
+ const flags = b[xing + 7];
23176
+ const lame = xing + 12 + (flags & 2 ? 4 : 0) + (flags & 4 ? 100 : 0) + (flags & 8 ? 4 : 0);
23177
+ const gap = lame + 24 <= b.length && /^(LAME|Lavc|Lavf)/.test(b.toString("ascii", lame, lame + 4)) ? (b[lame + 21] << 4) + (b[lame + 22] >> 4) + ((b[lame + 22] & 15) << 8 | b[lame + 23]) : 0;
23178
+ return (b.readUInt32BE(xing + 8) * spf - gap) / rate;
23179
+ }
23180
+ if (b.toString("ascii", i + 36, i + 40) === "VBRI") return b.readUInt32BE(i + 36 + 14) * spf / rate;
23181
+ const tail = b.length >= 128 && b.toString("ascii", b.length - 128, b.length - 125) === "TAG" ? 128 : 0;
23182
+ return (b.length - i - tail) * 8 / (kbps * 1e3);
23183
+ }
23184
+ return null;
23185
+ }
23186
+ function probeBuffer(b, mime) {
23187
+ const round = (n) => Math.round(n * 1e3) / 1e3;
23188
+ if (mime.startsWith("image/")) {
23189
+ const dim = probePng(b) ?? probeJpeg(b) ?? probeWebp(b) ?? probeGif(b);
23190
+ return dim ? { width: dim.width, height: dim.height } : null;
23191
+ }
23192
+ if (/^(video|audio)\/(mp4|quicktime|x-m4v|x-m4a|aac)$/.test(mime) || probeMp4Head(b)) {
23193
+ const info = mp4Info(b);
23194
+ if (!info.duration && !info.width) return null;
23195
+ const meta = {};
23196
+ if (info.width && info.height && mime.startsWith("video/")) {
23197
+ meta.width = info.width;
23198
+ meta.height = info.height;
23199
+ if (info.fps) meta.fps = info.fps;
23200
+ }
23201
+ if (info.duration) meta.duration = round(info.duration);
23202
+ return meta;
23203
+ }
23204
+ if (mime.startsWith("audio/")) {
23205
+ const seconds = probeWav(b) ?? probeFlac(b) ?? (mime === "audio/mpeg" ? probeMp3(b) : null);
23206
+ return seconds ? { duration: round(seconds) } : null;
23207
+ }
23208
+ return null;
23209
+ }
23210
+ function probeMp4Head(b) {
23211
+ return b.length > 12 && b.toString("ascii", 4, 8) === "ftyp";
23212
+ }
23213
+ async function ffprobeFile(path, timeoutMs = 2e4) {
23214
+ const bin = process.env.BEPLUS_FFPROBE?.trim() || "ffprobe";
23215
+ if (bin === "0") return null;
23216
+ const { execFile } = await import("child_process");
23217
+ const out = await new Promise((done) => {
23218
+ execFile(
23219
+ bin,
23220
+ ["-v", "error", "-print_format", "json", "-show_entries", "format=duration:stream=codec_type,width,height,avg_frame_rate", path],
23221
+ { timeout: timeoutMs, maxBuffer: 1024 * 1024 },
23222
+ (err, stdout) => done(err ? null : stdout)
23223
+ );
23224
+ });
23225
+ if (!out) return null;
23226
+ try {
23227
+ const j = JSON.parse(out);
23228
+ const meta = {};
23229
+ const video = j.streams?.find((s) => s.codec_type === "video" && s.width && s.height);
23230
+ if (video) {
23231
+ meta.width = video.width;
23232
+ meta.height = video.height;
23233
+ const [n, d] = String(video.avg_frame_rate ?? "").split("/").map(Number);
23234
+ if (n && d) meta.fps = Math.round(n / d * 100) / 100;
23235
+ }
23236
+ const duration3 = Number(j.format?.duration);
23237
+ if (Number.isFinite(duration3) && duration3 > 0) meta.duration = Math.round(duration3 * 1e3) / 1e3;
23238
+ return Object.keys(meta).length ? meta : null;
23239
+ } catch {
23240
+ return null;
23241
+ }
23242
+ }
22662
23243
 
22663
23244
  // src/tools/upscale.ts
22664
23245
  var IMAGE_MODEL = "topaz/upscale/image/generative";
@@ -23468,6 +24049,9 @@ ${calls.map(callLine).join("\n\n")}`);
23468
24049
  );
23469
24050
  }
23470
24051
 
24052
+ // src/tools/canvas.ts
24053
+ import { createHash } from "crypto";
24054
+
23471
24055
  // src/canvas/api.ts
23472
24056
  var PINNED_CORE_VERSION = "ca7b3b406184c7f679f555c3a008013197182b23";
23473
24057
  function errorRaw(err) {
@@ -23784,6 +24368,7 @@ function knownPort(kind, side, port) {
23784
24368
  // src/canvas/core.ts
23785
24369
  import { randomBytes, randomUUID } from "crypto";
23786
24370
  var SCHEMA_VERSION = 1;
24371
+ var MAX_ENVELOPES_PER_COMMIT = 200;
23787
24372
  var MAX_OP_BYTES = 64 * 1024;
23788
24373
  var MAX_DATA_URL_BYTES = 8 * 1024;
23789
24374
  var CLIENT_ID = `mcp-${randomBytes(6).toString("hex")}`;
@@ -23931,6 +24516,38 @@ function removeNodeOps(doc, nodeId) {
23931
24516
  function batchOf(ops) {
23932
24517
  return ops.length === 1 ? ops[0] : { type: "batch", ops };
23933
24518
  }
24519
+ var OpTooLargeError = class extends Error {
24520
+ constructor(op, bytes) {
24521
+ super(`opera\xE7\xE3o de ${bytes} bytes`);
24522
+ this.op = op;
24523
+ this.bytes = bytes;
24524
+ this.name = "OpTooLargeError";
24525
+ }
24526
+ op;
24527
+ bytes;
24528
+ };
24529
+ function packEnvelopes(boardId3, ops, actorId, limit = MAX_OP_BYTES - 1024) {
24530
+ const bytes = (v) => Buffer.byteLength(JSON.stringify(v));
24531
+ const overhead = bytes(envelope(boardId3, { type: "batch", ops: [] }, actorId));
24532
+ const out = [];
24533
+ let cur = [];
24534
+ let size = overhead;
24535
+ const flush = () => {
24536
+ if (cur.length) out.push(envelope(boardId3, batchOf(cur), actorId));
24537
+ cur = [];
24538
+ size = overhead;
24539
+ };
24540
+ for (const op of ops) {
24541
+ const b = bytes(op);
24542
+ if (overhead + b > limit) throw new OpTooLargeError(op, b);
24543
+ const next = size + b + (cur.length ? 1 : 0);
24544
+ if (next > limit) flush();
24545
+ size += b + (cur.length ? 1 : 0);
24546
+ cur.push(op);
24547
+ }
24548
+ flush();
24549
+ return out;
24550
+ }
23934
24551
 
23935
24552
  // src/canvas/summary.ts
23936
24553
  var MAX_TEXT = 160;
@@ -23941,6 +24558,7 @@ var HEAVY_KEYS = /* @__PURE__ */ new Set([
23941
24558
  "main",
23942
24559
  "lastFrame",
23943
24560
  "sequence",
24561
+ "timeline",
23944
24562
  "points",
23945
24563
  "extra",
23946
24564
  "mentions",
@@ -24027,6 +24645,10 @@ function nodeLines(node, run) {
24027
24645
  facts.push(`${d.rows.length} linha(s)`);
24028
24646
  extra.push(...rowsLines(d.rows));
24029
24647
  }
24648
+ if (kind === "montage") {
24649
+ const fact = timelineFact(d);
24650
+ if (fact) facts.push(fact);
24651
+ }
24030
24652
  const main2 = spec?.main;
24031
24653
  if (main2 && typeof d[main2] === "string" && d[main2]) facts.push(`${main2}: "${oneLine(d[main2])}"`);
24032
24654
  for (const [key, value] of Object.entries(d)) {
@@ -24041,6 +24663,18 @@ function nodeLines(node, run) {
24041
24663
  if (run?.claimedBy) facts.push("rodando agora");
24042
24664
  return [facts.length ? `${head} \xB7 ${facts.join(" \xB7 ")}` : head, ...extra];
24043
24665
  }
24666
+ function timelineFact(d) {
24667
+ const volume = "musicGainDb/duckingDb n\xE3o valem para ela: o volume fica nos clipes e faixas";
24668
+ if (d.timeline !== void 0) {
24669
+ const legacy = d.sequence !== void 0 ? "; data.sequence \xE9 o legado congelado" : "";
24670
+ return `timeline (v3): ${JSON.stringify(d.timeline).length} caracteres (inteira em canvas_read_node sem path${legacy}; ${volume})`;
24671
+ }
24672
+ const seq = d.sequence;
24673
+ if (!seq || typeof seq !== "object" || Array.isArray(seq)) return null;
24674
+ const plans = Array.isArray(seq.plans) ? seq.plans.length : 0;
24675
+ const clips = seq.audioClips && typeof seq.audioClips === "object" && !Array.isArray(seq.audioClips) ? Object.values(seq.audioClips).reduce((t, list) => t + (Array.isArray(list) ? list.length : 0), 0) : 0;
24676
+ return `sequ\xEAncia (legado, sem data.timeline): ${plans} plano(s), ${clips} clipe(s) de \xE1udio, ${JSON.stringify(seq).length} caracteres (inteira em canvas_read_node sem path; ${volume})`;
24677
+ }
24044
24678
  function boardSummary(snap) {
24045
24679
  const doc = snap.doc;
24046
24680
  const nodes = Object.values(doc.nodes).sort((a, b) => a.position.x - b.position.x || a.position.y - b.position.y);
@@ -24065,28 +24699,46 @@ function boardSummary(snap) {
24065
24699
  return lines.join("\n");
24066
24700
  }
24067
24701
  function nodeDetail(node) {
24068
- const strip = (v, depth) => {
24702
+ let cuts = 0;
24703
+ const strip = (v, depth, path) => {
24069
24704
  if (typeof v === "string") {
24070
24705
  if (v.startsWith("data:")) return `[data-url ${v.length}b]`;
24071
- return v.length > 2e3 ? `${v.slice(0, 2e3)}\u2026 [+${v.length - 2e3}]` : v;
24706
+ if (v.length <= 2e3) return v;
24707
+ cuts++;
24708
+ return `${v.slice(0, 2e3)}\u2026 [+${v.length - 2e3} caracteres: path=${path}]`;
24072
24709
  }
24073
24710
  if (Array.isArray(v)) {
24074
- if (depth > 4) return `[${v.length} itens]`;
24075
- const head = v.slice(0, 60).map((x) => strip(x, depth + 1));
24076
- return v.length > 60 ? [...head, `\u2026 +${v.length - 60}`] : head;
24711
+ if (depth > 4) {
24712
+ cuts++;
24713
+ return `[${v.length} itens, ${JSON.stringify(v).length} caracteres: path=${path}]`;
24714
+ }
24715
+ const head = v.slice(0, 60).map((x, i) => strip(x, depth + 1, `${path}.${i}`));
24716
+ if (v.length <= 60) return head;
24717
+ cuts++;
24718
+ return [...head, `\u2026 +${v.length - 60} itens: path=${path}`];
24077
24719
  }
24078
24720
  if (v && typeof v === "object") {
24079
- if (depth > 4) return "{\u2026}";
24721
+ if (depth > 4) {
24722
+ cuts++;
24723
+ return `{${JSON.stringify(v).length} caracteres: path=${path}}`;
24724
+ }
24080
24725
  const out = {};
24081
24726
  for (const [k, x] of Object.entries(v)) {
24082
- out[k] = k === "points" || k === "sequence" ? "[omitido]" : strip(x, depth + 1);
24727
+ const at = path ? `${path}.${k}` : k;
24728
+ if (depth === 0 && (k === "points" || k === "sequence" || k === "timeline")) {
24729
+ cuts++;
24730
+ out[k] = `[omitido: ${JSON.stringify(x).length} caracteres: path=${k}]`;
24731
+ } else out[k] = strip(x, depth + 1, at);
24083
24732
  }
24084
24733
  return out;
24085
24734
  }
24086
24735
  return v;
24087
24736
  };
24737
+ const json2 = JSON.stringify(strip(node.data, 0, ""));
24738
+ const note = cuts ? `
24739
+ (${cuts} corte(s) marcado(s) com path=\u2026: leia inteiro com canvas_read_node e esse path)` : "";
24088
24740
  return `${node.id} \xB7 ${nodeKind(node) ?? node.type} \xB7 "${nodeName(node)}"
24089
- ${JSON.stringify(strip(node.data, 0))}`;
24741
+ ${json2}${note}`;
24090
24742
  }
24091
24743
  function changesSince(envelopes, doc) {
24092
24744
  const count = /* @__PURE__ */ new Map();
@@ -24283,8 +24935,8 @@ function registerCanvasCommentTools(server, api, run) {
24283
24935
  const st = status ?? "open";
24284
24936
  const [snap, threads] = await Promise.all([api.snapshot(board_id), api.listComments(board_id, st)]);
24285
24937
  const text = commentsSummary(threads, snap.doc, st);
24286
- const open2 = threads.some((t) => !t.resolvedAt);
24287
- return open2 ? `${text}
24938
+ const open3 = threads.some((t) => !t.resolvedAt);
24939
+ return open3 ? `${text}
24288
24940
 
24289
24941
  Para aplicar: leia o n\xF3 com canvas_read_board (node_ids), edite pelas canvas_* e feche com canvas_resolve_comment dizendo o que fez.` : text;
24290
24942
  })
@@ -24301,8 +24953,8 @@ Para aplicar: leia o n\xF3 com canvas_read_board (node_ids), edite pelas canvas_
24301
24953
  const thread = await onComment(
24302
24954
  () => api.createComment(board_id, { body: text, parentId: comment_id, ...m?.length ? { mentions: m } : {} })
24303
24955
  );
24304
- const open2 = thread?.resolvedAt ? "A thread est\xE1 resolvida; reabra com canvas_reopen_comment se precisar." : "A thread segue aberta.";
24305
- return `\u2705 Resposta ${newReplyId(thread)} em ${comment_id}: "${oneLine(text, 120)}". ${open2}`;
24956
+ const open3 = thread?.resolvedAt ? "A thread est\xE1 resolvida; reabra com canvas_reopen_comment se precisar." : "A thread segue aberta.";
24957
+ return `\u2705 Resposta ${newReplyId(thread)} em ${comment_id}: "${oneLine(text, 120)}". ${open3}`;
24306
24958
  })
24307
24959
  );
24308
24960
  server.registerTool(
@@ -24383,16 +25035,224 @@ Para aplicar: leia o n\xF3 com canvas_read_board (node_ids), edite pelas canvas_
24383
25035
  const nodes = Object.values(snap.doc.nodes);
24384
25036
  anchor = nodes.length ? { kind: "point", x: Math.min(...nodes.map((n) => n.position.x)), y: Math.min(...nodes.map((n) => n.position.y)) - 80 } : { kind: "point", x: 0, y: 0 };
24385
25037
  }
24386
- const created = await onComment(
24387
- () => api.createComment(args.board_id, {
24388
- body: args.body,
24389
- anchor,
24390
- ...args.mentions?.length ? { mentions: args.mentions } : {}
24391
- })
24392
- );
24393
- const where = describeAnchor(anchor, snap.doc).text;
24394
- const at = anchor.kind === "point" && args.x !== void 0 ? ` em (${args.x}, ${args.y})` : "";
24395
- return `\u2705 Coment\xE1rio ${created?.id ?? ""} criado ${where}${at}.`.replace(" ", " ");
25038
+ const created = await onComment(
25039
+ () => api.createComment(args.board_id, {
25040
+ body: args.body,
25041
+ anchor,
25042
+ ...args.mentions?.length ? { mentions: args.mentions } : {}
25043
+ })
25044
+ );
25045
+ const where = describeAnchor(anchor, snap.doc).text;
25046
+ const at = anchor.kind === "point" && args.x !== void 0 ? ` em (${args.x}, ${args.y})` : "";
25047
+ return `\u2705 Coment\xE1rio ${created?.id ?? ""} criado ${where}${at}.`.replace(" ", " ");
25048
+ })
25049
+ );
25050
+ }
25051
+
25052
+ // src/canvas/upload.ts
25053
+ import { randomUUID as randomUUID2 } from "crypto";
25054
+ import { basename as basename2, extname as extname3 } from "path";
25055
+ function kindOfMime(mime) {
25056
+ if (mime.startsWith("image/")) return "image";
25057
+ if (mime.startsWith("video/")) return "video";
25058
+ if (mime.startsWith("audio/")) return "audio";
25059
+ return "file";
25060
+ }
25061
+ function withExtension(name, file) {
25062
+ if (!name?.trim()) return file.name;
25063
+ const ext = extname3(file.name);
25064
+ const clean = basename2(name.trim());
25065
+ return ext && extname3(clean).toLowerCase() !== ext.toLowerCase() ? `${clean}${ext}` : clean;
25066
+ }
25067
+ async function uploadMedia(cfg, source, name) {
25068
+ const remote = isRemoteRef(source);
25069
+ const loaded = remote ? await loadRemote(source) : await loadLocal(source);
25070
+ const file = { ...loaded, name: withExtension(name, loaded) };
25071
+ const reused = remote && new URL(source).host === BEPLUS_STORAGE_HOST;
25072
+ const url = reused ? source : await uploadBytes(cfg, file);
25073
+ const kind = kindOfMime(file.mime);
25074
+ let meta = null;
25075
+ let measuredBy = "n\xE3o medido";
25076
+ if (kind !== "file") {
25077
+ meta = probeBuffer(file.buf, file.mime);
25078
+ if (meta) measuredBy = "cabe\xE7alho";
25079
+ else {
25080
+ meta = await ffprobeFile(file.localPath ?? url);
25081
+ if (meta) measuredBy = "ffprobe";
25082
+ }
25083
+ }
25084
+ return {
25085
+ url,
25086
+ name: file.name,
25087
+ mime: file.mime,
25088
+ bytes: file.buf.byteLength,
25089
+ kind,
25090
+ meta: meta ?? {},
25091
+ measuredBy,
25092
+ reused,
25093
+ assetId: `asset_${randomUUID2()}`
25094
+ };
25095
+ }
25096
+ function mediaItem(u) {
25097
+ const item = { assetId: u.assetId, name: u.name, mime: u.mime, size: u.bytes };
25098
+ if (u.meta.width !== void 0) item.width = u.meta.width;
25099
+ if (u.meta.height !== void 0) item.height = u.meta.height;
25100
+ if (u.meta.duration !== void 0) item.duration = u.meta.duration;
25101
+ item.remoteUrl = u.url;
25102
+ return item;
25103
+ }
25104
+ function sequenceAsset(u) {
25105
+ return { assetId: u.assetId, name: u.name, mime: u.mime, size: u.bytes, origin: "imported" };
25106
+ }
25107
+ function libraryItemId(u, mediaNodeId) {
25108
+ return `${mediaNodeId ?? "<id do n\xF3 M\xEDdia>"}|${u.kind}::${u.url}`;
25109
+ }
25110
+ function describeUpload(u) {
25111
+ const parts = [u.mime, `${mb(u.bytes)} MB`];
25112
+ if (u.meta.width && u.meta.height) parts.push(`${u.meta.width}\xD7${u.meta.height}`);
25113
+ if (u.meta.duration !== void 0) parts.push(`${String(u.meta.duration).replace(".", ",")} s`);
25114
+ if (u.meta.fps) parts.push(`${String(u.meta.fps).replace(".", ",")} fps`);
25115
+ const measured = u.kind === "file" ? "" : u.measuredBy === "n\xE3o medido" ? " (dura\xE7\xE3o e dimens\xF5es n\xE3o medidas: formato sem leitor de cabe\xE7alho e sem ffprobe no PATH)" : ` (medido pelo ${u.measuredBy})`;
25116
+ return `"${u.name}" \xB7 ${parts.join(" \xB7 ")}${measured}`;
25117
+ }
25118
+
25119
+ // src/tools/canvas-media.ts
25120
+ var MAX_MEDIA_ITEMS = 60;
25121
+ var itemsOf = (node) => Array.isArray(node.data.items) ? node.data.items : [];
25122
+ function holdsOne(doc, node) {
25123
+ if (node.data.holds === "one") return true;
25124
+ if (node.data.holds === "many") return false;
25125
+ return itemsOf(node).length === 1 && Object.values(doc.edges).some((e) => e.source === node.id);
25126
+ }
25127
+ function needMediaNode(doc, nodeId) {
25128
+ const node = doc.nodes[nodeId];
25129
+ if (!node) throw new CanvasToolError(`N\xF3 ${nodeId} n\xE3o existe no board. Releia com canvas_read_board.`);
25130
+ if (nodeKind(node) !== "media") {
25131
+ throw new CanvasToolError(
25132
+ `O n\xF3 ${nodeId} ("${oneLine(nodeName(node), 40)}") \xE9 ${nodeKind(node) ?? node.type}, n\xE3o M\xEDdia. Passe o id de um n\xF3 media, ou omita node_id para criar um n\xF3 M\xEDdia novo.`
25133
+ );
25134
+ }
25135
+ return node;
25136
+ }
25137
+ function payload(u, nodeId) {
25138
+ const out = { url: u.url, mime: u.mime, bytes: u.bytes };
25139
+ if (u.meta.duration !== void 0) out.duration = u.meta.duration;
25140
+ if (u.meta.width !== void 0) out.width = u.meta.width;
25141
+ if (u.meta.height !== void 0) out.height = u.meta.height;
25142
+ if (u.meta.fps !== void 0) out.fps = u.meta.fps;
25143
+ out.media_item = mediaItem(u);
25144
+ if (u.kind !== "file") {
25145
+ out.sequence_asset = sequenceAsset(u);
25146
+ out.libraryItemId = libraryItemId(u, nodeId);
25147
+ }
25148
+ return JSON.stringify(out);
25149
+ }
25150
+ function sequenceHint(u, nodeId) {
25151
+ if (u.kind === "file") return "Documento: entra no n\xF3 M\xEDdia, n\xE3o na timeline da Montagem.";
25152
+ const lines = [
25153
+ "Num clipe da timeline da Montagem (data.timeline; data.sequence s\xF3 em n\xF3 que ainda n\xE3o migrou): use sequence_asset como `asset` e libraryItemId como est\xE1" + (nodeId ? "." : ", trocando <id do n\xF3 M\xEDdia> pelo id do n\xF3 onde o item ficou.")
25154
+ ];
25155
+ if (u.meta.duration !== void 0) {
25156
+ const at30 = Math.floor(u.meta.duration * 30 + 1e-9);
25157
+ lines.push(`Quadros = dura\xE7\xE3o \xD7 fps da timeline, para baixo (ex.: ${at30} a 30 fps).`);
25158
+ }
25159
+ return lines.join(" ");
25160
+ }
25161
+ function registerCanvasMediaTools(server, deps) {
25162
+ const { api, cfg, run, edit, seen, placeFor } = deps;
25163
+ server.registerTool(
25164
+ "canvas_upload_media",
25165
+ {
25166
+ title: "Canvas: subir arquivo",
25167
+ description: "Sobe um arquivo (caminho local ou URL) pela rota de arquivos da BePlus e devolve o item pronto: url, mime, bytes, dura\xE7\xE3o/largura/altura quando \xE9 m\xEDdia, media_item (data.items do n\xF3 M\xEDdia), sequence_asset e libraryItemId (clipe da timeline da Montagem). Com board_id grava no n\xF3 M\xEDdia node_id, ou cria um n\xF3 M\xEDdia novo sem node_id; a\xED exige canvas_read_board nesta sess\xE3o. Teto de 95 MB. N\xE3o gera m\xEDdia nem gasta diamantes.",
25168
+ inputSchema: {
25169
+ source: external_exports.string().trim().min(1).max(2e3).describe("Caminho local (/\u2026, ~/\u2026, file://) ou URL http(s)."),
25170
+ name: external_exports.string().trim().min(1).max(120).optional().describe("Nome do arquivo no Canvas (a extens\xE3o \xE9 mantida)."),
25171
+ board_id: external_exports.string().uuid().optional().describe("Board onde gravar o item (opcional)."),
25172
+ node_id: external_exports.string().min(1).max(128).optional().describe("N\xF3 M\xEDdia que recebe o item. Sem ele, cria um n\xF3 M\xEDdia novo."),
25173
+ label: external_exports.string().trim().min(1).max(120).optional().describe("Nome do n\xF3 M\xEDdia novo (padr\xE3o: nome do arquivo)."),
25174
+ replace: external_exports.boolean().optional().describe("true troca a lista do n\xF3 por este arquivo; false acrescenta. Padr\xE3o: a regra do Canvas (n\xF3 de um arquivo s\xF3, ligado, troca).")
25175
+ },
25176
+ annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true }
25177
+ },
25178
+ async (args) => run(async () => {
25179
+ if (!args.board_id && (args.node_id || args.label || args.replace !== void 0)) {
25180
+ throw new CanvasToolError("node_id, label e replace s\xF3 valem com board_id.");
25181
+ }
25182
+ if (args.board_id) {
25183
+ if (!seen.has(args.board_id)) {
25184
+ throw new CanvasToolError("Leia o board com canvas_read_board antes de gravar nele (a leitura vale para a sess\xE3o).");
25185
+ }
25186
+ const snap = await api.snapshot(args.board_id);
25187
+ if (snap.role === "viewer") throw new CanvasToolError("Voc\xEA \xE9 s\xF3 leitor neste board: pe\xE7a ao dono para te dar papel de editor.");
25188
+ if (args.node_id) {
25189
+ const node = needMediaNode(snap.doc, args.node_id);
25190
+ const replacing = args.replace ?? holdsOne(snap.doc, node);
25191
+ if (!replacing && itemsOf(node).length >= MAX_MEDIA_ITEMS) {
25192
+ throw new CanvasToolError(
25193
+ `O n\xF3 "${oneLine(nodeName(node), 40)}" j\xE1 tem ${MAX_MEDIA_ITEMS} arquivos (teto do Canvas). Omita node_id para criar outro n\xF3 M\xEDdia.`
25194
+ );
25195
+ }
25196
+ }
25197
+ }
25198
+ let u;
25199
+ try {
25200
+ u = await uploadMedia(cfg, args.source, args.name);
25201
+ } catch (e) {
25202
+ if (e instanceof ApiError && e.httpStatus !== 401) throw new CanvasToolError(e.message);
25203
+ throw e;
25204
+ }
25205
+ const head = `\u2705 ${u.reused ? "J\xE1 estava no armazenamento da BePlus (n\xE3o subiu de novo)" : "Subiu"}: ${describeUpload(u)}
25206
+ URL: ${u.url}`;
25207
+ if (!args.board_id) {
25208
+ return [head, "", payload(u), "", sequenceHint(u)].join("\n");
25209
+ }
25210
+ const boardId3 = args.board_id;
25211
+ let nodeId = args.node_id;
25212
+ let done;
25213
+ try {
25214
+ done = await edit(boardId3, async (doc) => {
25215
+ const item = mediaItem(u);
25216
+ if (nodeId) {
25217
+ const node = needMediaNode(doc, nodeId);
25218
+ const replacing = args.replace ?? holdsOne(doc, node);
25219
+ const items = replacing ? [item] : [...itemsOf(node), item];
25220
+ if (items.length > MAX_MEDIA_ITEMS) {
25221
+ throw new CanvasToolError(`O n\xF3 j\xE1 tem ${MAX_MEDIA_ITEMS} arquivos (teto do Canvas).`);
25222
+ }
25223
+ const before = itemsOf(node).length;
25224
+ return {
25225
+ ops: [{ type: "node.set", nodeId: node.id, path: "data.items", value: setValue(items) }],
25226
+ targets: [node.id],
25227
+ done: `N\xF3 M\xEDdia "${oneLine(nodeName(node), 40)}" (${node.id}): ` + (replacing ? `arquivo trocado (${before} \u2192 1)` : `arquivo acrescentado, agora com ${items.length}`)
25228
+ };
25229
+ }
25230
+ const spec = KINDS.media;
25231
+ const created = makeNode({
25232
+ type: WORKFLOW_NODE_TYPE,
25233
+ data: { ...spec.data, [KIND_FIELD]: "media", label: args.label ?? u.name, items: [item] },
25234
+ position: placeFor(doc, spec.size),
25235
+ size: spec.size,
25236
+ zIndex: Object.values(doc.nodes).reduce((t, n) => Math.max(t, n.zIndex), 0) + 1,
25237
+ createdBy: await api.me()
25238
+ });
25239
+ nodeId = created.id;
25240
+ return {
25241
+ ops: [{ type: "node.add", nodeId: created.id, node: created }],
25242
+ targets: [],
25243
+ done: `N\xF3 M\xEDdia "${oneLine(nodeName(created), 40)}" criado: ${created.id}`
25244
+ };
25245
+ });
25246
+ } catch (e) {
25247
+ const why = e instanceof CanvasToolError ? e.message : apiErrorToUserMessage(e);
25248
+ throw new CanvasToolError(
25249
+ `${head}
25250
+ Mas o item N\xC3O entrou no board: ${why}
25251
+ N\xE3o suba de novo: releia com canvas_read_board e grave media_item em data.items do n\xF3 M\xEDdia (canvas_update_node com a lista inteira) ou em um n\xF3 novo.
25252
+ ${payload(u)}`
25253
+ );
25254
+ }
25255
+ return [head, done, "", payload(u, nodeId), "", sequenceHint(u, nodeId)].join("\n");
24396
25256
  })
24397
25257
  );
24398
25258
  }
@@ -24404,6 +25264,22 @@ var REJECT_TEXT = {
24404
25264
  "invalid-op": "opera\xE7\xE3o inv\xE1lida ou repetida",
24405
25265
  "too-large": "opera\xE7\xE3o grande demais (64 KB) ou com m\xEDdia embutida"
24406
25266
  };
25267
+ var READ = "Exige canvas_read_board nesta sess\xE3o (e de novo depois de uma recusa). ";
25268
+ var MONTAGE_NOTE = "Montagem: musicGainDb, duckingDb e fadeMs valem s\xF3 para a montagem autom\xE1tica (clipes ligados) e n\xE3o mexem na timeline do editor (data.timeline; data.sequence \xE9 o legado); o volume dela fica nos clipes (gainDb, gainKeyframes, fades) e nas faixas (gainDb de cada faixa, master).";
25269
+ function dataSegments(path) {
25270
+ const p = path?.trim() ?? "";
25271
+ if (!p || p === "data") return [];
25272
+ const segs = (p.startsWith("data.") ? p.slice(5) : p).split(".");
25273
+ if (segs.some((seg) => !seg)) throw new CanvasToolError(`Caminho "${p}" tem segmento vazio (dois pontos seguidos ou ponto na ponta).`);
25274
+ return segs;
25275
+ }
25276
+ function legacySequenceGuard(node, key) {
25277
+ if (key === "sequence" && nodeKind(node) === "montage" && node.data.timeline !== void 0) {
25278
+ throw new CanvasToolError(
25279
+ "Este n\xF3 Montagem j\xE1 grava em data.timeline; data.sequence \xE9 o legado congelado e n\xE3o se escreve mais. Leia a timeline com canvas_read_node e grave por caminho em data.timeline com canvas_patch_node."
25280
+ );
25281
+ }
25282
+ }
24407
25283
  var SECTION_Z = -1e3;
24408
25284
  var GAP = 80;
24409
25285
  var boardId2 = external_exports.string().uuid().describe("Id (uuid) do board, como sai em canvas_list_boards.");
@@ -24414,10 +25290,9 @@ function registerCanvasTools(server, client, cfg) {
24414
25290
  const seen = /* @__PURE__ */ new Map();
24415
25291
  function fail(e) {
24416
25292
  if (e instanceof CanvasToolError || e instanceof CoreMismatchError) return errorResult(e.message);
25293
+ if (e instanceof LoginExpiredError) return errorResult(e.message);
24417
25294
  if (e instanceof ApiError && e.httpStatus === 401 && !api.usesPat) {
24418
- return errorResult(
24419
- "O acesso pelo navegador expirou ou foi revogado. Rode `beplus-mcp login` de novo e autorize."
24420
- );
25295
+ return errorResult(`O servidor recusou o acesso pelo navegador (${e.message}). Rode \`beplus-mcp login\` de novo e autorize.`);
24421
25296
  }
24422
25297
  if (e instanceof ApiError && e.httpStatus === 404) {
24423
25298
  return errorResult("Board n\xE3o encontrado, ou voc\xEA n\xE3o \xE9 membro dele. Confira o id em canvas_list_boards.");
@@ -24431,7 +25306,7 @@ function registerCanvasTools(server, client, cfg) {
24431
25306
  return fail(e);
24432
25307
  }
24433
25308
  }
24434
- async function edit(id, build) {
25309
+ async function edit(id, build, opts = {}) {
24435
25310
  const last = seen.get(id);
24436
25311
  if (last === void 0) {
24437
25312
  throw new CanvasToolError("Leia o board com canvas_read_board antes de editar (a leitura vale para a sess\xE3o).");
@@ -24462,6 +25337,7 @@ function registerCanvasTools(server, client, cfg) {
24462
25337
  if (theirs.length) note = `
24463
25338
  Aviso: ${changesSince(theirs, doc)}.`;
24464
25339
  }
25340
+ if (opts.split) return commitSplit(id, ops, done, note);
24465
25341
  const env = envelope(id, batchOf(ops), await api.me());
24466
25342
  const bad = checkEnvelope(env);
24467
25343
  if (bad) throw new CanvasToolError(`Edi\xE7\xE3o recusada antes de enviar: ${bad}.`);
@@ -24475,6 +25351,50 @@ Aviso: ${changesSince(theirs, doc)}.`;
24475
25351
  seen.set(id, res.seq);
24476
25352
  return `\u2705 ${done} (seq ${res.seq}).${note}`;
24477
25353
  }
25354
+ async function commitSplit(id, ops, done, note) {
25355
+ let envs;
25356
+ try {
25357
+ envs = packEnvelopes(id, ops, await api.me());
25358
+ } catch (e) {
25359
+ if (!(e instanceof OpTooLargeError)) throw e;
25360
+ const path = e.op.type === "node.set" ? e.op.path.replace(/^data\./, "") : e.op.type;
25361
+ throw new CanvasToolError(
25362
+ `O valor de ${path} tem ${Math.round(e.bytes / 1024)} KB e n\xE3o cabe num envelope (64 KB). Nada foi enviado: grave por partes menores (um caminho por item, ex.: <cole\xE7\xE3o>.<id>).`
25363
+ );
25364
+ }
25365
+ for (const env of envs) {
25366
+ const bad = checkEnvelope(env);
25367
+ if (bad) throw new CanvasToolError(`Edi\xE7\xE3o recusada antes de enviar: ${bad}. Nada foi enviado.`);
25368
+ }
25369
+ const outcomes = /* @__PURE__ */ new Map();
25370
+ let last = null;
25371
+ for (let i = 0; i < envs.length; i += MAX_ENVELOPES_PER_COMMIT) {
25372
+ const res = await api.commit(id, envs.slice(i, i + MAX_ENVELOPES_PER_COMMIT));
25373
+ for (const o of res.outcomes) outcomes.set(o.opId, o);
25374
+ last = res.seq;
25375
+ }
25376
+ const pathsOf = (op) => op.type === "batch" ? op.ops.flatMap(pathsOf) : op.type === "node.set" ? [op.path.replace(/^data\./, "")] : [op.type];
25377
+ let failed = 0;
25378
+ const lines = envs.map((env, i) => {
25379
+ const paths = pathsOf(env.op);
25380
+ const span = paths.length > 1 ? `${paths[0]} \u2026 ${paths[paths.length - 1]}` : paths[0];
25381
+ const kb = (Buffer.byteLength(JSON.stringify(env)) / 1024).toFixed(1).replace(".", ",");
25382
+ const o = outcomes.get(env.id);
25383
+ const result = o && "seq" in o ? `seq ${o.seq}` : (failed++, `RECUSADO (${o && "rejected" in o ? REJECT_TEXT[o.rejected] ?? o.rejected : "sem resposta do servidor"}): nada deste envelope entrou`);
25384
+ return `- envelope ${i + 1}/${envs.length}: ${paths.length} caminho(s) (${span}), ${kb} KB \u2192 ${result}`;
25385
+ });
25386
+ if (failed) {
25387
+ seen.delete(id);
25388
+ throw new CanvasToolError(
25389
+ `${done}: ${envs.length - failed} de ${envs.length} envelope(s) entraram, ${failed} recusado(s).
25390
+ ${lines.join("\n")}
25391
+ Os aceitos ficam. Releia com canvas_read_board e canvas_read_node e reenvie s\xF3 os caminhos dos envelopes recusados.` + note
25392
+ );
25393
+ }
25394
+ if (last !== null) seen.set(id, last);
25395
+ return `\u2705 ${done} em ${envs.length} envelope(s) (seq at\xE9 ${last}).
25396
+ ${lines.join("\n")}${note}`;
25397
+ }
24478
25398
  function needNode(doc, nodeId) {
24479
25399
  const node = doc.nodes[nodeId];
24480
25400
  if (!node) throw new CanvasToolError(`N\xF3 ${nodeId} n\xE3o existe no board. Releia com canvas_read_board.`);
@@ -24548,10 +25468,10 @@ Aviso: ${changesSince(theirs, doc)}.`;
24548
25468
  "canvas_read_board",
24549
25469
  {
24550
25470
  title: "Canvas: ler board",
24551
- description: "L\xEA um board: n\xF3s (id, tipo, nome, campos principais), liga\xE7\xF5es e v\xEDnculo com o IA Lab, sem m\xEDdia. Obrigat\xF3rio antes de editar (vale para a sess\xE3o). node_ids devolve o data completo desses n\xF3s.",
25471
+ description: "L\xEA um board: n\xF3s (id, tipo, nome, campos principais), liga\xE7\xF5es e v\xEDnculo com o IA Lab, sem m\xEDdia. Obrigat\xF3rio antes de editar (vale para a sess\xE3o). node_ids devolve o data desses n\xF3s, com cada corte marcado (path=\u2026); o valor inteiro (ex.: data.sequence da Montagem) sai no canvas_read_node.",
24552
25472
  inputSchema: {
24553
25473
  board_id: boardId2,
24554
- node_ids: external_exports.array(nodeIdArg).max(20).optional().describe("N\xF3s para ver o data inteiro (sem blobs).")
25474
+ node_ids: external_exports.array(nodeIdArg).max(20).optional().describe("N\xF3s para ver o data (sem blobs, cortes marcados).")
24555
25475
  },
24556
25476
  annotations: { readOnlyHint: true, openWorldHint: false }
24557
25477
  },
@@ -24566,6 +25486,61 @@ Aviso: ${changesSince(theirs, doc)}.`;
24566
25486
  return parts.join("\n");
24567
25487
  })
24568
25488
  );
25489
+ server.registerTool(
25490
+ "canvas_read_node",
25491
+ {
25492
+ title: "Canvas: ler n\xF3 inteiro",
25493
+ description: 'Devolve o data de UM n\xF3 sem corte nenhum, em JSON compacto, para conferir e fazer diff. Na Montagem, sem path, vem a timeline do editor: data.timeline, ou data.sequence (legado) quando o n\xF3 ainda n\xE3o tem timeline, e o cabe\xE7alho diz qual veio. path escolhe um peda\xE7o ("items" da M\xEDdia, "timeline.meta"); "data" traz o data todo. Diz o tamanho total e o sha256; acima de max_chars vem em partes expl\xEDcitas (offset). N\xE3o substitui o canvas_read_board, que continua obrigat\xF3rio antes de editar. ' + MONTAGE_NOTE,
25494
+ inputSchema: {
25495
+ board_id: boardId2,
25496
+ node_id: nodeIdArg,
25497
+ path: external_exports.string().trim().max(200).optional().describe('Caminho dentro do data, com pontos (ex.: "timeline.meta", "items.0"). "data" = o data todo.'),
25498
+ offset: external_exports.number().int().min(0).optional().describe("In\xEDcio da parte, em caracteres (padr\xE3o 0)."),
25499
+ max_chars: external_exports.number().int().min(1e3).max(6e4).optional().describe("Tamanho da parte (padr\xE3o 40000).")
25500
+ },
25501
+ annotations: { readOnlyHint: true, openWorldHint: false }
25502
+ },
25503
+ async ({ board_id, node_id, path, offset, max_chars }) => run(async () => {
25504
+ const snap = await api.snapshot(board_id);
25505
+ const node = snap.doc.nodes[node_id];
25506
+ if (!node) throw new CanvasToolError(`N\xF3 ${node_id} n\xE3o existe no board. Releia com canvas_read_board.`);
25507
+ let value = node.data;
25508
+ let segments = dataSegments(path);
25509
+ let which = "";
25510
+ if (!path?.trim() && nodeKind(node) === "montage") {
25511
+ if (node.data.timeline !== void 0) {
25512
+ segments = ["timeline"];
25513
+ which = " (a timeline do editor, formato v3)";
25514
+ } else if (node.data.sequence !== void 0) {
25515
+ segments = ["sequence"];
25516
+ which = " (legado: este n\xF3 ainda n\xE3o tem data.timeline)";
25517
+ } else which = " (sem timeline nem sequence: o data todo)";
25518
+ } else if (segments[0] === "sequence" && nodeKind(node) === "montage" && node.data.timeline !== void 0) {
25519
+ which = " (LEGADO congelado: o editor l\xEA data.timeline)";
25520
+ }
25521
+ for (const [i, seg] of segments.entries()) {
25522
+ const here = value;
25523
+ value = Array.isArray(here) ? here[Number(seg)] : here && typeof here === "object" ? here[seg] : void 0;
25524
+ if (value === void 0) {
25525
+ const at = segments.slice(0, i).join(".");
25526
+ const keys = Array.isArray(here) ? `\xEDndices 0 a ${here.length - 1}` : here && typeof here === "object" ? Object.keys(here).join(", ") : "\u2014";
25527
+ throw new CanvasToolError(`"${seg}" n\xE3o existe em data${at ? `.${at}` : ""}. Existe: ${keys || "\u2014"}.`);
25528
+ }
25529
+ }
25530
+ const json2 = JSON.stringify(value);
25531
+ const total = json2.length;
25532
+ const from = Math.min(offset ?? 0, total);
25533
+ const size = max_chars ?? 4e4;
25534
+ const to = Math.min(from + size, total);
25535
+ const hash = createHash("sha256").update(json2).digest("hex").slice(0, 12);
25536
+ const where = `data${segments.length ? `.${segments.join(".")}` : ""}`;
25537
+ const head = `${node.id} \xB7 ${nodeKind(node) ?? node.type} \xB7 "${oneLine(nodeName(node), 60)}" \xB7 board seq ${snap.seq} \xB7 ${where}${which}: ${total} caracteres (JSON compacto) \xB7 sha256 ${hash}`;
25538
+ const part = from === 0 && to === total ? "Inteiro, abaixo." : `Parte: caracteres ${from} a ${to} de ${total}. ${to < total ? `Falta o resto: chame de novo com offset=${to}.` : "Esta \xE9 a \xFAltima parte."}`;
25539
+ return `${head}
25540
+ ${part}
25541
+ ${json2.slice(from, to)}`;
25542
+ })
25543
+ );
24569
25544
  server.registerTool(
24570
25545
  "canvas_create_board",
24571
25546
  {
@@ -24620,7 +25595,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24620
25595
  "canvas_add_node",
24621
25596
  {
24622
25597
  title: "Canvas: adicionar n\xF3",
24623
- description: `Adiciona um n\xF3 (n\xE3o executa). kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board. inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo.`,
25598
+ description: `Adiciona um n\xF3 (n\xE3o executa). ${READ}kind: ${kindList()}. data completa o padr\xE3o do tipo; label d\xE1 o nome. Sem position, nasce ao lado do n\xF3 ligado ou \xE0 direita do board. inputs/outputs j\xE1 ligam o n\xF3 no mesmo passo. ` + MONTAGE_NOTE,
24624
25599
  inputSchema: {
24625
25600
  board_id: boardId2,
24626
25601
  kind: external_exports.string().min(1).max(40),
@@ -24668,7 +25643,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24668
25643
  "canvas_update_node",
24669
25644
  {
24670
25645
  title: "Canvas: editar n\xF3",
24671
- description: "Muda campos do data de um n\xF3, chave a chave (null apaga a chave), sem executar. label renomeia. N\xE3o troca o tipo. Leia o n\xF3 com node_ids antes para n\xE3o sobrescrever o que outra pessoa escreveu.",
25646
+ description: `Muda campos do data de um n\xF3, chave a chave (null apaga a chave), sem executar. ${READ}label renomeia. N\xE3o troca o tipo. Cada chave \xE9 gravada inteira: leia antes com canvas_read_node e mande o valor completo j\xE1 revisado, para n\xE3o apagar o que outra pessoa escreveu. Para mudar partes de uma estrutura grande (clipes da timeline), use canvas_patch_node, por caminho. ` + MONTAGE_NOTE,
24672
25647
  inputSchema: {
24673
25648
  board_id: boardId2,
24674
25649
  node_id: nodeIdArg,
@@ -24683,6 +25658,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24683
25658
  const node = needNode(doc, args.node_id);
24684
25659
  const ops = [];
24685
25660
  const patch = parseData(args.data);
25661
+ for (const key of Object.keys(patch)) legacySequenceGuard(node, key);
24686
25662
  if (args.label) patch.label = args.label;
24687
25663
  for (const [k, v] of Object.entries(patch)) {
24688
25664
  const path = `data.${k}`;
@@ -24701,11 +25677,102 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24701
25677
  })
24702
25678
  )
24703
25679
  );
25680
+ server.registerTool(
25681
+ "canvas_patch_node",
25682
+ {
25683
+ title: "Canvas: gravar por caminho",
25684
+ description: `Grava v\xE1rios caminhos dentro do data de um n\xF3, sem executar: {path, value} grava, {path, unset: true} apaga. ${READ}O caminho atravessa objetos (o n\xEDvel que falta \xE9 criado) e n\xE3o entra em lista: para mudar um item de lista, grave a lista inteira. Quebra sozinho em envelopes de at\xE9 64 KB, em ordem, e devolve o resultado de cada um; entre envelopes n\xE3o h\xE1 atomicidade (o que entrou fica). Serve para mexer em partes de uma estrutura grande, como clipes da timeline da Montagem, sem reenviar tudo. Leia antes com canvas_read_node. ` + MONTAGE_NOTE,
25685
+ inputSchema: {
25686
+ board_id: boardId2,
25687
+ node_id: nodeIdArg,
25688
+ sets: external_exports.array(
25689
+ external_exports.object({
25690
+ path: external_exports.string().trim().min(1).max(500).describe('Caminho dentro do data (ex.: "timeline.meta.fps"); aceita o prefixo "data.".'),
25691
+ value: external_exports.unknown().optional().describe("Valor JSON a gravar (null grava null)."),
25692
+ unset: external_exports.literal(true).optional().describe("true apaga a chave.")
25693
+ })
25694
+ ).min(1).max(5e3)
25695
+ },
25696
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false }
25697
+ },
25698
+ async (args) => run(
25699
+ () => edit(
25700
+ args.board_id,
25701
+ async (doc) => {
25702
+ const node = needNode(doc, args.node_id);
25703
+ const work = structuredClone(node.data);
25704
+ const ops = [];
25705
+ let same = 0;
25706
+ let absent = 0;
25707
+ for (const [i, item] of args.sets.entries()) {
25708
+ const at = `sets[${i}] (${item.path})`;
25709
+ const segs = dataSegments(item.path);
25710
+ if (!segs.length) throw new CanvasToolError(`${at}: informe um caminho dentro do data, n\xE3o o data inteiro.`);
25711
+ if (segs[0] === KIND_FIELD) throw new CanvasToolError(`${at}: data.kind n\xE3o muda (apague o n\xF3 e crie outro do tipo certo).`);
25712
+ legacySequenceGuard(node, segs[0]);
25713
+ const path = `data.${segs.join(".")}`;
25714
+ const badPath = checkNodePath(path);
25715
+ if (badPath) throw new CanvasToolError(`${at}: ${badPath}.`);
25716
+ const unset = item.unset === true;
25717
+ const hasValue = item.value !== void 0;
25718
+ if (unset === hasValue) throw new CanvasToolError(`${at}: mande value OU unset: true.`);
25719
+ if (hasValue && !isJson(item.value)) throw new CanvasToolError(`${at}: value n\xE3o \xE9 JSON v\xE1lido.`);
25720
+ let cur = work;
25721
+ for (const [j, seg] of segs.slice(0, -1).entries()) {
25722
+ const next = Object.hasOwn(cur, seg) ? cur[seg] : void 0;
25723
+ const isObject2 = !!next && typeof next === "object" && !Array.isArray(next);
25724
+ if (isObject2) {
25725
+ cur = next;
25726
+ continue;
25727
+ }
25728
+ if (unset) {
25729
+ cur = null;
25730
+ break;
25731
+ }
25732
+ if (next === void 0) {
25733
+ const created = {};
25734
+ cur[seg] = created;
25735
+ cur = created;
25736
+ continue;
25737
+ }
25738
+ throw new CanvasToolError(
25739
+ `${at}: data.${segs.slice(0, j + 1).join(".")} \xE9 ${Array.isArray(next) ? "uma lista" : "um valor simples"}, e o caminho n\xE3o entra nele. Grave o n\xEDvel de cima inteiro.`
25740
+ );
25741
+ }
25742
+ const leaf = segs[segs.length - 1];
25743
+ if (unset) {
25744
+ if (!cur || !Object.hasOwn(cur, leaf)) {
25745
+ absent++;
25746
+ continue;
25747
+ }
25748
+ delete cur[leaf];
25749
+ ops.push({ type: "node.set", nodeId: node.id, path, value: unsetValue() });
25750
+ continue;
25751
+ }
25752
+ const value = item.value;
25753
+ if (cur && Object.hasOwn(cur, leaf) && JSON.stringify(cur[leaf]) === JSON.stringify(value)) {
25754
+ same++;
25755
+ continue;
25756
+ }
25757
+ if (cur) cur[leaf] = value;
25758
+ ops.push({ type: "node.set", nodeId: node.id, path, value: setValue(value) });
25759
+ }
25760
+ const skipped = [same ? `${same} igual(is) ao que j\xE1 estava` : "", absent ? `${absent} unset de caminho que n\xE3o existe` : ""].filter(Boolean).join(", ");
25761
+ return {
25762
+ ops,
25763
+ targets: [node.id],
25764
+ done: `N\xF3 "${oneLine(nodeName(node), 40)}" (${node.id}): ${ops.length} caminho(s) gravado(s)` + (skipped ? ` (ignorados: ${skipped})` : "")
25765
+ };
25766
+ },
25767
+ { split: true }
25768
+ )
25769
+ )
25770
+ );
24704
25771
  server.registerTool(
24705
25772
  "canvas_connect",
24706
25773
  {
24707
25774
  title: "Canvas: ligar portas",
24708
- description: "Liga a sa\xEDda de um n\xF3 \xE0 entrada de outro (ids e portas de canvas_read_board). Liga\xE7\xE3o repetida \xE9 ignorada.",
25775
+ description: `Liga a sa\xEDda de um n\xF3 \xE0 entrada de outro (ids e portas de canvas_read_board). ${READ}Liga\xE7\xE3o repetida \xE9 ignorada.`,
24709
25776
  inputSchema: {
24710
25777
  board_id: boardId2,
24711
25778
  source: nodeIdArg,
@@ -24732,7 +25799,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24732
25799
  "canvas_delete",
24733
25800
  {
24734
25801
  title: "Canvas: apagar n\xF3s/liga\xE7\xF5es",
24735
- description: "Apaga n\xF3s (com as liga\xE7\xF5es e varia\xE7\xF5es deles) e/ou liga\xE7\xF5es, num passo s\xF3. Irrevers\xEDvel pelo MCP: confirme com o usu\xE1rio antes. N\xE3o apaga o board.",
25802
+ description: `Apaga n\xF3s (com as liga\xE7\xF5es e varia\xE7\xF5es deles) e/ou liga\xE7\xF5es, num passo s\xF3. Irrevers\xEDvel pelo MCP: confirme com o usu\xE1rio antes. ${READ}N\xE3o apaga o board.`,
24736
25803
  inputSchema: {
24737
25804
  board_id: boardId2,
24738
25805
  node_ids: external_exports.array(nodeIdArg).max(200).optional(),
@@ -24777,7 +25844,7 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24777
25844
  "canvas_rename_board",
24778
25845
  {
24779
25846
  title: "Canvas: renomear board",
24780
- description: "Troca o t\xEDtulo do board (board.set). Precisa de papel de editor ou dono.",
25847
+ description: `Troca o t\xEDtulo do board (board.set). ${READ}Precisa de papel de editor ou dono.`,
24781
25848
  inputSchema: { board_id: boardId2, title: external_exports.string().trim().min(1).max(200) },
24782
25849
  annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false }
24783
25850
  },
@@ -24836,13 +25903,14 @@ N\xF3s: ${Object.entries(ids).map(([k, v]) => `${k}=${v}`).join(" \xB7 ")}` : ""
24836
25903
  })
24837
25904
  );
24838
25905
  registerCanvasCommentTools(server, api, run);
25906
+ registerCanvasMediaTools(server, { api, cfg, run, edit, seen, placeFor });
24839
25907
  }
24840
25908
 
24841
25909
  // src/version.ts
24842
25910
  import { createRequire } from "module";
24843
25911
  var require2 = createRequire(import.meta.url);
24844
25912
  function readVersion() {
24845
- if ("0.27.0") return "0.27.0";
25913
+ if ("0.28.0") return "0.28.0";
24846
25914
  try {
24847
25915
  const pkg = require2("../package.json");
24848
25916
  return pkg.version ?? "0.0.0-unknown";
@@ -24899,8 +25967,8 @@ function assertSupportedNode() {
24899
25967
 
24900
25968
  // src/doctor.ts
24901
25969
  import { readFileSync } from "fs";
24902
- import { homedir as homedir3 } from "os";
24903
- import { join } from "path";
25970
+ import { homedir as homedir4 } from "os";
25971
+ import { join as join2 } from "path";
24904
25972
  var LABEL = { ok: "[ok] ", aviso: "[aviso]", erro: "[erro] " };
24905
25973
  var Report = class {
24906
25974
  failed = false;
@@ -24920,27 +25988,27 @@ function maskToken(token) {
24920
25988
  return `${token.slice(0, 4)}...${token.slice(-4)}`;
24921
25989
  }
24922
25990
  function configCandidates() {
24923
- const home = homedir3();
25991
+ const home = homedir4();
24924
25992
  const cwd = process.cwd();
24925
25993
  const list = [
24926
- { path: join(home, ".claude.json"), client: "Claude Code (global)" },
24927
- { path: join(cwd, ".mcp.json"), client: "Claude Code (projeto)" },
24928
- { path: join(home, ".cursor", "mcp.json"), client: "Cursor (global)" },
24929
- { path: join(cwd, ".cursor", "mcp.json"), client: "Cursor (projeto)" }
25994
+ { path: join2(home, ".claude.json"), client: "Claude Code (global)" },
25995
+ { path: join2(cwd, ".mcp.json"), client: "Claude Code (projeto)" },
25996
+ { path: join2(home, ".cursor", "mcp.json"), client: "Cursor (global)" },
25997
+ { path: join2(cwd, ".cursor", "mcp.json"), client: "Cursor (projeto)" }
24930
25998
  ];
24931
25999
  if (process.platform === "darwin") {
24932
26000
  list.push({
24933
- path: join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
26001
+ path: join2(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
24934
26002
  client: "Claude Desktop"
24935
26003
  });
24936
26004
  } else if (process.platform === "win32") {
24937
26005
  const appData = process.env.APPDATA;
24938
26006
  if (appData) {
24939
- list.push({ path: join(appData, "Claude", "claude_desktop_config.json"), client: "Claude Desktop" });
26007
+ list.push({ path: join2(appData, "Claude", "claude_desktop_config.json"), client: "Claude Desktop" });
24940
26008
  }
24941
26009
  } else {
24942
26010
  list.push({
24943
- path: join(home, ".config", "Claude", "claude_desktop_config.json"),
26011
+ path: join2(home, ".config", "Claude", "claude_desktop_config.json"),
24944
26012
  client: "Claude Desktop"
24945
26013
  });
24946
26014
  }
@@ -25058,216 +26126,6 @@ async function runDoctor() {
25058
26126
  return code;
25059
26127
  }
25060
26128
 
25061
- // src/oauth.ts
25062
- import crypto from "crypto";
25063
- import { createServer } from "http";
25064
- import { spawn } from "child_process";
25065
-
25066
- // src/credentials.ts
25067
- import { chmod, mkdir, readFile as readFile2, writeFile, unlink } from "fs/promises";
25068
- import { homedir as homedir4 } from "os";
25069
- import { dirname, join as join2 } from "path";
25070
- function credentialsPath() {
25071
- const base = process.env.XDG_CONFIG_HOME?.trim() || join2(homedir4(), ".config");
25072
- return join2(base, "beplus-mcp", "credentials.json");
25073
- }
25074
- async function readCredentials() {
25075
- try {
25076
- const raw = await readFile2(credentialsPath(), "utf8");
25077
- const parsed = JSON.parse(raw);
25078
- if (!parsed.accessToken || !parsed.apiUrl) return null;
25079
- return parsed;
25080
- } catch {
25081
- return null;
25082
- }
25083
- }
25084
- async function writeCredentials(creds) {
25085
- const path = credentialsPath();
25086
- await mkdir(dirname(path), { recursive: true, mode: 448 });
25087
- await writeFile(path, `${JSON.stringify(creds, null, 2)}
25088
- `, { mode: 384 });
25089
- await chmod(path, 384);
25090
- return path;
25091
- }
25092
- async function clearCredentials() {
25093
- try {
25094
- await unlink(credentialsPath());
25095
- return true;
25096
- } catch {
25097
- return false;
25098
- }
25099
- }
25100
- var RENEW_MARGIN_MS = 6e4;
25101
- function isExpired(creds) {
25102
- return typeof creds.expiresAt === "number" && creds.expiresAt - RENEW_MARGIN_MS <= Date.now();
25103
- }
25104
-
25105
- // src/oauth.ts
25106
- var CALLBACK_TIMEOUT_MS = 5 * 6e4;
25107
- async function json(url, init) {
25108
- let res;
25109
- try {
25110
- res = await fetch(url, init);
25111
- } catch {
25112
- throw new Error(`Nao consegui falar com ${new URL(url).origin}. Confira a rede e o BEPLUS_API_URL.`);
25113
- }
25114
- const text = await res.text();
25115
- let body2;
25116
- try {
25117
- body2 = text ? JSON.parse(text) : void 0;
25118
- } catch {
25119
- }
25120
- if (!res.ok) {
25121
- const msg = body2?.message ?? body2?.error_description ?? body2?.error ?? `HTTP ${res.status}`;
25122
- throw new Error(`${msg} (${url})`);
25123
- }
25124
- return body2;
25125
- }
25126
- async function discover(apiUrl2) {
25127
- const meta = await json(`${apiUrl2}/.well-known/oauth-authorization-server`);
25128
- if (!meta.authorization_endpoint || !meta.token_endpoint || !meta.registration_endpoint) {
25129
- throw new Error("O servidor respondeu a descoberta sem os endpoints obrigatorios.");
25130
- }
25131
- return meta;
25132
- }
25133
- function pkce() {
25134
- const verifier = crypto.randomBytes(32).toString("base64url");
25135
- return { verifier, challenge: crypto.createHash("sha256").update(verifier).digest("base64url") };
25136
- }
25137
- function openBrowser(url) {
25138
- try {
25139
- if (process.platform === "win32") {
25140
- spawn("cmd.exe", ["/c", "start", '""', "/b", url.replace(/&/g, "^&")], {
25141
- stdio: "ignore",
25142
- detached: true,
25143
- windowsVerbatimArguments: true
25144
- }).unref();
25145
- return;
25146
- }
25147
- const cmd = process.platform === "darwin" ? "open" : "xdg-open";
25148
- spawn(cmd, [url], { stdio: "ignore", detached: true }).unref();
25149
- } catch {
25150
- }
25151
- }
25152
- var PAGINA_OK = `<!doctype html><meta charset="utf-8"><title>Pronto</title>
25153
- <body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
25154
- <div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Tudo certo</h1>
25155
- <p style="margin:0;opacity:.7">Pode fechar esta aba e voltar para o seu agente.</p></div>`;
25156
- var PAGINA_ERRO = `<!doctype html><meta charset="utf-8"><title>Nao deu</title>
25157
- <body style="margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:#0e1433;color:#f7f6f2">
25158
- <div style="text-align:center;padding:24px"><h1 style="font-size:22px;margin:0 0 8px">Nao foi dessa vez</h1>
25159
- <p style="margin:0;opacity:.7">Volte ao terminal para ver o motivo.</p></div>`;
25160
- function listenForCallback(expectedState) {
25161
- return new Promise((resolvePort, rejectPort) => {
25162
- let settle;
25163
- let fail;
25164
- const code = new Promise((res, rej) => {
25165
- settle = res;
25166
- fail = rej;
25167
- });
25168
- const server = createServer((req, res) => {
25169
- const url = new URL(req.url ?? "/", "http://127.0.0.1");
25170
- if (url.pathname !== "/callback") {
25171
- res.writeHead(404).end();
25172
- return;
25173
- }
25174
- const erro = url.searchParams.get("error");
25175
- const recebido = url.searchParams.get("code");
25176
- const state = url.searchParams.get("state") ?? "";
25177
- const ok = !erro && recebido && state === expectedState;
25178
- res.writeHead(ok ? 200 : 400, { "content-type": "text/html; charset=utf-8" });
25179
- res.end(ok ? PAGINA_OK : PAGINA_ERRO);
25180
- server.close();
25181
- if (erro) return fail(new Error(url.searchParams.get("error_description") || erro));
25182
- if (!recebido || state !== expectedState) return fail(new Error("Resposta de autorizacao invalida."));
25183
- settle({ code: recebido, state });
25184
- });
25185
- server.on("error", rejectPort);
25186
- server.listen(0, "127.0.0.1", () => {
25187
- const addr = server.address();
25188
- if (!addr || typeof addr === "string") return rejectPort(new Error("Nao consegui abrir a porta local."));
25189
- const timer = setTimeout(() => {
25190
- server.close();
25191
- fail(new Error("Tempo esgotado esperando a autorizacao no navegador."));
25192
- }, CALLBACK_TIMEOUT_MS);
25193
- void code.finally(() => clearTimeout(timer));
25194
- resolvePort({ port: addr.port, code });
25195
- });
25196
- });
25197
- }
25198
- function toStored(t, apiUrl2, clientId) {
25199
- return {
25200
- accessToken: t.access_token,
25201
- refreshToken: t.refresh_token,
25202
- expiresAt: t.expires_in ? Date.now() + t.expires_in * 1e3 : void 0,
25203
- apiUrl: apiUrl2,
25204
- clientId
25205
- };
25206
- }
25207
- async function login(apiUrl2, onUrl) {
25208
- const meta = await discover(apiUrl2);
25209
- const state = crypto.randomBytes(24).toString("base64url");
25210
- const { verifier, challenge } = pkce();
25211
- const { port, code } = await listenForCallback(state);
25212
- const redirectUri = `http://127.0.0.1:${port}/callback`;
25213
- const client = await json(meta.registration_endpoint, {
25214
- method: "POST",
25215
- headers: { "content-type": "application/json" },
25216
- body: JSON.stringify({
25217
- client_name: "beplus-mcp (CLI)",
25218
- redirect_uris: [redirectUri],
25219
- token_endpoint_auth_method: "none",
25220
- grant_types: ["authorization_code", "refresh_token"]
25221
- })
25222
- });
25223
- const authorizeUrl = new URL(meta.authorization_endpoint);
25224
- authorizeUrl.searchParams.set("response_type", "code");
25225
- authorizeUrl.searchParams.set("client_id", client.client_id);
25226
- authorizeUrl.searchParams.set("redirect_uri", redirectUri);
25227
- authorizeUrl.searchParams.set("code_challenge", challenge);
25228
- authorizeUrl.searchParams.set("code_challenge_method", "S256");
25229
- authorizeUrl.searchParams.set("state", state);
25230
- onUrl(authorizeUrl.toString());
25231
- openBrowser(authorizeUrl.toString());
25232
- const { code: authCode } = await code;
25233
- const token = await json(meta.token_endpoint, {
25234
- method: "POST",
25235
- headers: { "content-type": "application/json" },
25236
- body: JSON.stringify({
25237
- grant_type: "authorization_code",
25238
- code: authCode,
25239
- code_verifier: verifier,
25240
- client_id: client.client_id,
25241
- redirect_uri: redirectUri
25242
- })
25243
- });
25244
- const path = await writeCredentials(toStored(token, apiUrl2, client.client_id));
25245
- return { path, authorizeUrl: authorizeUrl.toString() };
25246
- }
25247
- async function tokenFromDisk(apiUrl2) {
25248
- const creds = await readCredentials();
25249
- if (!creds) return null;
25250
- if (creds.apiUrl.replace(/\/$/, "") !== apiUrl2.replace(/\/$/, "")) return null;
25251
- if (!isExpired(creds)) return creds.accessToken;
25252
- if (!creds.refreshToken) return null;
25253
- try {
25254
- const meta = await discover(apiUrl2);
25255
- const token = await json(meta.token_endpoint, {
25256
- method: "POST",
25257
- headers: { "content-type": "application/json" },
25258
- body: JSON.stringify({
25259
- grant_type: "refresh_token",
25260
- refresh_token: creds.refreshToken,
25261
- client_id: creds.clientId
25262
- })
25263
- });
25264
- await writeCredentials(toStored(token, apiUrl2, creds.clientId));
25265
- return token.access_token;
25266
- } catch {
25267
- return null;
25268
- }
25269
- }
25270
-
25271
26129
  // src/index.ts
25272
26130
  if (process.argv.length <= 2) assertSupportedNode();
25273
26131
  var HELP = `beplus-mcp ${VERSION}
@@ -25332,7 +26190,7 @@ Se ele nao abrir, acesse:
25332
26190
  });
25333
26191
  process.stdout.write(`Pronto. Credencial guardada em ${path}
25334
26192
  `);
25335
- process.stdout.write("Reinicie o seu agente para as ferramentas aparecerem.\n");
26193
+ process.stdout.write("Se as ferramentas beplus ainda nao aparecem no agente, reinicie o agente.\n");
25336
26194
  return 0;
25337
26195
  } catch (e) {
25338
26196
  logError(e.message);
@@ -25344,9 +26202,13 @@ async function main() {
25344
26202
  if (handled !== null) {
25345
26203
  process.exit(handled);
25346
26204
  }
26205
+ let doLogin = false;
25347
26206
  if (!process.env.BEPLUS_API_TOKEN?.trim()) {
25348
26207
  const doDisco = await tokenFromDisk(apiUrl());
25349
- if (doDisco) process.env.BEPLUS_API_TOKEN = doDisco;
26208
+ if (doDisco) {
26209
+ process.env.BEPLUS_API_TOKEN = doDisco;
26210
+ doLogin = true;
26211
+ }
25350
26212
  }
25351
26213
  let cfg;
25352
26214
  try {
@@ -25355,6 +26217,7 @@ async function main() {
25355
26217
  logError(e.message);
25356
26218
  process.exit(1);
25357
26219
  }
26220
+ if (doLogin) cfg.auth = new LoginToken(cfg.baseUrl, cfg.token);
25358
26221
  const { server, client } = buildServer(cfg);
25359
26222
  if (cfg.verifyOnStart) {
25360
26223
  try {
@@ -25363,7 +26226,7 @@ async function main() {
25363
26226
  } catch (e) {
25364
26227
  if (e instanceof ApiError && e.httpStatus === 401) {
25365
26228
  logError(
25366
- 'Token invalido ou revogado. Gere um novo Personal Access Token no painel BePlus e atualize BEPLUS_API_TOKEN no config do MCP. Rode "beplus-mcp doctor" para conferir.'
26229
+ doLogin ? 'O login pelo navegador expirou e nao deu para renovar. Rode "beplus-mcp login" de novo.' : 'Token invalido ou revogado. Gere um novo Personal Access Token no painel BePlus e atualize BEPLUS_API_TOKEN no config do MCP. Rode "beplus-mcp doctor" para conferir.'
25367
26230
  );
25368
26231
  process.exit(1);
25369
26232
  }