@doist/automations-cli 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import { fileURLToPath } from "node:url";
15
15
  // package.json
16
16
  var package_default = {
17
17
  name: "@doist/automations-cli",
18
- version: "1.8.0",
18
+ version: "1.8.1",
19
19
  description: "Command-line client for Todoist Automations",
20
20
  type: "module",
21
21
  bin: {
@@ -64,8 +64,7 @@ var package_default = {
64
64
  ai: "7.0.77",
65
65
  commander: "15.0.0",
66
66
  oauth4webapi: "3.8.8",
67
- open: "11.0.2",
68
- "p-limit": "3.1.0"
67
+ open: "11.0.3"
69
68
  },
70
69
  devDependencies: {
71
70
  "@doist/automations-core": "*",
@@ -1829,10 +1828,10 @@ function node(obj, key, make) {
1829
1828
  }
1830
1829
  return obj[key];
1831
1830
  }
1832
- function flattenError(error61, mapper = (issue2) => issue2.message) {
1831
+ function flattenError(error62, mapper = (issue2) => issue2.message) {
1833
1832
  const fieldErrors = {};
1834
1833
  const formErrors = [];
1835
- for (const sub of error61.issues) {
1834
+ for (const sub of error62.issues) {
1836
1835
  if (sub.path.length > 0) {
1837
1836
  node(fieldErrors, sub.path[0], () => []).push(mapper(sub));
1838
1837
  } else {
@@ -1841,10 +1840,10 @@ function flattenError(error61, mapper = (issue2) => issue2.message) {
1841
1840
  }
1842
1841
  return { formErrors, fieldErrors };
1843
1842
  }
1844
- function formatError(error61, mapper = (issue2) => issue2.message) {
1843
+ function formatError(error62, mapper = (issue2) => issue2.message) {
1845
1844
  const fieldErrors = { _errors: [] };
1846
- const processError = (error62, path = []) => {
1847
- for (const issue2 of error62.issues) {
1845
+ const processError = (error63, path = []) => {
1846
+ for (const issue2 of error63.issues) {
1848
1847
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1849
1848
  issue2.errors.map((issues) => processError({ issues }, [...path, ...issue2.path]));
1850
1849
  } else if (issue2.code === "invalid_key") {
@@ -1886,14 +1885,14 @@ function formatError(error61, mapper = (issue2) => issue2.message) {
1886
1885
  }
1887
1886
  }
1888
1887
  };
1889
- processError(error61);
1888
+ processError(error62);
1890
1889
  return fieldErrors;
1891
1890
  }
1892
- function treeifyError(error61, mapper = (issue2) => issue2.message) {
1891
+ function treeifyError(error62, mapper = (issue2) => issue2.message) {
1893
1892
  const result = { errors: [] };
1894
- const processError = (error62, path = []) => {
1893
+ const processError = (error63, path = []) => {
1895
1894
  var _a3;
1896
- for (const issue2 of error62.issues) {
1895
+ for (const issue2 of error63.issues) {
1897
1896
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1898
1897
  issue2.errors.map((issues) => processError({ issues }, [...path, ...issue2.path]));
1899
1898
  } else if (issue2.code === "invalid_key") {
@@ -1935,7 +1934,7 @@ function treeifyError(error61, mapper = (issue2) => issue2.message) {
1935
1934
  }
1936
1935
  }
1937
1936
  };
1938
- processError(error61);
1937
+ processError(error62);
1939
1938
  return result;
1940
1939
  }
1941
1940
  function toDotPath(_path) {
@@ -1956,9 +1955,9 @@ function toDotPath(_path) {
1956
1955
  }
1957
1956
  return segs.join("");
1958
1957
  }
1959
- function prettifyError(error61) {
1958
+ function prettifyError(error62) {
1960
1959
  const lines = [];
1961
- const issues = [...error61.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);
1960
+ const issues = [...error62.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);
1962
1961
  for (const issue2 of issues) {
1963
1962
  lines.push(`\u2716 ${issue2.message}`);
1964
1963
  if (issue2.path?.length)
@@ -2014,19 +2013,19 @@ var _safeParse = (_Err) => (schema, value, _ctx) => {
2014
2013
  };
2015
2014
  var safeParse = /* @__PURE__ */ _safeParse($ZodRealError);
2016
2015
  function failure(Err, issues, ctx) {
2017
- let error61;
2016
+ let error62;
2018
2017
  return {
2019
2018
  success: false,
2020
2019
  get error() {
2021
- if (!error61) {
2022
- error61 = new Err(issues.map((iss) => finalizeIssue(iss, ctx, config())));
2020
+ if (!error62) {
2021
+ error62 = new Err(issues.map((iss) => finalizeIssue(iss, ctx, config())));
2023
2022
  issues = void 0;
2024
2023
  ctx = void 0;
2025
2024
  }
2026
- return error61;
2025
+ return error62;
2027
2026
  },
2028
2027
  set error(e) {
2029
- error61 = e;
2028
+ error62 = e;
2030
2029
  issues = void 0;
2031
2030
  ctx = void 0;
2032
2031
  }
@@ -2790,7 +2789,7 @@ ${content.join("\n")}
2790
2789
  var version = {
2791
2790
  major: 4,
2792
2791
  minor: 6,
2793
- patch: 0
2792
+ patch: 2
2794
2793
  };
2795
2794
 
2796
2795
  // ../../node_modules/zod/v4/core/schemas.js
@@ -3594,7 +3593,7 @@ function handlePropertyResult(result, final, key, input2, optin, optout) {
3594
3593
  return;
3595
3594
  }
3596
3595
  if (result.value === void 0) {
3597
- if (isPresent) {
3596
+ if (isPresent || optin === "defaulted" && !isOptionalOut) {
3598
3597
  final.value[key] = void 0;
3599
3598
  }
3600
3599
  } else {
@@ -3830,16 +3829,16 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
3830
3829
  doc.write(`
3831
3830
  if (${id}.issues.length) {${prefixStr(id, k)}
3832
3831
  }
3833
-
3834
- if (${id}.value === undefined) {
3835
- if (${isPresent}) {
3836
- newResult[${k}] = undefined;
3837
- }
3832
+ `);
3833
+ if (optin === "defaulted") {
3834
+ doc.write(`newResult[${k}] = ${id}.value;`);
3838
3835
  } else {
3836
+ doc.write(`
3837
+ if (${id}.value !== undefined || ${isPresent}) {
3839
3838
  newResult[${k}] = ${id}.value;
3840
3839
  }
3841
-
3842
3840
  `);
3841
+ }
3843
3842
  }
3844
3843
  }
3845
3844
  doc.write(`payload.value = newResult;`);
@@ -4003,16 +4002,31 @@ function getDiscriminatedOption(union2, value) {
4003
4002
  const internals = union2._zod;
4004
4003
  let map2 = internals.bag.optionsMap;
4005
4004
  if (!map2) {
4006
- map2 = /* @__PURE__ */ new Map();
4007
- const { options, discriminator } = internals.def;
4008
- for (const option of options) {
4009
- for (const v of option._zod.propValues?.[discriminator] ?? [])
4010
- if (!map2.has(v))
4011
- map2.set(v, option);
4012
- }
4005
+ map2 = discriminatorMap(internals.def);
4013
4006
  internals.bag.optionsMap = map2;
4014
4007
  }
4015
- return map2.get(value);
4008
+ const option = map2.get(value);
4009
+ if (option === null)
4010
+ throw new Error(`Ambiguous discriminator value "${String(value)}"`);
4011
+ return option;
4012
+ }
4013
+ function discriminatorMap(def) {
4014
+ const map2 = /* @__PURE__ */ new Map();
4015
+ for (const option of def.options) {
4016
+ const values = option._zod.propValues?.[def.discriminator];
4017
+ if (!values || values.size === 0)
4018
+ throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
4019
+ for (const value of values) {
4020
+ if (map2.has(value)) {
4021
+ if (value !== void 0)
4022
+ throw new Error(`Duplicate discriminator value "${String(value)}"`);
4023
+ map2.set(value, null);
4024
+ } else {
4025
+ map2.set(value, option);
4026
+ }
4027
+ }
4028
+ }
4029
+ return map2;
4016
4030
  }
4017
4031
  var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnion", (inst, def) => {
4018
4032
  def.inclusive = false;
@@ -4020,10 +4034,13 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4020
4034
  const _super = inst._zod.parse;
4021
4035
  defineLazyInternal(inst, "propValues", (zod) => {
4022
4036
  const propValues = {};
4037
+ let undefinedCount = 0;
4023
4038
  for (const option of zod.def.options) {
4024
4039
  const pv = option._zod.propValues;
4025
4040
  if (!pv || Object.keys(pv).length === 0)
4026
4041
  throw new Error(`Invalid discriminated union option at index "${zod.def.options.indexOf(option)}"`);
4042
+ if (pv[zod.def.discriminator]?.has(void 0))
4043
+ undefinedCount++;
4027
4044
  for (const [k, v] of Object.entries(pv)) {
4028
4045
  if (!Object.prototype.hasOwnProperty.call(propValues, k)) {
4029
4046
  assignProp(propValues, k, /* @__PURE__ */ new Set());
@@ -4033,6 +4050,8 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4033
4050
  }
4034
4051
  }
4035
4052
  }
4053
+ if (!zod.def.unionFallback && undefinedCount > 1)
4054
+ propValues[zod.def.discriminator]?.delete(void 0);
4036
4055
  return propValues;
4037
4056
  });
4038
4057
  def.options.forEach((option, i) => {
@@ -4041,22 +4060,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4041
4060
  throw new Error(`Invalid discriminated union option at index "${i}"`);
4042
4061
  }
4043
4062
  });
4044
- const disc = cached(() => {
4045
- const opts = def.options;
4046
- const map2 = /* @__PURE__ */ new Map();
4047
- for (const o of opts) {
4048
- const values = o._zod.propValues?.[def.discriminator];
4049
- if (!values || values.size === 0)
4050
- throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
4051
- for (const v of values) {
4052
- if (map2.has(v)) {
4053
- throw new Error(`Duplicate discriminator value "${String(v)}"`);
4054
- }
4055
- map2.set(v, o);
4056
- }
4057
- }
4058
- return map2;
4059
- });
4063
+ const disc = cached(() => discriminatorMap(def));
4060
4064
  inst._zod.parse = (payload, ctx) => {
4061
4065
  const input2 = payload.value;
4062
4066
  if (!isObject(input2)) {
@@ -4068,8 +4072,9 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4068
4072
  });
4069
4073
  return payload;
4070
4074
  }
4071
- const opt = disc.value.get(input2?.[def.discriminator]);
4072
- if (opt) {
4075
+ const value = input2?.[def.discriminator];
4076
+ const opt = disc.value.get(value);
4077
+ if (opt && (value !== void 0 || ctx.direction !== "backward")) {
4073
4078
  return opt._zod.run(payload, ctx);
4074
4079
  }
4075
4080
  if (def.unionFallback || ctx.direction === "backward") {
@@ -4080,7 +4085,7 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4080
4085
  errors: [],
4081
4086
  note: "No matching discriminator",
4082
4087
  discriminator: def.discriminator,
4083
- options: Array.from(disc.value.keys()),
4088
+ options: Array.from(disc.value.keys()).filter((value2) => disc.value.get(value2) !== null),
4084
4089
  input: input2,
4085
4090
  path: [def.discriminator],
4086
4091
  inst
@@ -5568,6 +5573,7 @@ __export(locales_exports, {
5568
5573
  sl: () => sl_default,
5569
5574
  sv: () => sv_default,
5570
5575
  ta: () => ta_default,
5576
+ tg: () => tg_default,
5571
5577
  th: () => th_default,
5572
5578
  tk: () => tk_default,
5573
5579
  tr: () => tr_default,
@@ -11774,8 +11780,124 @@ function ta_default() {
11774
11780
  };
11775
11781
  }
11776
11782
 
11777
- // ../../node_modules/zod/v4/locales/th.js
11783
+ // ../../node_modules/zod/v4/locales/tg.js
11778
11784
  var error51 = () => {
11785
+ const Sizable = {
11786
+ string: { unit: "\u0430\u043B\u043E\u043C\u0430\u0442", verb: "\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434" },
11787
+ file: { unit: "\u0431\u0430\u0439\u0442", verb: "\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434" },
11788
+ array: { unit: "\u0443\u043D\u0441\u0443\u0440", verb: "\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434" },
11789
+ set: { unit: "\u0443\u043D\u0441\u0443\u0440", verb: "\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434" },
11790
+ map: { unit: "\u0441\u0430\u0431\u0442", verb: "\u0434\u043E\u0448\u0442\u0430 \u0431\u043E\u0448\u0430\u0434" }
11791
+ };
11792
+ function getSizing(origin) {
11793
+ return Sizable[origin] ?? null;
11794
+ }
11795
+ const FormatDictionary = {
11796
+ regex: "\u0432\u0443\u0440\u0443\u0434",
11797
+ email: "\u0441\u0443\u0440\u043E\u0493\u0430\u0438 email",
11798
+ url: "URL",
11799
+ emoji: "\u044D\u043C\u043E\u04B7\u0438",
11800
+ uuid: "UUID",
11801
+ uuidv4: "UUIDv4",
11802
+ uuidv6: "UUIDv6",
11803
+ nanoid: "nanoid",
11804
+ guid: "GUID",
11805
+ cuid: "cuid",
11806
+ cuid2: "cuid2",
11807
+ ulid: "ULID",
11808
+ xid: "XID",
11809
+ ksuid: "KSUID",
11810
+ datetime: "\u0441\u0430\u043D\u0430\u0432\u0443 \u0432\u0430\u049B\u0442\u0438 ISO",
11811
+ date: "\u0441\u0430\u043D\u0430\u0438 ISO",
11812
+ time: "\u0432\u0430\u049B\u0442\u0438 ISO",
11813
+ duration: "\u0434\u0430\u0432\u043E\u043C\u043D\u043E\u043A\u0438\u0438 ISO",
11814
+ ipv4: "\u0441\u0443\u0440\u043E\u0493\u0430\u0438 IPv4",
11815
+ ipv6: "\u0441\u0443\u0440\u043E\u0493\u0430\u0438 IPv6",
11816
+ mac: "\u0441\u0443\u0440\u043E\u0493\u0430\u0438 MAC",
11817
+ cidrv4: "\u043C\u0430\u04B3\u0434\u0443\u0434\u0430\u0438 IPv4",
11818
+ cidrv6: "\u043C\u0430\u04B3\u0434\u0443\u0434\u0430\u0438 IPv6",
11819
+ base64: "\u0441\u0430\u0442\u0440\u0438 \u0434\u0430\u0440 \u0444\u043E\u0440\u043C\u0430\u0442\u0438 base64",
11820
+ base64url: "\u0441\u0430\u0442\u0440\u0438 \u0434\u0430\u0440 \u0444\u043E\u0440\u043C\u0430\u0442\u0438 base64url",
11821
+ json_string: "\u0441\u0430\u0442\u0440\u0438 JSON",
11822
+ e164: "\u0440\u0430\u049B\u0430\u043C\u0438 E.164",
11823
+ credit_card: "\u0440\u0430\u049B\u0430\u043C\u0438 \u043A\u043E\u0440\u0442\u0438 \u043A\u0440\u0435\u0434\u0438\u0442\u04E3",
11824
+ iban: "IBAN",
11825
+ jwt: "JWT",
11826
+ template_literal: "\u0432\u0443\u0440\u0443\u0434"
11827
+ };
11828
+ const TypeDictionary = {
11829
+ nan: "NaN",
11830
+ number: "\u0440\u0430\u049B\u0430\u043C",
11831
+ string: "\u0441\u0430\u0442\u0440",
11832
+ array: "\u043C\u0430\u0441\u0441\u0438\u0432",
11833
+ object: "\u043E\u0431\u044A\u0435\u043A\u0442",
11834
+ date: "\u0441\u0430\u043D\u0430"
11835
+ };
11836
+ return (issue2) => {
11837
+ switch (issue2.code) {
11838
+ case "invalid_type": {
11839
+ const expected = TypeDictionary[issue2.expected] ?? issue2.expected;
11840
+ const receivedType = parsedType(issue2.input);
11841
+ const received = TypeDictionary[receivedType] ?? receivedType;
11842
+ return `\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: ${expected} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442, ${received} \u0433\u0438\u0440\u0438\u0444\u0442\u0430 \u0448\u0443\u0434`;
11843
+ }
11844
+ case "invalid_value":
11845
+ if (issue2.values.length === 1)
11846
+ return `\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: ${stringifyPrimitive(issue2.values[0])} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442`;
11847
+ return `\u0418\u043D\u0442\u0438\u0445\u043E\u0431\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u044F\u043A\u0435 \u0430\u0437 ${joinValues(issue2.values, "|")} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442`;
11848
+ case "too_big": {
11849
+ const adj = issue2.inclusive ? "<=" : "<";
11850
+ const sizing = getSizing(issue2.origin);
11851
+ if (sizing)
11852
+ return `\u0425\u0435\u043B\u0435 \u043A\u0430\u043B\u043E\u043D: ${issue2.origin ?? "\u049B\u0438\u043C\u0430\u0442"} \u0431\u043E\u044F\u0434 ${adj}${issue2.maximum.toString()} ${sizing.unit} ${sizing.verb}`;
11853
+ return `\u0425\u0435\u043B\u0435 \u043A\u0430\u043B\u043E\u043D: ${issue2.origin ?? "\u049B\u0438\u043C\u0430\u0442"} \u0431\u043E\u044F\u0434 ${adj}${issue2.maximum.toString()} \u0431\u043E\u0448\u0430\u0434`;
11854
+ }
11855
+ case "too_small": {
11856
+ const adj = issue2.inclusive ? ">=" : ">";
11857
+ const sizing = getSizing(issue2.origin);
11858
+ if (sizing)
11859
+ return `\u0425\u0435\u043B\u0435 \u0445\u0443\u0440\u0434: ${issue2.origin} \u0431\u043E\u044F\u0434 ${adj}${issue2.minimum.toString()} ${sizing.unit} ${sizing.verb}`;
11860
+ return `\u0425\u0435\u043B\u0435 \u0445\u0443\u0440\u0434: ${issue2.origin} \u0431\u043E\u044F\u0434 ${adj}${issue2.minimum.toString()} \u0431\u043E\u0448\u0430\u0434`;
11861
+ }
11862
+ case "invalid_format": {
11863
+ const _issue = issue2;
11864
+ if (_issue.format === "starts_with")
11865
+ return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u043E "${_issue.prefix}" \u043E\u0493\u043E\u0437 \u0448\u0430\u0432\u0430\u0434`;
11866
+ if (_issue.format === "ends_with")
11867
+ return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u043E "${_issue.suffix}" \u0430\u043D\u04B7\u043E\u043C \u0451\u0431\u0430\u0434`;
11868
+ if (_issue.format === "includes")
11869
+ return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 "${_issue.includes}"-\u0440\u043E \u0434\u0430\u0440 \u0431\u0430\u0440 \u0433\u0438\u0440\u0430\u0434`;
11870
+ if (_issue.format === "regex")
11871
+ return `\u0421\u0430\u0442\u0440\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u0430 \u043D\u0430\u043C\u0443\u043D\u0430\u0438 ${_issue.pattern} \u043C\u0443\u0432\u043E\u0444\u0438\u049B\u0430\u0442 \u043A\u0443\u043D\u0430\u0434`;
11872
+ return `${FormatDictionary[_issue.format] ?? issue2.format}-\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442`;
11873
+ }
11874
+ case "not_multiple_of":
11875
+ return `\u0420\u0430\u049B\u0430\u043C\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442: \u0431\u043E\u044F\u0434 \u0431\u0430 ${issue2.divisor} \u0431\u0435 \u0431\u0430\u049B\u0438\u044F \u0442\u0430\u049B\u0441\u0438\u043C \u0448\u0430\u0432\u0430\u0434`;
11876
+ case "unrecognized_keys":
11877
+ return `\u041A\u0430\u043B\u0438\u0434${issue2.keys.length > 1 ? "\u04B3\u043E\u0438" : "\u0438"} \u043D\u043E\u043C\u0430\u044A\u043B\u0443\u043C: ${joinValues(issue2.keys, ", ")}`;
11878
+ case "invalid_key":
11879
+ return `\u041A\u0430\u043B\u0438\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442 \u0434\u0430\u0440 ${issue2.origin}`;
11880
+ case "invalid_union":
11881
+ if (issue2.options && Array.isArray(issue2.options) && issue2.options.length > 0) {
11882
+ const opts = issue2.options.map((o) => `'${o}'`).join(" | ");
11883
+ return `\u049A\u0438\u043C\u0430\u0442\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442\u0438 \u0434\u0438\u0441\u043A\u0440\u0438\u043C\u0438\u043D\u0430\u0442\u043E\u0440: ${opts} \u0438\u043D\u0442\u0438\u0437\u043E\u0440 \u043C\u0435\u0440\u0430\u0444\u0442`;
11884
+ }
11885
+ return "\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442";
11886
+ case "invalid_element":
11887
+ return `\u049A\u0438\u043C\u0430\u0442\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442 \u0434\u0430\u0440 ${issue2.origin}`;
11888
+ default:
11889
+ return `\u0412\u0443\u0440\u0443\u0434\u0438 \u043D\u043E\u0434\u0443\u0440\u0443\u0441\u0442`;
11890
+ }
11891
+ };
11892
+ };
11893
+ function tg_default() {
11894
+ return {
11895
+ localeError: error51()
11896
+ };
11897
+ }
11898
+
11899
+ // ../../node_modules/zod/v4/locales/th.js
11900
+ var error52 = () => {
11779
11901
  const Sizable = {
11780
11902
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
11781
11903
  file: { unit: "\u0E44\u0E1A\u0E15\u0E4C", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -11885,12 +12007,12 @@ var error51 = () => {
11885
12007
  };
11886
12008
  function th_default() {
11887
12009
  return {
11888
- localeError: error51()
12010
+ localeError: error52()
11889
12011
  };
11890
12012
  }
11891
12013
 
11892
12014
  // ../../node_modules/zod/v4/locales/tk.js
11893
- var error52 = () => {
12015
+ var error53 = () => {
11894
12016
  const Sizable = {
11895
12017
  string: { unit: "simwol", verb: "bolmaly" },
11896
12018
  file: { unit: "ba\xFDt", verb: "bolmaly" },
@@ -11992,12 +12114,12 @@ var error52 = () => {
11992
12114
  };
11993
12115
  function tk_default() {
11994
12116
  return {
11995
- localeError: error52()
12117
+ localeError: error53()
11996
12118
  };
11997
12119
  }
11998
12120
 
11999
12121
  // ../../node_modules/zod/v4/locales/tr.js
12000
- var error53 = () => {
12122
+ var error54 = () => {
12001
12123
  const Sizable = {
12002
12124
  string: { unit: "karakter", verb: "olmal\u0131" },
12003
12125
  file: { unit: "bayt", verb: "olmal\u0131" },
@@ -12102,12 +12224,12 @@ var error53 = () => {
12102
12224
  };
12103
12225
  function tr_default() {
12104
12226
  return {
12105
- localeError: error53()
12227
+ localeError: error54()
12106
12228
  };
12107
12229
  }
12108
12230
 
12109
12231
  // ../../node_modules/zod/v4/locales/uk.js
12110
- var error54 = () => {
12232
+ var error55 = () => {
12111
12233
  const Sizable = {
12112
12234
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
12113
12235
  file: { unit: "\u0431\u0430\u0439\u0442\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -12215,7 +12337,7 @@ var error54 = () => {
12215
12337
  };
12216
12338
  function uk_default() {
12217
12339
  return {
12218
- localeError: error54()
12340
+ localeError: error55()
12219
12341
  };
12220
12342
  }
12221
12343
 
@@ -12225,7 +12347,7 @@ function ua_default() {
12225
12347
  }
12226
12348
 
12227
12349
  // ../../node_modules/zod/v4/locales/ur.js
12228
- var error55 = () => {
12350
+ var error56 = () => {
12229
12351
  const Sizable = {
12230
12352
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
12231
12353
  file: { unit: "\u0628\u0627\u0626\u0679\u0633", verb: "\u06C1\u0648\u0646\u0627" },
@@ -12335,12 +12457,12 @@ var error55 = () => {
12335
12457
  };
12336
12458
  function ur_default() {
12337
12459
  return {
12338
- localeError: error55()
12460
+ localeError: error56()
12339
12461
  };
12340
12462
  }
12341
12463
 
12342
12464
  // ../../node_modules/zod/v4/locales/uz.js
12343
- var error56 = () => {
12465
+ var error57 = () => {
12344
12466
  const Sizable = {
12345
12467
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
12346
12468
  file: { unit: "bayt", verb: "bo\u2018lishi kerak" },
@@ -12448,12 +12570,12 @@ var error56 = () => {
12448
12570
  };
12449
12571
  function uz_default() {
12450
12572
  return {
12451
- localeError: error56()
12573
+ localeError: error57()
12452
12574
  };
12453
12575
  }
12454
12576
 
12455
12577
  // ../../node_modules/zod/v4/locales/vi.js
12456
- var error57 = () => {
12578
+ var error58 = () => {
12457
12579
  const Sizable = {
12458
12580
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
12459
12581
  file: { unit: "byte", verb: "c\xF3" },
@@ -12561,12 +12683,12 @@ var error57 = () => {
12561
12683
  };
12562
12684
  function vi_default() {
12563
12685
  return {
12564
- localeError: error57()
12686
+ localeError: error58()
12565
12687
  };
12566
12688
  }
12567
12689
 
12568
12690
  // ../../node_modules/zod/v4/locales/zh-CN.js
12569
- var error58 = () => {
12691
+ var error59 = () => {
12570
12692
  const Sizable = {
12571
12693
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
12572
12694
  file: { unit: "\u5B57\u8282", verb: "\u5305\u542B" },
@@ -12675,12 +12797,12 @@ var error58 = () => {
12675
12797
  };
12676
12798
  function zh_CN_default() {
12677
12799
  return {
12678
- localeError: error58()
12800
+ localeError: error59()
12679
12801
  };
12680
12802
  }
12681
12803
 
12682
12804
  // ../../node_modules/zod/v4/locales/zh-TW.js
12683
- var error59 = () => {
12805
+ var error60 = () => {
12684
12806
  const Sizable = {
12685
12807
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
12686
12808
  file: { unit: "\u4F4D\u5143\u7D44", verb: "\u64C1\u6709" },
@@ -12787,12 +12909,12 @@ var error59 = () => {
12787
12909
  };
12788
12910
  function zh_TW_default() {
12789
12911
  return {
12790
- localeError: error59()
12912
+ localeError: error60()
12791
12913
  };
12792
12914
  }
12793
12915
 
12794
12916
  // ../../node_modules/zod/v4/locales/yo.js
12795
- var error60 = () => {
12917
+ var error61 = () => {
12796
12918
  const Sizable = {
12797
12919
  string: { unit: "\xE0mi", verb: "n\xED" },
12798
12920
  file: { unit: "bytes", verb: "n\xED" },
@@ -12899,7 +13021,7 @@ var error60 = () => {
12899
13021
  };
12900
13022
  function yo_default() {
12901
13023
  return {
12902
- localeError: error60()
13024
+ localeError: error61()
12903
13025
  };
12904
13026
  }
12905
13027
 
@@ -13776,7 +13898,7 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
13776
13898
  }
13777
13899
  }
13778
13900
  const outputVar = newVar(ctx);
13779
- const hasConditionalKeys = allKeys.some((k) => mayOutputUndefined(propShape[k]) || dropsWhenAbsent(propShape[k]));
13901
+ const hasConditionalKeys = allKeys.some((k) => mayOmitUndefined(propShape[k]) || dropsWhenAbsent(propShape[k]));
13780
13902
  if (!buildsValue) {
13781
13903
  if (unknownKeysMode === "schema") {
13782
13904
  const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;
@@ -13803,7 +13925,7 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
13803
13925
  const out = propOutputs.get(k);
13804
13926
  if (dropsWhenAbsent(propShape[k])) {
13805
13927
  doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
13806
- } else if (mayOutputUndefined(propShape[k])) {
13928
+ } else if (mayOmitUndefined(propShape[k])) {
13807
13929
  doc.write(`if (${out} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
13808
13930
  } else {
13809
13931
  doc.write(`${outputVar}[${kx}] = ${out};`);
@@ -13936,6 +14058,9 @@ function fastPathAcceptsAbsence(schema) {
13936
14058
  function dropsWhenAbsent(schema) {
13937
14059
  return schema._zod.optin === "optional" && schema._zod.optout === "optional";
13938
14060
  }
14061
+ function mayOmitUndefined(schema) {
14062
+ return (schema._zod.optin !== "defaulted" || schema._zod.optout === "optional") && mayOutputUndefined(schema);
14063
+ }
13939
14064
  function mayOutputUndefined(schema) {
13940
14065
  const def = schema._zod.def;
13941
14066
  switch (def.type) {
@@ -20053,9 +20178,9 @@ function summarizeToolCallResult(toolName, payload) {
20053
20178
  }
20054
20179
  return { outcome, preview: summarizeToolCallPayloadPreview(payload) };
20055
20180
  }
20056
- function classifyToolCallOutcome(toolName, result, error61, errorDetails = {}) {
20057
- if (error61 !== void 0) {
20058
- return { outcome: "error", errorCategory: classifyToolCallError(error61, errorDetails) };
20181
+ function classifyToolCallOutcome(toolName, result, error62, errorDetails = {}) {
20182
+ if (error62 !== void 0) {
20183
+ return { outcome: "error", errorCategory: classifyToolCallError(error62, errorDetails) };
20059
20184
  }
20060
20185
  return { outcome: summarizeToolCallResult(toolName, result).outcome };
20061
20186
  }
@@ -21264,10 +21389,10 @@ function validateIfConditionLiteral({ condition, context, stepId }) {
21264
21389
  if (!resolved)
21265
21390
  continue;
21266
21391
  anyResolved = true;
21267
- const error61 = ifConditionLiteralError({ reference, literal: literal2, stepId, schema: resolved });
21268
- if (!error61)
21392
+ const error62 = ifConditionLiteralError({ reference, literal: literal2, stepId, schema: resolved });
21393
+ if (!error62)
21269
21394
  return null;
21270
- firstError ??= error61;
21395
+ firstError ??= error62;
21271
21396
  }
21272
21397
  return anyResolved ? firstError : null;
21273
21398
  }
@@ -21328,17 +21453,17 @@ function validateManifestTemplateVariables(data, ctx) {
21328
21453
  };
21329
21454
  if (typeof step.if === "string") {
21330
21455
  for (const variable of extractTemplateVariables(step.if)) {
21331
- const error61 = validateTemplateVariable({
21456
+ const error62 = validateTemplateVariable({
21332
21457
  variable,
21333
21458
  context,
21334
21459
  stepId: step.id,
21335
21460
  currentStepGuard,
21336
21461
  sourceType: "condition"
21337
21462
  });
21338
- if (error61) {
21463
+ if (error62) {
21339
21464
  ctx.addIssue({
21340
21465
  code: external_exports.ZodIssueCode.custom,
21341
- message: error61,
21466
+ message: error62,
21342
21467
  path: ["steps", stepIndex, "if"]
21343
21468
  });
21344
21469
  }
@@ -21359,21 +21484,21 @@ function validateManifestTemplateVariables(data, ctx) {
21359
21484
  if ("prompt" in step && typeof step.prompt === "string") {
21360
21485
  const variables = extractTemplateVariables(step.prompt);
21361
21486
  for (const variable of variables) {
21362
- const error61 = validateTemplateVariable({
21487
+ const error62 = validateTemplateVariable({
21363
21488
  variable,
21364
21489
  context,
21365
21490
  stepId: step.id,
21366
21491
  currentStepGuard
21367
21492
  });
21368
- if (!error61)
21493
+ if (!error62)
21369
21494
  continue;
21370
21495
  const parts = variable.split(".");
21371
- if (parts[0] === "steps" && parts[1] && !context.steps.has(parts[1]) && error61.includes("before it is available")) {
21496
+ if (parts[0] === "steps" && parts[1] && !context.steps.has(parts[1]) && error62.includes("before it is available")) {
21372
21497
  unavailableStepRefs.add(parts[1]);
21373
21498
  } else {
21374
21499
  ctx.addIssue({
21375
21500
  code: external_exports.ZodIssueCode.custom,
21376
- message: error61,
21501
+ message: error62,
21377
21502
  path: ["steps", stepIndex, "prompt"]
21378
21503
  });
21379
21504
  }
@@ -21392,18 +21517,18 @@ function validateManifestTemplateVariables(data, ctx) {
21392
21517
  if (typeof value !== "string")
21393
21518
  continue;
21394
21519
  for (const variable of extractTemplateVariables(value)) {
21395
- const error61 = validateTemplateVariable({
21520
+ const error62 = validateTemplateVariable({
21396
21521
  variable,
21397
21522
  context,
21398
21523
  stepId: step.id,
21399
21524
  currentStepGuard,
21400
21525
  sourceType: fieldName
21401
21526
  });
21402
- if (!error61)
21527
+ if (!error62)
21403
21528
  continue;
21404
21529
  ctx.addIssue({
21405
21530
  code: external_exports.ZodIssueCode.custom,
21406
- message: error61,
21531
+ message: error62,
21407
21532
  path: ["steps", stepIndex, fieldName]
21408
21533
  });
21409
21534
  }
@@ -22759,6 +22884,7 @@ var UsageBillingEntrySchema = external_exports.object({
22759
22884
  var USAGE_BILLING_ENTRY_TYPES = [
22760
22885
  "usage_settled",
22761
22886
  "top_up",
22887
+ "adjustment",
22762
22888
  "void",
22763
22889
  "expiry",
22764
22890
  "chargeback"
@@ -23369,10 +23495,10 @@ async function request(args) {
23369
23495
  let response;
23370
23496
  try {
23371
23497
  response = await fetch(url2, init);
23372
- } catch (error61) {
23498
+ } catch (error62) {
23373
23499
  if (signal?.aborted)
23374
- throw error61;
23375
- throw new AutomationsNetworkError("Request failed before a response was received", error61);
23500
+ throw error62;
23501
+ throw new AutomationsNetworkError("Request failed before a response was received", error62);
23376
23502
  }
23377
23503
  const data = await readResponseBody(response);
23378
23504
  if (!response.ok) {
@@ -24092,11 +24218,11 @@ var connectionsEndpoints = {
24092
24218
  };
24093
24219
 
24094
24220
  // ../../packages/sdk/dist/esm/clients/connections/connections-client.js
24095
- function getConnectionInUseError(error61) {
24096
- if (!(error61 instanceof AutomationsRequestError) || error61.httpStatusCode !== 409) {
24221
+ function getConnectionInUseError(error62) {
24222
+ if (!(error62 instanceof AutomationsRequestError) || error62.httpStatusCode !== 409) {
24097
24223
  return null;
24098
24224
  }
24099
- const parsed = ConnectionInUseConflictSchema.safeParse(error61.responseData);
24225
+ const parsed = ConnectionInUseConflictSchema.safeParse(error62.responseData);
24100
24226
  return parsed.success ? parsed.data : null;
24101
24227
  }
24102
24228
  var connectionTokenResponseSchema = external_exports.object({
@@ -24689,6 +24815,58 @@ var AutomationsApi = class {
24689
24815
  }
24690
24816
  };
24691
24817
 
24818
+ // ../../packages/sdk/dist/esm/summaries/automation-summary.js
24819
+ function summarizeAutomation(automation) {
24820
+ return {
24821
+ ...automation,
24822
+ connections: automation.connections.map((connection) => ({
24823
+ id: connection.id,
24824
+ name: connection.name,
24825
+ connectorId: connection.connectorId,
24826
+ capabilities: connection.capabilities,
24827
+ status: connection.status,
24828
+ createdAt: connection.createdAt
24829
+ }))
24830
+ };
24831
+ }
24832
+ function summarizeAutomationPage(page) {
24833
+ return { ...page, data: page.data.map(summarizeAutomation) };
24834
+ }
24835
+
24836
+ // ../../packages/sdk/dist/esm/summaries/run-summary.js
24837
+ function summarizeRun(run) {
24838
+ return {
24839
+ id: run.id,
24840
+ automationId: run.automationId,
24841
+ status: run.status,
24842
+ createdAt: run.createdAt,
24843
+ updatedAt: run.updatedAt,
24844
+ failureCategory: getRunOutcomeCategory(run),
24845
+ failureReason: getRunOutcomeReason(run),
24846
+ result: run.result,
24847
+ temporalUrl: run.temporalUrl,
24848
+ steps: run.steps.map((step) => ({
24849
+ stepId: step.stepId,
24850
+ type: step.type,
24851
+ description: step.description,
24852
+ status: step.status,
24853
+ startedAt: step.startedAt,
24854
+ completedAt: step.completedAt,
24855
+ error: step.error,
24856
+ toolCalls: step.toolCalls?.map((toolCall) => ({
24857
+ id: toolCall.id,
24858
+ name: toolCall.name,
24859
+ argumentKeys: toolCall.argumentKeys,
24860
+ hasResult: toolCall.hasResult,
24861
+ hasError: toolCall.hasError,
24862
+ resultPreview: toolCall.resultPreview,
24863
+ errorPreview: toolCall.errorPreview,
24864
+ timestamp: toolCall.timestamp
24865
+ }))
24866
+ }))
24867
+ };
24868
+ }
24869
+
24692
24870
  // src/lib/auth-environment.ts
24693
24871
  import { InvalidArgumentError } from "commander";
24694
24872
  var ENVIRONMENTS = {
@@ -25038,9 +25216,9 @@ async function fetchTodoistUser(token, todoistApiUrl) {
25038
25216
  response = await fetch(url2, {
25039
25217
  headers: { Authorization: `Bearer ${token}`, Accept: "application/json" }
25040
25218
  });
25041
- } catch (error61) {
25219
+ } catch (error62) {
25042
25220
  throw new Error(
25043
- `Could not reach Todoist to identify the account: ${getErrorMessage(error61)}`
25221
+ `Could not reach Todoist to identify the account: ${getErrorMessage(error62)}`
25044
25222
  );
25045
25223
  }
25046
25224
  if (!response.ok) {
@@ -25051,9 +25229,9 @@ async function fetchTodoistUser(token, todoistApiUrl) {
25051
25229
  let user;
25052
25230
  try {
25053
25231
  user = await response.json();
25054
- } catch (error61) {
25232
+ } catch (error62) {
25055
25233
  throw new Error(
25056
- `Todoist returned an unreadable identity response: ${getErrorMessage(error61)}`
25234
+ `Todoist returned an unreadable identity response: ${getErrorMessage(error62)}`
25057
25235
  );
25058
25236
  }
25059
25237
  return { id: requireUserId(user.id), email: typeof user.email === "string" ? user.email : "" };
@@ -25066,16 +25244,16 @@ function requireUserId(id) {
25066
25244
 
25067
25245
  // src/lib/errors.ts
25068
25246
  import { getErrorMessage as getErrorMessage2 } from "@doist/cli-core";
25069
- function getErrorCode(error61) {
25070
- return typeof error61 === "object" && error61 !== null && "code" in error61 ? String(error61.code) : void 0;
25247
+ function getErrorCode(error62) {
25248
+ return typeof error62 === "object" && error62 !== null && "code" in error62 ? String(error62.code) : void 0;
25071
25249
  }
25072
- function formatError2(error61) {
25073
- const hints = errorHints(error61);
25074
- return [getErrorMessage2(error61), ...hints.map((hint) => ` - ${hint}`)].join("\n");
25250
+ function formatError2(error62) {
25251
+ const hints = errorHints(error62);
25252
+ return [getErrorMessage2(error62), ...hints.map((hint) => ` - ${hint}`)].join("\n");
25075
25253
  }
25076
- function errorHints(error61) {
25077
- if (typeof error61 !== "object" || error61 === null || !("hints" in error61)) return [];
25078
- const hints = error61.hints;
25254
+ function errorHints(error62) {
25255
+ if (typeof error62 !== "object" || error62 === null || !("hints" in error62)) return [];
25256
+ const hints = error62.hints;
25079
25257
  return Array.isArray(hints) ? hints.filter((hint) => typeof hint === "string") : [];
25080
25258
  }
25081
25259
 
@@ -25106,8 +25284,8 @@ async function resolveCredential(options = {}) {
25106
25284
  let snapshot;
25107
25285
  try {
25108
25286
  snapshot = await store2.activeBundle();
25109
- } catch (error61) {
25110
- return resolveAfterStoreFailure(error61);
25287
+ } catch (error62) {
25288
+ return resolveAfterStoreFailure(error62);
25111
25289
  }
25112
25290
  if (!snapshot) return fromEnvironment() ?? raiseNotAuthenticated();
25113
25291
  const accessToken = await freshAccessToken(store2, snapshot, options.minimumTokenLifetimeMs);
@@ -25129,12 +25307,12 @@ async function freshAccessToken(store2, snapshot, minimumTokenLifetimeMs) {
25129
25307
  handshake: { env: getEnvironment().name }
25130
25308
  });
25131
25309
  return result.bundle.accessToken;
25132
- } catch (error61) {
25133
- return accessTokenAfterFailedRefresh(error61, snapshot);
25310
+ } catch (error62) {
25311
+ return accessTokenAfterFailedRefresh(error62, snapshot);
25134
25312
  }
25135
25313
  }
25136
- function accessTokenAfterFailedRefresh(error61, snapshot) {
25137
- switch (getErrorCode(error61)) {
25314
+ function accessTokenAfterFailedRefresh(error62, snapshot) {
25315
+ switch (getErrorCode(error62)) {
25138
25316
  case "AUTH_REFRESH_UNAVAILABLE":
25139
25317
  return snapshot.bundle.accessToken;
25140
25318
  case "AUTH_REFRESH_EXPIRED":
@@ -25145,7 +25323,7 @@ function accessTokenAfterFailedRefresh(error61, snapshot) {
25145
25323
  if (hasTokenLifeLeft(snapshot)) return snapshot.bundle.accessToken;
25146
25324
  throw new CredentialError(
25147
25325
  "REFRESH_FAILED",
25148
- `Could not refresh your access token: ${getErrorMessage3(error61)}`,
25326
+ `Could not refresh your access token: ${getErrorMessage3(error62)}`,
25149
25327
  ["Check your network connection and try again."]
25150
25328
  );
25151
25329
  }
@@ -25161,8 +25339,8 @@ function fromEnvironment() {
25161
25339
  function raiseNotAuthenticated() {
25162
25340
  throw new NotAuthenticatedError();
25163
25341
  }
25164
- function resolveAfterStoreFailure(error61) {
25165
- const code = getErrorCode(error61);
25342
+ function resolveAfterStoreFailure(error62) {
25343
+ const code = getErrorCode(error62);
25166
25344
  if (code === "NO_ACCOUNT_SELECTED") {
25167
25345
  throw new CredentialError(
25168
25346
  "ACCOUNT_AMBIGUOUS",
@@ -25173,25 +25351,25 @@ function resolveAfterStoreFailure(error61) {
25173
25351
  if (code !== "AUTH_STORE_READ_FAILED") {
25174
25352
  throw new CredentialError(
25175
25353
  "CREDENTIAL_UNREADABLE",
25176
- `Could not read the stored credential: ${getErrorMessage3(error61)}`,
25354
+ `Could not read the stored credential: ${getErrorMessage3(error62)}`,
25177
25355
  ["Run `tda auth logout` and then `tda auth login` to replace it."]
25178
25356
  );
25179
25357
  }
25180
25358
  const fallback = fromEnvironment();
25181
25359
  if (fallback) {
25182
25360
  process.stderr.write(
25183
- `Warning: could not read the stored credential (${getErrorMessage3(error61)}). Using ${TOKEN_ENV_VAR}.
25361
+ `Warning: could not read the stored credential (${getErrorMessage3(error62)}). Using ${TOKEN_ENV_VAR}.
25184
25362
  `
25185
25363
  );
25186
25364
  return fallback;
25187
25365
  }
25188
- throw new CredentialError("CREDENTIAL_UNREADABLE", getErrorMessage3(error61), [
25366
+ throw new CredentialError("CREDENTIAL_UNREADABLE", getErrorMessage3(error62), [
25189
25367
  `Set ${TOKEN_ENV_VAR} to bypass the credential store.`,
25190
25368
  "Or re-run `tda auth login --credential-store plaintext`."
25191
25369
  ]);
25192
25370
  }
25193
- function explainAuthFailure(error61, source) {
25194
- const status = httpStatus(error61);
25371
+ function explainAuthFailure(error62, source) {
25372
+ const status = httpStatus(error62);
25195
25373
  if (status === 401) {
25196
25374
  return source === "env" ? new CredentialError("NOT_AUTHENTICATED", `Your ${TOKEN_ENV_VAR} was rejected.`, [
25197
25375
  "Check the token is a valid Todoist API token.",
@@ -25200,14 +25378,14 @@ function explainAuthFailure(error61, source) {
25200
25378
  "Run `tda auth login` to sign in again."
25201
25379
  ]);
25202
25380
  }
25203
- if (status === 403 && isInsufficientScopeChallenge(authChallenge(error61))) {
25381
+ if (status === 403 && isInsufficientScopeChallenge(authChallenge(error62))) {
25204
25382
  return new CredentialError(
25205
25383
  "INSUFFICIENT_SCOPE",
25206
25384
  "Your login does not grant what this command needs.",
25207
- insufficientScopeFixes(requiredScope(error61))
25385
+ insufficientScopeFixes(requiredScope(error62))
25208
25386
  );
25209
25387
  }
25210
- return error61;
25388
+ return error62;
25211
25389
  }
25212
25390
  function insufficientScopeFixes(scope) {
25213
25391
  if (!scope) {
@@ -25222,23 +25400,23 @@ function insufficientScopeFixes(scope) {
25222
25400
  flag ? `Run \`tda auth login --additional-scopes ${flag}\` to grant it.` : "Run `tda auth login` to authorize again, without --read-only."
25223
25401
  ];
25224
25402
  }
25225
- function requiredScope(error61) {
25226
- return readStringProperty(error61, "requiredScope");
25403
+ function requiredScope(error62) {
25404
+ return readStringProperty(error62, "requiredScope");
25227
25405
  }
25228
- function authChallenge(error61) {
25229
- return readStringProperty(error61, "authChallenge");
25406
+ function authChallenge(error62) {
25407
+ return readStringProperty(error62, "authChallenge");
25230
25408
  }
25231
- function httpStatus(error61) {
25232
- const status = readProperty(error61, "httpStatusCode");
25409
+ function httpStatus(error62) {
25410
+ const status = readProperty(error62, "httpStatusCode");
25233
25411
  return typeof status === "number" ? status : void 0;
25234
25412
  }
25235
- function readStringProperty(error61, key) {
25236
- const value = readProperty(error61, key);
25413
+ function readStringProperty(error62, key) {
25414
+ const value = readProperty(error62, key);
25237
25415
  return typeof value === "string" ? value : void 0;
25238
25416
  }
25239
- function readProperty(error61, key) {
25240
- if (typeof error61 !== "object" || error61 === null || !(key in error61)) return void 0;
25241
- return error61[key];
25417
+ function readProperty(error62, key) {
25418
+ if (typeof error62 !== "object" || error62 === null || !(key in error62)) return void 0;
25419
+ return error62[key];
25242
25420
  }
25243
25421
 
25244
25422
  // src/lib/api-configuration.ts
@@ -25891,8 +26069,8 @@ async function revokeToken(token) {
25891
26069
  signal: AbortSignal.timeout(REVOKE_TIMEOUT_MS)
25892
26070
  });
25893
26071
  return response.ok ? void 0 : `HTTP ${response.status}`;
25894
- } catch (error61) {
25895
- return getErrorMessage4(error61);
26072
+ } catch (error62) {
26073
+ return getErrorMessage4(error62);
25896
26074
  }
25897
26075
  }
25898
26076
 
@@ -26057,8 +26235,8 @@ async function writeNdjsonItem(item, stream = process.stdout) {
26057
26235
  }
26058
26236
 
26059
26237
  // src/lib/command-error.ts
26060
- function renderFailure(error61, context = {}) {
26061
- const explained = context.source ? explainAuthFailure(error61, context.source) : error61;
26238
+ function renderFailure(error62, context = {}) {
26239
+ const explained = context.source ? explainAuthFailure(error62, context.source) : error62;
26062
26240
  const code = getErrorCode(explained);
26063
26241
  return {
26064
26242
  message: getErrorMessage5(explained),
@@ -26108,7 +26286,7 @@ async function runApiCommand(command, operation, presentation, execution = {}) {
26108
26286
  );
26109
26287
  stopEarlySpinner();
26110
26288
  writeResult(mode, result, presentation);
26111
- } catch (error61) {
26289
+ } catch (error62) {
26112
26290
  if (abortController.signal.aborted) {
26113
26291
  writeFailure(mode, "interrupted", {
26114
26292
  message: "Interrupted.",
@@ -26117,7 +26295,7 @@ async function runApiCommand(command, operation, presentation, execution = {}) {
26117
26295
  process.exitCode = 130;
26118
26296
  return;
26119
26297
  }
26120
- writeFailure(mode, "error", renderFailure(error61, { mode, source }));
26298
+ writeFailure(mode, "error", renderFailure(error62, { mode, source }));
26121
26299
  process.exitCode = 1;
26122
26300
  } finally {
26123
26301
  process.removeListener("SIGINT", onInterrupt);
@@ -26176,22 +26354,6 @@ function formatAutomation(automation) {
26176
26354
  formatValue(automation.manifest)
26177
26355
  ].join("\n");
26178
26356
  }
26179
- function summarizeAutomation(automation) {
26180
- return {
26181
- ...automation,
26182
- connections: automation.connections.map((connection) => ({
26183
- id: connection.id,
26184
- name: connection.name,
26185
- connectorId: connection.connectorId,
26186
- capabilities: connection.capabilities,
26187
- status: connection.status,
26188
- createdAt: connection.createdAt
26189
- }))
26190
- };
26191
- }
26192
- function summarizeAutomationPage(page) {
26193
- return { ...page, data: page.data.map(summarizeAutomation) };
26194
- }
26195
26357
  function formatDraftList(page) {
26196
26358
  if (page.data.length === 0) return "No drafts found.";
26197
26359
  return withNextCursor(
@@ -26293,38 +26455,6 @@ function formatRun(run) {
26293
26455
  }
26294
26456
  return lines.join("\n");
26295
26457
  }
26296
- function summarizeRun(run) {
26297
- return {
26298
- id: run.id,
26299
- automationId: run.automationId,
26300
- status: run.status,
26301
- createdAt: run.createdAt,
26302
- updatedAt: run.updatedAt,
26303
- failureCategory: getRunOutcomeCategory(run),
26304
- failureReason: getRunOutcomeReason(run),
26305
- result: run.result,
26306
- temporalUrl: run.temporalUrl,
26307
- steps: run.steps.map((step) => ({
26308
- stepId: step.stepId,
26309
- type: step.type,
26310
- description: step.description,
26311
- status: step.status,
26312
- startedAt: step.startedAt,
26313
- completedAt: step.completedAt,
26314
- error: step.error,
26315
- toolCalls: step.toolCalls?.map((toolCall) => ({
26316
- id: toolCall.id,
26317
- name: toolCall.name,
26318
- argumentKeys: toolCall.argumentKeys,
26319
- hasResult: toolCall.hasResult,
26320
- hasError: toolCall.hasError,
26321
- resultPreview: toolCall.resultPreview,
26322
- errorPreview: toolCall.errorPreview,
26323
- timestamp: toolCall.timestamp
26324
- }))
26325
- }))
26326
- };
26327
- }
26328
26458
  function getResourceName(manifest) {
26329
26459
  if (!isRecord2(manifest)) return "(unnamed)";
26330
26460
  return typeof manifest.name === "string" && manifest.name.trim() ? manifest.name : "(unnamed)";
@@ -26558,13 +26688,13 @@ async function runStreamingCommand(command, handlers) {
26558
26688
  const context = { options, mode, output: output2, signal: abortController.signal };
26559
26689
  const result = await handlers.operation(context);
26560
26690
  await handlers.onSuccess(result, context);
26561
- } catch (error61) {
26691
+ } catch (error62) {
26562
26692
  const state = { mode, output: output2, signal: abortController.signal };
26563
26693
  if (abortController.signal.aborted) {
26564
26694
  await handlers.onInterrupted(state);
26565
26695
  process.exitCode = 130;
26566
26696
  } else {
26567
- await handlers.onError(error61, state);
26697
+ await handlers.onError(error62, state);
26568
26698
  process.exitCode = 1;
26569
26699
  }
26570
26700
  } finally {
@@ -26573,10 +26703,79 @@ async function runStreamingCommand(command, handlers) {
26573
26703
  }
26574
26704
  }
26575
26705
 
26576
- // src/commands/chat/chat-service.ts
26577
- import { getErrorMessage as getErrorMessage6 } from "@doist/cli-core";
26578
- import { createInterface } from "node:readline/promises";
26579
- import pLimit from "p-limit";
26706
+ // ../../packages/sdk/dist/esm/chat-turn/connection-requirements.js
26707
+ var CONNECTION_LOOKUP_CONCURRENCY = 4;
26708
+ function deduplicateConnectionRequirements(requirements) {
26709
+ const seen = /* @__PURE__ */ new Set();
26710
+ return requirements.filter((requirement) => {
26711
+ const key = JSON.stringify([requirement.connectorId, requirement.connectionType]);
26712
+ if (seen.has(key))
26713
+ return false;
26714
+ seen.add(key);
26715
+ return true;
26716
+ });
26717
+ }
26718
+ async function loadConnectionRequirements(connections, requirements, options) {
26719
+ return mapWithConcurrency(deduplicateConnectionRequirements(requirements), CONNECTION_LOOKUP_CONCURRENCY, async (requirement) => {
26720
+ const response = await connections.list({
26721
+ connectorId: requirement.connectorId,
26722
+ capability: requirement.connectionType,
26723
+ status: "authorized"
26724
+ }, options);
26725
+ return {
26726
+ ...requirement,
26727
+ availableConnections: response.connections.map((connection) => ({
26728
+ id: connection.id,
26729
+ label: connection.accountDisplayLabel ?? connection.name ?? connection.id
26730
+ }))
26731
+ };
26732
+ });
26733
+ }
26734
+ async function mapWithConcurrency(items, concurrency, map2) {
26735
+ const results = new Array(items.length);
26736
+ let next = 0;
26737
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
26738
+ while (next < items.length) {
26739
+ const index = next;
26740
+ next += 1;
26741
+ results[index] = await map2(items[index]);
26742
+ }
26743
+ });
26744
+ await Promise.all(workers);
26745
+ return results;
26746
+ }
26747
+
26748
+ // ../../packages/sdk/dist/esm/chat-turn/connection-setup.js
26749
+ async function startConnectionSetup(connections, request2, options) {
26750
+ const created = await connections.create({
26751
+ connectorId: request2.connectorId,
26752
+ capability: request2.capability,
26753
+ ...request2.automationIds?.length ? { body: { automationIds: [...request2.automationIds] } } : {}
26754
+ }, options);
26755
+ return { connectionId: created.connectionId, setup: created.setup, resumed: false };
26756
+ }
26757
+ function summarizeConnectionSetup(setup) {
26758
+ if (setup?.kind === "oauth") {
26759
+ return { setupKind: "oauth", authorizationUrl: setup.authorizationUrl };
26760
+ }
26761
+ if (setup?.kind === "managed") {
26762
+ return {
26763
+ setupKind: "managed",
26764
+ instructions: setup.instructions,
26765
+ code: setup.code,
26766
+ deepLinkUrl: setup.deepLinkUrl,
26767
+ expiresAt: setup.expiresAt
26768
+ };
26769
+ }
26770
+ return { setupKind: "none" };
26771
+ }
26772
+ function getConnectionSetupUrl(setup) {
26773
+ if (setup?.kind === "oauth")
26774
+ return setup.authorizationUrl;
26775
+ if (setup?.kind === "managed")
26776
+ return setup.deepLinkUrl;
26777
+ return null;
26778
+ }
26580
26779
 
26581
26780
  // ../../packages/core/dist/esm/chat-tools/client-tool-result.js
26582
26781
  var clientToolContinuationPartSchema = external_exports.discriminatedUnion("type", [
@@ -26611,11 +26810,10 @@ var toolUpdateMemoryResultSchema = external_exports.object({
26611
26810
  output: UpdateMemoryOutputSchema
26612
26811
  });
26613
26812
 
26614
- // src/commands/chat/chat-message.ts
26615
- import { randomUUID } from "node:crypto";
26813
+ // ../../packages/sdk/dist/esm/chat-turn/messages.js
26616
26814
  function createUserMessage(text) {
26617
26815
  return {
26618
- id: randomUUID(),
26816
+ id: globalThis.crypto.randomUUID(),
26619
26817
  role: "user",
26620
26818
  parts: [{ type: "text", text }]
26621
26819
  };
@@ -26634,9 +26832,7 @@ function toUiMessage(message) {
26634
26832
  };
26635
26833
  }
26636
26834
  function getVisibleText(message) {
26637
- return message.parts.filter(
26638
- (part) => part.type === "text"
26639
- ).map((part) => part.text).join("");
26835
+ return message.parts.filter((part) => part.type === "text").map((part) => part.text).join("");
26640
26836
  }
26641
26837
  function getPendingClientAction(message) {
26642
26838
  for (let index = message.parts.length - 1; index >= 0; index -= 1) {
@@ -26661,6 +26857,12 @@ function getPendingClientAction(message) {
26661
26857
  }
26662
26858
  return null;
26663
26859
  }
26860
+ function getPendingActionFromMessages(messages) {
26861
+ const latestMessage = messages.at(-1);
26862
+ if (!latestMessage || latestMessage.role !== "assistant")
26863
+ return null;
26864
+ return getPendingClientAction(toUiMessage(latestMessage));
26865
+ }
26664
26866
  function getPublishedAutomationId(message) {
26665
26867
  for (let index = message.parts.length - 1; index >= 0; index -= 1) {
26666
26868
  const part = message.parts[index];
@@ -26685,7 +26887,181 @@ function createSelectConnectionsContinuation(action, output2) {
26685
26887
  };
26686
26888
  }
26687
26889
 
26688
- // src/commands/chat/chat-transport.ts
26890
+ // ../../packages/sdk/dist/esm/chat-turn/types.js
26891
+ var ChatTurnInputError = class extends Error {
26892
+ code;
26893
+ constructor(code, message) {
26894
+ super(message);
26895
+ this.name = "ChatTurnInputError";
26896
+ this.code = code;
26897
+ }
26898
+ };
26899
+
26900
+ // ../../packages/sdk/dist/esm/chat-turn/run-conversation-turn.js
26901
+ async function runConversationTurn(options) {
26902
+ const { api, transport, conversationId, signal } = options;
26903
+ const workspaceId = options.workspaceId ?? null;
26904
+ const requestOptions = { signal };
26905
+ const pending = await readPendingAction(options);
26906
+ let nextMessage;
26907
+ if (pending?.kind === "enable_push") {
26908
+ if ("selections" in options.input && options.input.selections.length > 0) {
26909
+ throw new ChatTurnInputError("not_awaiting_selection", "The conversation is not waiting for connection selection.");
26910
+ }
26911
+ return actionRequired(conversationId, getVisibleText(pending.message), {
26912
+ kind: "enable_push",
26913
+ toolCallId: pending.toolCallId,
26914
+ draftId: pending.draftId
26915
+ });
26916
+ }
26917
+ if ("message" in options.input) {
26918
+ if (pending?.kind === "select_connections") {
26919
+ throw new ChatTurnInputError("awaiting_selection", "The conversation is waiting for connection selection.");
26920
+ }
26921
+ nextMessage = createUserMessage(options.input.message);
26922
+ } else {
26923
+ const selections = options.input.selections;
26924
+ if (pending?.kind !== "select_connections") {
26925
+ throw new ChatTurnInputError(selections.length > 0 ? "not_awaiting_selection" : "input_required", selections.length > 0 ? "The conversation is not waiting for connection selection." : "A message is required to continue.");
26926
+ }
26927
+ const resolution = await resolveSelectConnections(options, pending, selections);
26928
+ if (resolution.kind === "required") {
26929
+ return actionRequired(conversationId, getVisibleText(pending.message), resolution.pendingAction);
26930
+ }
26931
+ nextMessage = resolution.continuation;
26932
+ }
26933
+ while (true) {
26934
+ const response = await transport.streamTurn({
26935
+ conversationId,
26936
+ workspaceId,
26937
+ message: nextMessage,
26938
+ signal,
26939
+ onText: options.onText,
26940
+ onToolActivity: options.onToolActivity
26941
+ });
26942
+ const assistantText = getVisibleText(response);
26943
+ const automationId = getPublishedAutomationId(response);
26944
+ if (automationId) {
26945
+ options.onPublished?.(automationId);
26946
+ const archive = await archiveConversation(api, conversationId, requestOptions);
26947
+ return {
26948
+ conversationId,
26949
+ outcome: "published",
26950
+ assistantText,
26951
+ automationId,
26952
+ ...archive
26953
+ };
26954
+ }
26955
+ const responseAction = getPendingClientAction(response);
26956
+ if (responseAction?.kind === "select_connections") {
26957
+ const resolution = await resolveSelectConnections(options, responseAction, []);
26958
+ if (resolution.kind === "resolved") {
26959
+ nextMessage = resolution.continuation;
26960
+ continue;
26961
+ }
26962
+ return actionRequired(conversationId, assistantText, resolution.pendingAction);
26963
+ }
26964
+ if (responseAction?.kind === "enable_push") {
26965
+ return actionRequired(conversationId, assistantText, {
26966
+ kind: "enable_push",
26967
+ toolCallId: responseAction.toolCallId,
26968
+ draftId: responseAction.draftId
26969
+ });
26970
+ }
26971
+ return { conversationId, outcome: "awaiting_input", assistantText };
26972
+ }
26973
+ }
26974
+ async function readPendingAction(options) {
26975
+ if (options.pendingAction !== void 0)
26976
+ return options.pendingAction;
26977
+ const messages = await options.api.chat.getMessages(options.conversationId, {
26978
+ signal: options.signal
26979
+ });
26980
+ return getPendingActionFromMessages(messages);
26981
+ }
26982
+ function actionRequired(conversationId, assistantText, pendingAction) {
26983
+ return { conversationId, outcome: "action_required", assistantText, pendingAction };
26984
+ }
26985
+ async function archiveConversation(api, conversationId, requestOptions) {
26986
+ try {
26987
+ const conversation = await api.chat.updateConversation(conversationId, { isArchived: true }, requestOptions);
26988
+ if (!conversation.isArchived) {
26989
+ throw new Error("The Automations API returned an active conversation.");
26990
+ }
26991
+ return { conversationArchived: true };
26992
+ } catch (error62) {
26993
+ return {
26994
+ conversationArchived: false,
26995
+ conversationArchiveError: error62 instanceof Error ? error62.message : String(error62)
26996
+ };
26997
+ }
26998
+ }
26999
+ async function resolveSelectConnections(options, action, selections) {
27000
+ const { api, signal } = options;
27001
+ const requestOptions = { signal };
27002
+ const requirements = await loadConnectionRequirements(api.connections, action.connections, requestOptions);
27003
+ assertSelectionsUnambiguous(requirements, selections);
27004
+ const resolved = [];
27005
+ for (const requirement of requirements) {
27006
+ const explicit = selections.find((selection) => selection.connectorId === requirement.connectorId && (!selection.connectionType || selection.connectionType === requirement.connectionType));
27007
+ let connectionId = explicit?.connectionId;
27008
+ let setup;
27009
+ if (connectionId) {
27010
+ const exists = requirement.availableConnections.some((connection) => connection.id === connectionId);
27011
+ if (!exists) {
27012
+ throw new ChatTurnInputError("unknown_connection", `Connection ${connectionId} is not an authorized ${requirement.serviceName} connection.`);
27013
+ }
27014
+ } else if (requirement.availableConnections.length === 1) {
27015
+ connectionId = requirement.availableConnections[0]?.id;
27016
+ } else if (requirement.availableConnections.length > 1) {
27017
+ connectionId = await options.chooseConnection?.(requirement);
27018
+ } else if (options.authorizeConnection) {
27019
+ connectionId = await options.authorizeConnection(requirement);
27020
+ } else {
27021
+ setup = await startConnectionSetup(api.connections, { connectorId: requirement.connectorId, capability: requirement.connectionType }, requestOptions);
27022
+ }
27023
+ if (!connectionId) {
27024
+ return {
27025
+ kind: "required",
27026
+ pendingAction: {
27027
+ kind: "select_connections",
27028
+ toolCallId: action.toolCallId,
27029
+ draftId: action.draftId,
27030
+ requirements: requirements.map((item) => item === requirement && setup ? { ...item, setup } : item)
27031
+ }
27032
+ };
27033
+ }
27034
+ resolved.push({ requirement, connectionId });
27035
+ }
27036
+ const output2 = [];
27037
+ for (const item of resolved) {
27038
+ const body = {
27039
+ connectorId: item.requirement.connectorId,
27040
+ connectionType: item.requirement.connectionType,
27041
+ connectionId: item.connectionId
27042
+ };
27043
+ const workspaceId = options.workspaceId ?? null;
27044
+ if (workspaceId === null) {
27045
+ await api.automationDraftConnections.upsert(action.draftId, body, requestOptions);
27046
+ } else {
27047
+ await api.workspaceAutomationDraftConnections.upsert(workspaceId, action.draftId, body, requestOptions);
27048
+ }
27049
+ output2.push({ type: "success", ...body });
27050
+ }
27051
+ return { kind: "resolved", continuation: createSelectConnectionsContinuation(action, output2) };
27052
+ }
27053
+ function assertSelectionsUnambiguous(requirements, selections) {
27054
+ for (const selection of selections) {
27055
+ if (selection.connectionType)
27056
+ continue;
27057
+ const matchingTypes = new Set(requirements.filter((requirement) => requirement.connectorId === selection.connectorId).map((requirement) => requirement.connectionType));
27058
+ if (matchingTypes.size > 1) {
27059
+ throw new ChatTurnInputError("ambiguous_selection", `Connection selection for ${selection.connectorId} is ambiguous. Specify ${selection.connectorId}:mcp or ${selection.connectorId}:trigger.`);
27060
+ }
27061
+ }
27062
+ }
27063
+
27064
+ // ../../packages/sdk/dist/esm/chat-turn/transport.js
26689
27065
  import { DefaultChatTransport, readUIMessageStream } from "ai";
26690
27066
  var ChatTurnTransport = class {
26691
27067
  transport;
@@ -26712,14 +27088,7 @@ var ChatTurnTransport = class {
26712
27088
  });
26713
27089
  }
26714
27090
  /** Streams one server turn, reporting incremental text and deduplicated tool state changes. */
26715
- async streamTurn({
26716
- conversationId,
26717
- workspaceId = null,
26718
- message,
26719
- signal,
26720
- onText,
26721
- onToolActivity
26722
- }) {
27091
+ async streamTurn({ conversationId, workspaceId = null, message, signal, onText, onToolActivity }) {
26723
27092
  const stream = await this.transport.sendMessages({
26724
27093
  trigger: "submit-message",
26725
27094
  chatId: conversationId,
@@ -26739,14 +27108,17 @@ var ChatTurnTransport = class {
26739
27108
  const visibleText = getVisibleText(currentMessage);
26740
27109
  if (visibleText.startsWith(emittedText)) {
26741
27110
  const delta = visibleText.slice(emittedText.length);
26742
- if (delta) onText(delta);
27111
+ if (delta)
27112
+ onText?.(delta);
26743
27113
  emittedText = visibleText;
26744
27114
  }
26745
27115
  for (const part of currentMessage.parts) {
26746
27116
  const activity = toToolActivity(part);
26747
- if (!activity) continue;
27117
+ if (!activity)
27118
+ continue;
26748
27119
  const key = `${activity.toolCallId}:${activity.state}`;
26749
- if (emittedToolStates.has(key)) continue;
27120
+ if (emittedToolStates.has(key))
27121
+ continue;
26750
27122
  emittedToolStates.add(key);
26751
27123
  onToolActivity?.(activity);
26752
27124
  }
@@ -26768,6 +27140,9 @@ function toToolActivity(part) {
26768
27140
  };
26769
27141
  }
26770
27142
 
27143
+ // src/commands/chat/chat-service.ts
27144
+ import { createInterface } from "node:readline/promises";
27145
+
26771
27146
  // src/commands/chat/connection-authorizer.ts
26772
27147
  import open2 from "open";
26773
27148
  import { setTimeout as wait } from "node:timers/promises";
@@ -27084,11 +27459,12 @@ var ApiConnectionAuthorizer = class {
27084
27459
  this.timeoutMs = timeoutMs ?? CONNECTION_AUTHORIZATION_TIMEOUT_MS;
27085
27460
  }
27086
27461
  async authorize(request2, signal) {
27087
- const created = await this.connections.create(
27462
+ const created = await startConnectionSetup(
27463
+ this.connections,
27088
27464
  {
27089
27465
  connectorId: request2.connectorId,
27090
27466
  capability: request2.connectionType,
27091
- ...request2.automationIds?.length ? { body: { automationIds: [...request2.automationIds] } } : {}
27467
+ automationIds: request2.automationIds
27092
27468
  },
27093
27469
  { signal }
27094
27470
  );
@@ -27115,19 +27491,12 @@ var ApiConnectionAuthorizer = class {
27115
27491
  connectionType: request2.connectionType,
27116
27492
  state: "waiting_for_user",
27117
27493
  terminal: false,
27118
- setupKind: setup?.kind ?? "none",
27119
- ...resumed ? { resumed: true } : {},
27120
- ...setup?.kind === "oauth" ? { authorizationUrl: setup.authorizationUrl } : {},
27121
- ...setup?.kind === "managed" ? {
27122
- instructions: setup.instructions,
27123
- code: setup.code,
27124
- deepLinkUrl: setup.deepLinkUrl,
27125
- expiresAt: setup.expiresAt
27126
- } : {}
27494
+ ...summarizeConnectionSetup(setup),
27495
+ ...resumed ? { resumed: true } : {}
27127
27496
  });
27128
27497
  }
27129
27498
  async openSetup(request2, connectionId, setup, signal) {
27130
- const url2 = setup?.kind === "oauth" ? setup.authorizationUrl : setup?.kind === "managed" ? setup.deepLinkUrl : null;
27499
+ const url2 = getConnectionSetupUrl(setup);
27131
27500
  if (!url2 || !this.openBrowser || !isSafeSetupUrl(url2)) return;
27132
27501
  try {
27133
27502
  signal?.throwIfAborted();
@@ -27142,8 +27511,8 @@ var ApiConnectionAuthorizer = class {
27142
27511
  state: "waiting_for_user",
27143
27512
  terminal: false
27144
27513
  });
27145
- } catch (error61) {
27146
- if (signal?.aborted) throw error61;
27514
+ } catch (error62) {
27515
+ if (signal?.aborted) throw error62;
27147
27516
  this.output.emit({
27148
27517
  type: "warning",
27149
27518
  code: "TDA_BROWSER_OPEN_FAILED",
@@ -27208,22 +27577,11 @@ function isSafeSetupUrl(value) {
27208
27577
  }
27209
27578
  }
27210
27579
 
27211
- // src/commands/chat/connection-requirements.ts
27212
- function deduplicateConnectionRequirements(requirements) {
27213
- const seen = /* @__PURE__ */ new Set();
27214
- return requirements.filter((requirement) => {
27215
- const key = JSON.stringify([requirement.connectorId, requirement.connectionType]);
27216
- if (seen.has(key)) return false;
27217
- seen.add(key);
27218
- return true;
27219
- });
27220
- }
27221
-
27222
27580
  // src/commands/chat/conversation-turn-lock.ts
27223
27581
  import { link, mkdir, readFile, rm, writeFile } from "node:fs/promises";
27224
27582
  import { tmpdir } from "node:os";
27225
27583
  import { join } from "node:path";
27226
- import { randomUUID as randomUUID2 } from "node:crypto";
27584
+ import { randomUUID } from "node:crypto";
27227
27585
  var ConversationTurnLock = class {
27228
27586
  directory;
27229
27587
  pid;
@@ -27237,7 +27595,7 @@ var ConversationTurnLock = class {
27237
27595
  async acquire(conversationId) {
27238
27596
  await mkdir(this.directory, { recursive: true, mode: 448 });
27239
27597
  const path = join(this.directory, `${encodeURIComponent(conversationId)}.lock`);
27240
- const ownerId = randomUUID2();
27598
+ const ownerId = randomUUID();
27241
27599
  const pendingPath = `${path}.${ownerId}.pending`;
27242
27600
  await writeFile(
27243
27601
  pendingPath,
@@ -27255,8 +27613,8 @@ var ConversationTurnLock = class {
27255
27613
  const current2 = await readLock(path);
27256
27614
  if (current2?.ownerId === ownerId) await rm(path, { force: true });
27257
27615
  };
27258
- } catch (error61) {
27259
- if (!isFileExistsError(error61)) throw error61;
27616
+ } catch (error62) {
27617
+ if (!isFileExistsError(error62)) throw error62;
27260
27618
  }
27261
27619
  const current = await readLock(path);
27262
27620
  if (current && this.isProcessRunning(current.pid)) {
@@ -27277,8 +27635,8 @@ async function readLock(path) {
27277
27635
  if (typeof value === "object" && value !== null && typeof value.ownerId === "string" && typeof value.pid === "number") {
27278
27636
  return value;
27279
27637
  }
27280
- } catch (error61) {
27281
- if (!isFileMissingError(error61) && !(error61 instanceof SyntaxError)) throw error61;
27638
+ } catch (error62) {
27639
+ if (!isFileMissingError(error62) && !(error62 instanceof SyntaxError)) throw error62;
27282
27640
  }
27283
27641
  return null;
27284
27642
  }
@@ -27291,23 +27649,22 @@ function isProcessRunning(pid) {
27291
27649
  try {
27292
27650
  process.kill(pid, 0);
27293
27651
  return true;
27294
- } catch (error61) {
27295
- return !isNoSuchProcessError(error61);
27652
+ } catch (error62) {
27653
+ return !isNoSuchProcessError(error62);
27296
27654
  }
27297
27655
  }
27298
- function isFileExistsError(error61) {
27299
- return getErrorCode(error61) === "EEXIST";
27656
+ function isFileExistsError(error62) {
27657
+ return getErrorCode(error62) === "EEXIST";
27300
27658
  }
27301
- function isFileMissingError(error61) {
27302
- return getErrorCode(error61) === "ENOENT";
27659
+ function isFileMissingError(error62) {
27660
+ return getErrorCode(error62) === "ENOENT";
27303
27661
  }
27304
- function isNoSuchProcessError(error61) {
27305
- return getErrorCode(error61) === "ESRCH";
27662
+ function isNoSuchProcessError(error62) {
27663
+ return getErrorCode(error62) === "ESRCH";
27306
27664
  }
27307
27665
 
27308
27666
  // src/commands/chat/chat-service.ts
27309
27667
  var TURN_HEARTBEAT_INTERVAL_MS = 15e3;
27310
- var CONNECTION_LOOKUP_CONCURRENCY = 4;
27311
27668
  var TURN_RUNNING_MESSAGE = "Keep monitoring this process; do not invoke continue until turn_completed with terminal=true is emitted and the process exits.";
27312
27669
  var ChatService = class {
27313
27670
  api;
@@ -27351,12 +27708,12 @@ var ChatService = class {
27351
27708
  this.output.emit({ type: "session_started", conversationId: conversation.id });
27352
27709
  return this.withActiveTurn(
27353
27710
  conversation.id,
27354
- () => this.runConversationUntilTerminal({
27355
- conversationId: conversation.id,
27356
- workspaceId: conversation.workspaceId,
27357
- incomingMessage: createUserMessage(message),
27358
- signal
27359
- })
27711
+ () => this.runUntilTerminal(
27712
+ { conversationId: conversation.id, workspaceId: conversation.workspaceId },
27713
+ { message },
27714
+ signal,
27715
+ null
27716
+ )
27360
27717
  );
27361
27718
  }
27362
27719
  /** Resumes a persisted conversation with a message or pending connection selections. */
@@ -27367,59 +27724,26 @@ var ChatService = class {
27367
27724
  signal
27368
27725
  }) {
27369
27726
  const conversation = await this.api.chat.getConversation(conversationId, { signal });
27370
- const { workspaceId } = conversation;
27727
+ const scope = { conversationId, workspaceId: conversation.workspaceId };
27371
27728
  return this.withActiveTurn(
27372
27729
  conversationId,
27373
27730
  async () => {
27374
- let incomingMessage;
27375
27731
  const pendingAction = await this.getPersistedPendingAction(conversationId, signal);
27376
- if (pendingAction?.kind === "select_connections") {
27377
- if (message) {
27378
- throw new Error(
27379
- "Use either a message or --connection selections, not both."
27380
- );
27381
- }
27382
- const resolution = await this.resolveSelectConnections(
27383
- { conversationId, workspaceId },
27384
- pendingAction,
27385
- selections,
27386
- this.interactive,
27387
- signal
27388
- );
27389
- if (resolution.kind === "required") {
27390
- return this.completeRequiredConnectionAction(
27391
- conversationId,
27392
- getVisibleText(pendingAction.message),
27393
- resolution.action
27394
- );
27395
- }
27396
- incomingMessage = resolution.continuation;
27397
- } else if (pendingAction?.kind === "enable_push") {
27398
- if (selections.length > 0) {
27399
- throw new Error("The conversation is not waiting for connection selection.");
27400
- }
27401
- return this.completeRequiredPushAction(
27402
- conversationId,
27403
- getVisibleText(pendingAction.message),
27404
- pendingAction
27405
- );
27406
- } else if (selections.length > 0) {
27407
- throw new Error("The conversation is not waiting for connection selection.");
27732
+ let input2;
27733
+ if (message) {
27734
+ input2 = { message };
27735
+ } else if (selections.length > 0 || pendingAction) {
27736
+ input2 = { selections };
27408
27737
  } else {
27409
- const nextMessage = message ?? (this.interactive ? await this.promptForMessage(signal) : "");
27738
+ const nextMessage = this.interactive ? await this.promptForMessage(signal) : "";
27410
27739
  if (!nextMessage) {
27411
27740
  throw new Error(
27412
27741
  "A message or --connection selection is required to continue."
27413
27742
  );
27414
27743
  }
27415
- incomingMessage = createUserMessage(nextMessage);
27744
+ input2 = { message: nextMessage };
27416
27745
  }
27417
- return this.runConversationUntilTerminal({
27418
- conversationId,
27419
- workspaceId,
27420
- incomingMessage,
27421
- signal
27422
- });
27746
+ return this.runUntilTerminal(scope, input2, signal, pendingAction);
27423
27747
  },
27424
27748
  () => this.output.emit({ type: "session_resumed", conversationId })
27425
27749
  );
@@ -27451,13 +27775,12 @@ var ChatService = class {
27451
27775
  close() {
27452
27776
  this.readline?.close();
27453
27777
  }
27454
- async runConversationUntilTerminal({
27455
- conversationId,
27456
- workspaceId,
27457
- incomingMessage,
27458
- signal
27459
- }) {
27460
- let nextIncomingMessage = incomingMessage;
27778
+ /**
27779
+ * Runs server turns until one ends somewhere the CLI has to stop: a pending client action,
27780
+ * a publication, or, outside an interactive terminal, the agent waiting for input.
27781
+ */
27782
+ async runUntilTerminal(scope, input2, signal, pendingAction) {
27783
+ const { conversationId } = scope;
27461
27784
  const startedAt = Date.now();
27462
27785
  let lastActivityAt = startedAt;
27463
27786
  const markActivity = () => {
@@ -27477,67 +27800,29 @@ var ChatService = class {
27477
27800
  }, this.heartbeatIntervalMs);
27478
27801
  heartbeat?.unref();
27479
27802
  try {
27803
+ let nextInput = input2;
27804
+ let knownPendingAction = pendingAction;
27480
27805
  while (true) {
27481
- const response = await this.transport.streamTurn({
27482
- conversationId,
27483
- workspaceId,
27484
- message: nextIncomingMessage,
27485
- signal,
27486
- onText: (text) => {
27487
- markActivity();
27488
- this.output.emit({ type: "assistant_text", conversationId, text });
27489
- },
27490
- onToolActivity: (activity) => {
27491
- markActivity();
27492
- this.output.emit({ type: "tool_activity", conversationId, ...activity });
27493
- }
27806
+ const result = await this.runTurn(scope, nextInput, signal, knownPendingAction, {
27807
+ markActivity
27494
27808
  });
27495
- const assistantText = getVisibleText(response);
27496
- const automationId = getPublishedAutomationId(response);
27497
- if (automationId) {
27498
- this.output.emit({ type: "published", conversationId, automationId });
27499
- const conversationArchived = await this.archivePublishedConversation(
27500
- conversationId,
27501
- signal
27502
- );
27809
+ if (result.outcome === "published") {
27810
+ this.emitArchiveResult(result);
27503
27811
  return this.completeTurn({
27504
27812
  conversationId,
27505
- assistantText,
27813
+ assistantText: result.assistantText,
27506
27814
  status: "published",
27507
- automationId,
27508
- conversationArchived
27815
+ automationId: result.automationId,
27816
+ conversationArchived: result.conversationArchived
27509
27817
  });
27510
27818
  }
27511
- const pendingAction = getPendingClientAction(response);
27512
- if (pendingAction?.kind === "select_connections") {
27513
- const resolution = await this.resolveSelectConnections(
27514
- { conversationId, workspaceId },
27515
- pendingAction,
27516
- [],
27517
- this.interactive,
27518
- signal
27519
- );
27520
- if (resolution.kind === "resolved") {
27521
- nextIncomingMessage = resolution.continuation;
27522
- continue;
27523
- }
27524
- return this.completeRequiredConnectionAction(
27525
- conversationId,
27526
- assistantText,
27527
- resolution.action
27528
- );
27529
- }
27530
- if (pendingAction?.kind === "enable_push") {
27531
- return this.completeRequiredPushAction(
27532
- conversationId,
27533
- assistantText,
27534
- pendingAction
27535
- );
27819
+ if (result.outcome === "action_required" && result.pendingAction) {
27820
+ return this.completeRequiredAction(result, result.pendingAction);
27536
27821
  }
27537
27822
  if (!this.interactive) {
27538
27823
  return this.completeTurn({
27539
27824
  conversationId,
27540
- assistantText,
27825
+ assistantText: result.assistantText,
27541
27826
  status: "awaiting_input"
27542
27827
  });
27543
27828
  }
@@ -27545,17 +27830,76 @@ var ChatService = class {
27545
27830
  if (!userMessage || userMessage === "/exit") {
27546
27831
  return this.completeTurn({
27547
27832
  conversationId,
27548
- assistantText,
27833
+ assistantText: result.assistantText,
27549
27834
  status: "awaiting_input"
27550
27835
  });
27551
27836
  }
27552
27837
  markActivity();
27553
- nextIncomingMessage = createUserMessage(userMessage);
27838
+ nextInput = { message: userMessage };
27839
+ knownPendingAction = null;
27554
27840
  }
27555
27841
  } finally {
27556
27842
  if (heartbeat) clearInterval(heartbeat);
27557
27843
  }
27558
27844
  }
27845
+ async runTurn({ conversationId, workspaceId }, input2, signal, pendingAction, { markActivity }) {
27846
+ try {
27847
+ return await runConversationTurn({
27848
+ api: this.api,
27849
+ transport: this.transport,
27850
+ conversationId,
27851
+ workspaceId,
27852
+ input: input2,
27853
+ pendingAction,
27854
+ signal,
27855
+ onText: (text) => {
27856
+ markActivity();
27857
+ this.output.emit({ type: "assistant_text", conversationId, text });
27858
+ },
27859
+ onToolActivity: (activity) => {
27860
+ markActivity();
27861
+ this.output.emit({ type: "tool_activity", conversationId, ...activity });
27862
+ },
27863
+ onPublished: (automationId) => {
27864
+ this.output.emit({ type: "published", conversationId, automationId });
27865
+ },
27866
+ chooseConnection: this.interactive ? (requirement) => this.promptForConnection(requirement, signal) : void 0,
27867
+ authorizeConnection: async (requirement) => {
27868
+ if (this.interactive && !await this.confirmConnectionAuthorization(requirement, signal)) {
27869
+ return void 0;
27870
+ }
27871
+ return this.connectionAuthorizer.authorize(
27872
+ { ...requirement, conversationId },
27873
+ signal
27874
+ );
27875
+ }
27876
+ });
27877
+ } catch (error62) {
27878
+ if (error62 instanceof ChatTurnInputError) {
27879
+ throw new Error(describeInputError(error62));
27880
+ }
27881
+ throw error62;
27882
+ }
27883
+ }
27884
+ emitArchiveResult(result) {
27885
+ if (result.conversationArchived) {
27886
+ this.output.emit({
27887
+ type: "conversation_archived",
27888
+ conversationId: result.conversationId,
27889
+ state: "completed",
27890
+ terminal: false
27891
+ });
27892
+ return;
27893
+ }
27894
+ this.output.emit({
27895
+ type: "warning",
27896
+ code: "TDA_CHAT_ARCHIVE_FAILED",
27897
+ conversationId: result.conversationId,
27898
+ message: `The automation was published, but its chat could not be archived: ${result.conversationArchiveError}`,
27899
+ state: "warning",
27900
+ terminal: false
27901
+ });
27902
+ }
27559
27903
  completeTurn(summary) {
27560
27904
  const resumeCommand = getResumeCommand(summary);
27561
27905
  this.output.emit({
@@ -27570,66 +27914,23 @@ var ChatService = class {
27570
27914
  });
27571
27915
  return summary;
27572
27916
  }
27573
- completeRequiredConnectionAction(conversationId, assistantText, action) {
27917
+ completeRequiredAction(result, pendingAction) {
27918
+ const { conversationId } = result;
27919
+ const action = toRequiredActionPayload(pendingAction);
27574
27920
  this.output.emit({
27575
27921
  type: "action_required",
27576
27922
  conversationId,
27577
- action: "select_connections",
27578
- message: "Select or authorize the required service connections.",
27923
+ action: pendingAction.kind,
27924
+ message: pendingAction.kind === "select_connections" ? "Select or authorize the required service connections." : "Enable Todoist push notifications in a supported Todoist client.",
27579
27925
  ...action
27580
27926
  });
27581
27927
  return this.completeTurn({
27582
27928
  conversationId,
27583
- assistantText,
27929
+ assistantText: result.assistantText,
27584
27930
  status: "action_required",
27585
27931
  action
27586
27932
  });
27587
27933
  }
27588
- completeRequiredPushAction(conversationId, assistantText, action) {
27589
- const actionPayload = toActionPayload(action);
27590
- this.output.emit({
27591
- type: "action_required",
27592
- conversationId,
27593
- action: action.kind,
27594
- message: "Enable Todoist push notifications in a supported Todoist client.",
27595
- ...actionPayload
27596
- });
27597
- return this.completeTurn({
27598
- conversationId,
27599
- assistantText,
27600
- status: "action_required",
27601
- action: actionPayload
27602
- });
27603
- }
27604
- async archivePublishedConversation(conversationId, signal) {
27605
- try {
27606
- const conversation = await this.api.chat.updateConversation(
27607
- conversationId,
27608
- { isArchived: true },
27609
- { signal }
27610
- );
27611
- if (!conversation.isArchived) {
27612
- throw new Error("The Automations API returned an active conversation.");
27613
- }
27614
- this.output.emit({
27615
- type: "conversation_archived",
27616
- conversationId,
27617
- state: "completed",
27618
- terminal: false
27619
- });
27620
- return true;
27621
- } catch (error61) {
27622
- this.output.emit({
27623
- type: "warning",
27624
- code: "TDA_CHAT_ARCHIVE_FAILED",
27625
- conversationId,
27626
- message: `The automation was published, but its chat could not be archived: ${getErrorMessage6(error61)}`,
27627
- state: "warning",
27628
- terminal: false
27629
- });
27630
- return false;
27631
- }
27632
- }
27633
27934
  async withActiveTurn(conversationId, operation, onAcquired) {
27634
27935
  const release = await this.turnLock.acquire(conversationId);
27635
27936
  onAcquired?.();
@@ -27650,108 +27951,6 @@ var ChatService = class {
27650
27951
  const messages = await this.api.chat.getMessages(conversationId, { signal });
27651
27952
  return getPendingActionFromMessages(messages);
27652
27953
  }
27653
- async resolveSelectConnections({ conversationId, workspaceId }, action, selections, allowPrompt, signal) {
27654
- const uniqueConnections = deduplicateConnectionRequirements(action.connections);
27655
- const limitConnectionLookup = pLimit(CONNECTION_LOOKUP_CONCURRENCY);
27656
- const requirements = await Promise.all(
27657
- uniqueConnections.map(
27658
- (connection) => limitConnectionLookup(async () => {
27659
- const response = await this.api.connections.list(
27660
- {
27661
- connectorId: connection.connectorId,
27662
- capability: connection.connectionType,
27663
- status: "authorized"
27664
- },
27665
- { signal }
27666
- );
27667
- return {
27668
- ...connection,
27669
- availableConnections: response.connections.map((availableConnection) => ({
27670
- id: availableConnection.id,
27671
- label: availableConnection.accountDisplayLabel ?? availableConnection.name ?? availableConnection.id
27672
- }))
27673
- };
27674
- })
27675
- )
27676
- );
27677
- for (const selection of selections) {
27678
- if (selection.connectionType) continue;
27679
- const matchingTypes = new Set(
27680
- requirements.filter((requirement) => requirement.connectorId === selection.connectorId).map((requirement) => requirement.connectionType)
27681
- );
27682
- if (matchingTypes.size > 1) {
27683
- throw new Error(
27684
- `Connection selection for ${selection.connectorId} is ambiguous. Specify ${selection.connectorId}:mcp or ${selection.connectorId}:trigger.`
27685
- );
27686
- }
27687
- }
27688
- const resolved = [];
27689
- for (const requirement of requirements) {
27690
- const explicit = selections.find(
27691
- (selection) => selection.connectorId === requirement.connectorId && (!selection.connectionType || selection.connectionType === requirement.connectionType)
27692
- );
27693
- let connectionId = explicit?.connectionId;
27694
- if (connectionId) {
27695
- const exists = requirement.availableConnections.some(
27696
- (connection) => connection.id === connectionId
27697
- );
27698
- if (!exists) {
27699
- throw new Error(
27700
- `Connection ${connectionId} is not an authorized ${requirement.serviceName} connection.`
27701
- );
27702
- }
27703
- } else if (requirement.availableConnections.length === 1) {
27704
- connectionId = requirement.availableConnections[0]?.id;
27705
- } else if (allowPrompt && requirement.availableConnections.length > 1) {
27706
- connectionId = await this.promptForConnection(requirement, signal);
27707
- } else if (requirement.availableConnections.length === 0 && (!this.interactive || await this.confirmConnectionAuthorization(requirement, signal))) {
27708
- connectionId = await this.connectionAuthorizer.authorize(
27709
- { ...requirement, conversationId },
27710
- signal
27711
- );
27712
- }
27713
- if (!connectionId) {
27714
- return {
27715
- kind: "required",
27716
- action: {
27717
- toolCallId: action.toolCallId,
27718
- draftId: action.draftId,
27719
- requirements,
27720
- resume: requirements.some((item) => item.availableConnections.length === 0) ? "tda chat continue <conversation-id>" : "tda chat continue <conversation-id> --connection <connector-id>=<connection-id>"
27721
- }
27722
- };
27723
- }
27724
- resolved.push({ requirement, connectionId });
27725
- }
27726
- const output2 = [];
27727
- for (const item of resolved) {
27728
- const body = {
27729
- connectorId: item.requirement.connectorId,
27730
- connectionType: item.requirement.connectionType,
27731
- connectionId: item.connectionId
27732
- };
27733
- if (workspaceId === null) {
27734
- await this.api.automationDraftConnections.upsert(action.draftId, body, { signal });
27735
- } else {
27736
- await this.api.workspaceAutomationDraftConnections.upsert(
27737
- workspaceId,
27738
- action.draftId,
27739
- body,
27740
- { signal }
27741
- );
27742
- }
27743
- output2.push({
27744
- type: "success",
27745
- connectionId: item.connectionId,
27746
- connectorId: item.requirement.connectorId,
27747
- connectionType: item.requirement.connectionType
27748
- });
27749
- }
27750
- return {
27751
- kind: "resolved",
27752
- continuation: createSelectConnectionsContinuation(action, output2)
27753
- };
27754
- }
27755
27954
  async promptForConnection(requirement, signal) {
27756
27955
  const readline = this.getReadline();
27757
27956
  process.stdout.write(
@@ -27786,10 +27985,28 @@ No authorized ${sanitizeTerminalText(requirement.serviceName)} connection exists
27786
27985
  return this.readline;
27787
27986
  }
27788
27987
  };
27789
- function getPendingActionFromMessages(messages) {
27790
- const latestMessage = messages.at(-1);
27791
- if (!latestMessage || latestMessage.role !== "assistant") return null;
27792
- return getPendingClientAction(toUiMessage(latestMessage));
27988
+ function describeInputError(error62) {
27989
+ switch (error62.code) {
27990
+ case "awaiting_selection":
27991
+ return "Use either a message or --connection selections, not both.";
27992
+ case "not_awaiting_selection":
27993
+ return "The conversation is not waiting for connection selection.";
27994
+ case "input_required":
27995
+ return "A message or --connection selection is required to continue.";
27996
+ default:
27997
+ return error62.message;
27998
+ }
27999
+ }
28000
+ function toRequiredActionPayload(action) {
28001
+ if (action.kind === "enable_push") {
28002
+ return { toolCallId: action.toolCallId, draftId: action.draftId };
28003
+ }
28004
+ return {
28005
+ toolCallId: action.toolCallId,
28006
+ draftId: action.draftId,
28007
+ requirements: action.requirements,
28008
+ resume: action.requirements.some((item) => item.availableConnections.length === 0) ? "tda chat continue <conversation-id>" : "tda chat continue <conversation-id> --connection <connector-id>=<connection-id>"
28009
+ };
27793
28010
  }
27794
28011
  function toActionPayload(action) {
27795
28012
  if (action.kind === "select_connections") {
@@ -27917,8 +28134,8 @@ async function runCommand(command, operation) {
27917
28134
  assistantText: ""
27918
28135
  });
27919
28136
  },
27920
- onError: (error61, { mode, output: output2 }) => {
27921
- const failure2 = renderFailure(error61, { mode, source });
28137
+ onError: (error62, { mode, output: output2 }) => {
28138
+ const failure2 = renderFailure(error62, { mode, source });
27922
28139
  const message = mode === "human" ? failure2.humanMessage : failure2.message;
27923
28140
  output2.emit({
27924
28141
  type: "error",
@@ -28179,8 +28396,8 @@ async function runAuthorizationCommand(command, operation) {
28179
28396
  });
28180
28397
  output2.finish({ status: "interrupted", message: "Interrupted." });
28181
28398
  },
28182
- onError: (error61, { mode, output: output2 }) => {
28183
- const failure2 = renderFailure(error61, { mode, source });
28399
+ onError: (error62, { mode, output: output2 }) => {
28400
+ const failure2 = renderFailure(error62, { mode, source });
28184
28401
  const message = mode === "human" ? failure2.humanMessage : failure2.message;
28185
28402
  output2.emit({
28186
28403
  type: "error",
@@ -28223,10 +28440,10 @@ async function disconnectConnection(api, connectionId, { confirmed, force }, sig
28223
28440
  }
28224
28441
  try {
28225
28442
  await api.connections.delete(connectionId, { signal, force });
28226
- } catch (error61) {
28227
- const conflict = getConnectionInUseError(error61);
28443
+ } catch (error62) {
28444
+ const conflict = getConnectionInUseError(error62);
28228
28445
  if (!conflict) {
28229
- throw error61;
28446
+ throw error62;
28230
28447
  }
28231
28448
  const details = conflict.automations.map((automation) => `${automation.id} (${automation.name})`).join(", ");
28232
28449
  throw new Error(
@@ -28551,8 +28768,8 @@ async function runLocalCommand(command, operation, presentation, execution = {})
28551
28768
  const result = await withSpinner({ text: execution.spinner ?? "Loading..." }, operation);
28552
28769
  stopEarlySpinner();
28553
28770
  writeResult(mode, result, presentation);
28554
- } catch (error61) {
28555
- writeFailure(mode, "error", renderFailure(error61, { mode }));
28771
+ } catch (error62) {
28772
+ writeFailure(mode, "error", renderFailure(error62, { mode }));
28556
28773
  process.exitCode = 1;
28557
28774
  }
28558
28775
  }
@@ -28669,7 +28886,7 @@ async function updateAllSkills(options, command) {
28669
28886
  throw new CliError3(
28670
28887
  "UPDATE_FAILED",
28671
28888
  `Could not update ${result.errors.length} skill file(s).`,
28672
- { hints: result.errors.map((error61) => `${error61.agent}: ${error61.message}`) }
28889
+ { hints: result.errors.map((error62) => `${error62.agent}: ${error62.message}`) }
28673
28890
  );
28674
28891
  }
28675
28892
  return { action: "updated_all", ...result };
@@ -28866,9 +29083,9 @@ if (isEntrypoint()) {
28866
29083
  try {
28867
29084
  startEarlySpinner();
28868
29085
  await createProgram().parseAsync(process.argv);
28869
- } catch (error61) {
29086
+ } catch (error62) {
28870
29087
  stopEarlySpinner();
28871
- process.stderr.write(`error: ${formatError2(error61)}
29088
+ process.stderr.write(`error: ${formatError2(error62)}
28872
29089
  `);
28873
29090
  process.exitCode = 1;
28874
29091
  } finally {