@doist/automations-cli 1.18.0 → 1.20.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
@@ -7,7 +7,7 @@ import {
7
7
  collectSkillStatus,
8
8
  getInstaller,
9
9
  updateAllInstalledSkills
10
- } from "./chunk-DTY2LZDU.js";
10
+ } from "./chunk-23LIA37W.js";
11
11
 
12
12
  // ../../node_modules/ajv/dist/compile/codegen/code.js
13
13
  var require_code = __commonJS({
@@ -2868,7 +2868,7 @@ var require_compile = __commonJS({
2868
2868
  }
2869
2869
  };
2870
2870
  exports.SchemaEnv = SchemaEnv;
2871
- function compileSchema(sch) {
2871
+ function compileSchema2(sch) {
2872
2872
  const _sch = getCompilingSchema.call(this, sch);
2873
2873
  if (_sch)
2874
2874
  return _sch;
@@ -2953,29 +2953,29 @@ var require_compile = __commonJS({
2953
2953
  this._compilations.delete(sch);
2954
2954
  }
2955
2955
  }
2956
- exports.compileSchema = compileSchema;
2957
- function resolveRef2(root15, baseId, ref) {
2956
+ exports.compileSchema = compileSchema2;
2957
+ function resolveRef2(root16, baseId, ref) {
2958
2958
  var _a3;
2959
2959
  ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref);
2960
- const schOrFunc = root15.refs[ref];
2960
+ const schOrFunc = root16.refs[ref];
2961
2961
  if (schOrFunc)
2962
2962
  return schOrFunc;
2963
- let _sch = resolve.call(this, root15, ref);
2963
+ let _sch = resolve.call(this, root16, ref);
2964
2964
  if (_sch === void 0) {
2965
- const schema = (_a3 = root15.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2965
+ const schema = (_a3 = root16.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
2966
2966
  const { schemaId } = this.opts;
2967
2967
  if (schema)
2968
- _sch = new SchemaEnv({ schema, schemaId, root: root15, baseId });
2968
+ _sch = new SchemaEnv({ schema, schemaId, root: root16, baseId });
2969
2969
  }
2970
2970
  if (_sch === void 0)
2971
2971
  return;
2972
- return root15.refs[ref] = inlineOrCompile.call(this, _sch);
2972
+ return root16.refs[ref] = inlineOrCompile.call(this, _sch);
2973
2973
  }
2974
2974
  exports.resolveRef = resolveRef2;
2975
2975
  function inlineOrCompile(sch) {
2976
2976
  if ((0, resolve_1.inlineRef)(sch.schema, this.opts.inlineRefs))
2977
2977
  return sch.schema;
2978
- return sch.validate ? sch : compileSchema.call(this, sch);
2978
+ return sch.validate ? sch : compileSchema2.call(this, sch);
2979
2979
  }
2980
2980
  function getCompilingSchema(schEnv) {
2981
2981
  for (const sch of this._compilations) {
@@ -2987,23 +2987,23 @@ var require_compile = __commonJS({
2987
2987
  function sameSchemaEnv(s1, s2) {
2988
2988
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
2989
2989
  }
2990
- function resolve(root15, ref) {
2990
+ function resolve(root16, ref) {
2991
2991
  let sch;
2992
2992
  while (typeof (sch = this.refs[ref]) == "string")
2993
2993
  ref = sch;
2994
- return sch || this.schemas[ref] || resolveSchema.call(this, root15, ref);
2994
+ return sch || this.schemas[ref] || resolveSchema.call(this, root16, ref);
2995
2995
  }
2996
- function resolveSchema(root15, ref) {
2996
+ function resolveSchema(root16, ref) {
2997
2997
  const p = this.opts.uriResolver.parse(ref);
2998
2998
  const refPath = (0, resolve_1._getFullPath)(this.opts.uriResolver, p);
2999
- let baseId = (0, resolve_1.getFullPath)(this.opts.uriResolver, root15.baseId, void 0);
3000
- if (Object.keys(root15.schema).length > 0 && refPath === baseId) {
3001
- return getJsonPointer.call(this, p, root15);
2999
+ let baseId = (0, resolve_1.getFullPath)(this.opts.uriResolver, root16.baseId, void 0);
3000
+ if (Object.keys(root16.schema).length > 0 && refPath === baseId) {
3001
+ return getJsonPointer.call(this, p, root16);
3002
3002
  }
3003
3003
  const id = (0, resolve_1.normalizeId)(refPath);
3004
3004
  const schOrRef = this.refs[id] || this.schemas[id];
3005
3005
  if (typeof schOrRef == "string") {
3006
- const sch = resolveSchema.call(this, root15, schOrRef);
3006
+ const sch = resolveSchema.call(this, root16, schOrRef);
3007
3007
  if (typeof (sch === null || sch === void 0 ? void 0 : sch.schema) !== "object")
3008
3008
  return;
3009
3009
  return getJsonPointer.call(this, p, sch);
@@ -3011,14 +3011,14 @@ var require_compile = __commonJS({
3011
3011
  if (typeof (schOrRef === null || schOrRef === void 0 ? void 0 : schOrRef.schema) !== "object")
3012
3012
  return;
3013
3013
  if (!schOrRef.validate)
3014
- compileSchema.call(this, schOrRef);
3014
+ compileSchema2.call(this, schOrRef);
3015
3015
  if (id === (0, resolve_1.normalizeId)(ref)) {
3016
3016
  const { schema } = schOrRef;
3017
3017
  const { schemaId } = this.opts;
3018
3018
  const schId = schema[schemaId];
3019
3019
  if (schId)
3020
3020
  baseId = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schId);
3021
- return new SchemaEnv({ schema, schemaId, root: root15, baseId });
3021
+ return new SchemaEnv({ schema, schemaId, root: root16, baseId });
3022
3022
  }
3023
3023
  return getJsonPointer.call(this, p, schOrRef);
3024
3024
  }
@@ -3030,7 +3030,7 @@ var require_compile = __commonJS({
3030
3030
  "dependencies",
3031
3031
  "definitions"
3032
3032
  ]);
3033
- function getJsonPointer(parsedRef, { baseId, schema, root: root15 }) {
3033
+ function getJsonPointer(parsedRef, { baseId, schema, root: root16 }) {
3034
3034
  var _a3;
3035
3035
  if (((_a3 = parsedRef.fragment) === null || _a3 === void 0 ? void 0 : _a3[0]) !== "/")
3036
3036
  return;
@@ -3049,10 +3049,10 @@ var require_compile = __commonJS({
3049
3049
  let env;
3050
3050
  if (typeof schema != "boolean" && schema.$ref && !(0, util_1.schemaHasRulesButRef)(schema, this.RULES)) {
3051
3051
  const $ref = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, schema.$ref);
3052
- env = resolveSchema.call(this, root15, $ref);
3052
+ env = resolveSchema.call(this, root16, $ref);
3053
3053
  }
3054
3054
  const { schemaId } = this.opts;
3055
- env = env || new SchemaEnv({ schema, schemaId, root: root15, baseId });
3055
+ env = env || new SchemaEnv({ schema, schemaId, root: root16, baseId });
3056
3056
  if (env.schema !== env.root.schema)
3057
3057
  return env;
3058
3058
  return void 0;
@@ -4033,7 +4033,7 @@ var require_core = __commonJS({
4033
4033
  uriResolver
4034
4034
  };
4035
4035
  }
4036
- var Ajv = class {
4036
+ var Ajv2 = class {
4037
4037
  constructor(opts = {}) {
4038
4038
  this.schemas = {};
4039
4039
  this.refs = {};
@@ -4207,8 +4207,8 @@ var require_core = __commonJS({
4207
4207
  keyRef = sch;
4208
4208
  if (sch === void 0) {
4209
4209
  const { schemaId } = this.opts;
4210
- const root15 = new compile_1.SchemaEnv({ schema: {}, schemaId });
4211
- sch = compile_1.resolveSchema.call(this, root15, keyRef);
4210
+ const root16 = new compile_1.SchemaEnv({ schema: {}, schemaId });
4211
+ sch = compile_1.resolveSchema.call(this, root16, keyRef);
4212
4212
  if (!sch)
4213
4213
  return;
4214
4214
  this.refs[keyRef] = sch;
@@ -4317,7 +4317,7 @@ var require_core = __commonJS({
4317
4317
  errorsText(errors = this.errors, { separator = ", ", dataVar = "data" } = {}) {
4318
4318
  if (!errors || errors.length === 0)
4319
4319
  return "No errors";
4320
- return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((text, msg) => text + separator + msg);
4320
+ return errors.map((e) => `${dataVar}${e.instancePath} ${e.message}`).reduce((text2, msg) => text2 + separator + msg);
4321
4321
  }
4322
4322
  $dataMetaSchema(metaSchema, keywordsJsonPointers) {
4323
4323
  const rules = this.RULES.all;
@@ -4403,9 +4403,9 @@ var require_core = __commonJS({
4403
4403
  }
4404
4404
  }
4405
4405
  };
4406
- Ajv.ValidationError = validation_error_1.default;
4407
- Ajv.MissingRefError = ref_error_1.default;
4408
- exports.default = Ajv;
4406
+ Ajv2.ValidationError = validation_error_1.default;
4407
+ Ajv2.MissingRefError = ref_error_1.default;
4408
+ exports.default = Ajv2;
4409
4409
  function checkOptions(checkOpts, options, msg, log = "error") {
4410
4410
  for (const key in checkOpts) {
4411
4411
  const opt = key;
@@ -4569,20 +4569,20 @@ var require_ref = __commonJS({
4569
4569
  code(cxt) {
4570
4570
  const { gen, schema: $ref, it } = cxt;
4571
4571
  const { baseId, schemaEnv: env, validateName, opts, self } = it;
4572
- const { root: root15 } = env;
4573
- if (($ref === "#" || $ref === "#/") && baseId === root15.baseId)
4572
+ const { root: root16 } = env;
4573
+ if (($ref === "#" || $ref === "#/") && baseId === root16.baseId)
4574
4574
  return callRootRef();
4575
- const schOrEnv = compile_1.resolveRef.call(self, root15, baseId, $ref);
4575
+ const schOrEnv = compile_1.resolveRef.call(self, root16, baseId, $ref);
4576
4576
  if (schOrEnv === void 0)
4577
4577
  throw new ref_error_1.default(it.opts.uriResolver, baseId, $ref);
4578
4578
  if (schOrEnv instanceof compile_1.SchemaEnv)
4579
4579
  return callValidate(schOrEnv);
4580
4580
  return inlineRefSchema(schOrEnv);
4581
4581
  function callRootRef() {
4582
- if (env === root15)
4582
+ if (env === root16)
4583
4583
  return callRef(cxt, validateName, env, env.$async);
4584
- const rootName = gen.scopeValue("root", { ref: root15 });
4585
- return callRef(cxt, (0, codegen_1._)`${rootName}.validate`, root15, root15.$async);
4584
+ const rootName = gen.scopeValue("root", { ref: root16 });
4585
+ return callRef(cxt, (0, codegen_1._)`${rootName}.validate`, root16, root16.$async);
4586
4586
  }
4587
4587
  function callValidate(sch) {
4588
4588
  const v = getValidate(cxt, sch);
@@ -6516,7 +6516,7 @@ var require_ajv = __commonJS({
6516
6516
  var draft7MetaSchema = require_json_schema_draft_07();
6517
6517
  var META_SUPPORT_DATA = ["/properties"];
6518
6518
  var META_SCHEMA_ID = "http://json-schema.org/draft-07/schema";
6519
- var Ajv = class extends core_1.default {
6519
+ var Ajv2 = class extends core_1.default {
6520
6520
  _addVocabularies() {
6521
6521
  super._addVocabularies();
6522
6522
  draft7_1.default.forEach((v) => this.addVocabulary(v));
@@ -6535,11 +6535,11 @@ var require_ajv = __commonJS({
6535
6535
  return this.opts.defaultMeta = super.defaultMeta() || (this.getSchema(META_SCHEMA_ID) ? META_SCHEMA_ID : void 0);
6536
6536
  }
6537
6537
  };
6538
- exports.Ajv = Ajv;
6539
- module.exports = exports = Ajv;
6540
- module.exports.Ajv = Ajv;
6538
+ exports.Ajv = Ajv2;
6539
+ module.exports = exports = Ajv2;
6540
+ module.exports.Ajv = Ajv2;
6541
6541
  Object.defineProperty(exports, "__esModule", { value: true });
6542
- exports.default = Ajv;
6542
+ exports.default = Ajv2;
6543
6543
  var validate_1 = require_validate();
6544
6544
  Object.defineProperty(exports, "KeywordCxt", { enumerable: true, get: function() {
6545
6545
  return validate_1.KeywordCxt;
@@ -6899,7 +6899,7 @@ import { fileURLToPath } from "node:url";
6899
6899
  // package.json
6900
6900
  var package_default = {
6901
6901
  name: "@doist/automations-cli",
6902
- version: "1.18.0",
6902
+ version: "1.20.0",
6903
6903
  description: "Command-line client for Todoist Automations",
6904
6904
  type: "module",
6905
6905
  bin: {
@@ -11206,7 +11206,7 @@ function handleIntersectionResults(result, left, right) {
11206
11206
  const unrecKeys = /* @__PURE__ */ new Map();
11207
11207
  let unrecIssue;
11208
11208
  const keyIssues = /* @__PURE__ */ new Map();
11209
- const collect3 = (iss, side) => {
11209
+ const collect2 = (iss, side) => {
11210
11210
  let keys;
11211
11211
  if (iss.code === "unrecognized_keys" && !iss.path?.length) {
11212
11212
  unrecIssue ?? (unrecIssue = iss);
@@ -11227,11 +11227,11 @@ function handleIntersectionResults(result, left, right) {
11227
11227
  return true;
11228
11228
  };
11229
11229
  for (const iss of left.issues) {
11230
- if (!collect3(iss, "l"))
11230
+ if (!collect2(iss, "l"))
11231
11231
  result.issues.push(iss);
11232
11232
  }
11233
11233
  for (const iss of right.issues) {
11234
- if (!collect3(iss, "r"))
11234
+ if (!collect2(iss, "r"))
11235
11235
  result.issues.push(iss);
11236
11236
  }
11237
11237
  const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
@@ -16534,8 +16534,8 @@ function ko_default() {
16534
16534
  }
16535
16535
 
16536
16536
  // ../../node_modules/zod/v4/locales/lt.js
16537
- var capitalizeFirstCharacter = (text) => {
16538
- return text.charAt(0).toUpperCase() + text.slice(1);
16537
+ var capitalizeFirstCharacter = (text2) => {
16538
+ return text2.charAt(0).toUpperCase() + text2.slice(1);
16539
16539
  };
16540
16540
  function getUnitTypeFromNumber(number4) {
16541
16541
  const abs = Math.abs(number4);
@@ -22892,8 +22892,8 @@ function encodeJSONPointerSegment(segment) {
22892
22892
  return segment.replace(/~/g, "~0").replace(/\//g, "~1");
22893
22893
  }
22894
22894
  function extractDefs(ctx, schema) {
22895
- const root15 = ctx.seen.get(schema);
22896
- if (!root15)
22895
+ const root16 = ctx.seen.get(schema);
22896
+ if (!root16)
22897
22897
  throw new Error("Unprocessed schema. This is a bug in Zod.");
22898
22898
  if (ctx.external && ctx.sharedDefsExtractedFor === ctx.external)
22899
22899
  return;
@@ -22922,7 +22922,7 @@ function extractDefs(ctx, schema) {
22922
22922
  }
22923
22923
  const uriPrefix = `#`;
22924
22924
  const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
22925
- if (entry[1] === root15 && !entry[1].schema.id) {
22925
+ if (entry[1] === root16 && !entry[1].schema.id) {
22926
22926
  return { ref: uriPrefix };
22927
22927
  }
22928
22928
  const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`;
@@ -23093,8 +23093,8 @@ function foldIntersection(json2) {
23093
23093
  assignProps(json2, folded);
23094
23094
  }
23095
23095
  function finalize(ctx, schema) {
23096
- const root15 = ctx.seen.get(schema);
23097
- if (!root15)
23096
+ const root16 = ctx.seen.get(schema);
23097
+ if (!root16)
23098
23098
  throw new Error("Unprocessed schema. This is a bug in Zod.");
23099
23099
  const flattenRef = (zodSchema) => {
23100
23100
  const seen = ctx.seen.get(zodSchema);
@@ -23205,7 +23205,7 @@ function finalize(ctx, schema) {
23205
23205
  throw new Error("Schema is missing an `id` property");
23206
23206
  result.$id = ctx.external.uri(id);
23207
23207
  }
23208
- assignProps(result, root15.defId ? root15.schema : root15.def ?? root15.schema);
23208
+ assignProps(result, root16.defId ? root16.schema : root16.def ?? root16.schema);
23209
23209
  const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
23210
23210
  if (rootMetaId !== void 0 && result.id === rootMetaId)
23211
23211
  delete result.id;
@@ -27859,6 +27859,9 @@ function hasTriggerType(value) {
27859
27859
  function isManifestRecord(value) {
27860
27860
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
27861
27861
  }
27862
+ function isStepWithTools(step) {
27863
+ return "tools" in step && step.tools != null && typeof step.tools === "object";
27864
+ }
27862
27865
  function isStringTypedSchema(schema) {
27863
27866
  if (!schema)
27864
27867
  return false;
@@ -27914,6 +27917,180 @@ function resolvePropertySchemaInSchema(schema, propertyPath) {
27914
27917
  return null;
27915
27918
  return resolvePropertySchemaInSchema(propertySchema, remainingPath);
27916
27919
  }
27920
+ function parseWebhookTriggerConnector(trigger) {
27921
+ if (trigger.type !== "webhook")
27922
+ return null;
27923
+ const triggerEventId = trigger.event;
27924
+ if (typeof triggerEventId !== "string")
27925
+ return null;
27926
+ const connectorId = triggerEventId.split(".")[0];
27927
+ return connectorId ? { connectorId, triggerEventId } : null;
27928
+ }
27929
+ function getWebhookTriggerConnectors(manifest) {
27930
+ const triggers = getManifestTriggers(manifest);
27931
+ const results = [];
27932
+ for (const trigger of triggers) {
27933
+ const parsed = parseWebhookTriggerConnector(trigger);
27934
+ if (parsed) {
27935
+ results.push(parsed);
27936
+ }
27937
+ }
27938
+ return results;
27939
+ }
27940
+ function getRequiredConnectorsFromManifest(manifest) {
27941
+ const requirements = /* @__PURE__ */ new Map();
27942
+ if (manifest.steps) {
27943
+ for (const step of manifest.steps) {
27944
+ if (!isStepWithTools(step))
27945
+ continue;
27946
+ for (const connectorName of Object.keys(step.tools)) {
27947
+ if (!requirements.has(connectorName)) {
27948
+ requirements.set(connectorName, /* @__PURE__ */ new Set());
27949
+ }
27950
+ requirements.get(connectorName)?.add("mcp");
27951
+ }
27952
+ }
27953
+ }
27954
+ for (const { connectorId } of getWebhookTriggerConnectors(manifest)) {
27955
+ if (!requirements.has(connectorId)) {
27956
+ requirements.set(connectorId, /* @__PURE__ */ new Set());
27957
+ }
27958
+ requirements.get(connectorId)?.add("trigger");
27959
+ }
27960
+ return requirements;
27961
+ }
27962
+ function formatScheduleTime(hour, minute, timeFormat) {
27963
+ return new Intl.DateTimeFormat("en-US", {
27964
+ hour: timeFormat === "24h" ? "2-digit" : "numeric",
27965
+ minute: "2-digit",
27966
+ hour12: timeFormat !== "24h",
27967
+ hourCycle: timeFormat === "24h" ? "h23" : "h12",
27968
+ timeZone: "UTC"
27969
+ }).format(new Date(Date.UTC(2024, 0, 1, hour, minute)));
27970
+ }
27971
+ function parseIntegerToken(value, min, max) {
27972
+ if (!/^\d+$/.test(value)) {
27973
+ return null;
27974
+ }
27975
+ const parsed = Number(value);
27976
+ if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
27977
+ return null;
27978
+ }
27979
+ return parsed;
27980
+ }
27981
+ function parseSimpleDayOfWeekList(value) {
27982
+ if (!/^\d(?:,\d)*$/.test(value)) {
27983
+ return null;
27984
+ }
27985
+ const parsed = value.split(",").map((token) => parseIntegerToken(token, 0, 6)).filter((token) => token != null);
27986
+ if (parsed.length === 0 || parsed.length !== new Set(parsed).size) {
27987
+ return null;
27988
+ }
27989
+ return [...parsed].sort((left, right) => left - right);
27990
+ }
27991
+ function formatList(values) {
27992
+ if (values.length <= 1) {
27993
+ return values[0] ?? "";
27994
+ }
27995
+ if (values.length === 2) {
27996
+ return `${values[0]} and ${values[1]}`;
27997
+ }
27998
+ return `${values.slice(0, -1).join(", ")}, and ${values.at(-1)}`;
27999
+ }
28000
+ function formatOrdinal(value) {
28001
+ const remainder100 = value % 100;
28002
+ if (remainder100 >= 11 && remainder100 <= 13) {
28003
+ return `${value}th`;
28004
+ }
28005
+ switch (value % 10) {
28006
+ case 1:
28007
+ return `${value}st`;
28008
+ case 2:
28009
+ return `${value}nd`;
28010
+ case 3:
28011
+ return `${value}rd`;
28012
+ default:
28013
+ return `${value}th`;
28014
+ }
28015
+ }
28016
+ function formatDuration(value) {
28017
+ const match = value.match(/^(\d+)(ms|s|m|h|d|w)$/);
28018
+ if (!match) {
28019
+ return value;
28020
+ }
28021
+ const [, rawAmount, unit] = match;
28022
+ const amount = Number(rawAmount);
28023
+ const unitLabelMap = {
28024
+ ms: amount === 1 ? "millisecond" : "milliseconds",
28025
+ s: amount === 1 ? "second" : "seconds",
28026
+ m: amount === 1 ? "minute" : "minutes",
28027
+ h: amount === 1 ? "hour" : "hours",
28028
+ d: amount === 1 ? "day" : "days",
28029
+ w: amount === 1 ? "week" : "weeks"
28030
+ };
28031
+ return `${amount} ${unitLabelMap[unit]}`;
28032
+ }
28033
+ function describeIntervalSchedule(value) {
28034
+ if (!value.includes("/")) {
28035
+ return `Runs every ${formatDuration(value)}`;
28036
+ }
28037
+ const [offset, interval] = value.split("/");
28038
+ if (!offset || !interval) {
28039
+ return `Runs on schedule: ${value}`;
28040
+ }
28041
+ return `Runs every ${formatDuration(interval)}, starting ${formatDuration(offset)} after activation`;
28042
+ }
28043
+ function describeCronSchedule(value, timeFormat) {
28044
+ const [minute, hour, dayOfMonth, month, dayOfWeek, extra] = value.expression.trim().split(/\s+/);
28045
+ if (!minute || !hour || !dayOfMonth || !month || !dayOfWeek || extra) {
28046
+ return `Runs on cron schedule ${value.expression} (${value.timezone})`;
28047
+ }
28048
+ const minuteNumber = parseIntegerToken(minute, 0, 59);
28049
+ const hourNumber = parseIntegerToken(hour, 0, 23);
28050
+ if (minuteNumber == null || hourNumber == null || month !== "*") {
28051
+ return `Runs on cron schedule ${value.expression} (${value.timezone})`;
28052
+ }
28053
+ const time3 = formatScheduleTime(hourNumber, minuteNumber, timeFormat);
28054
+ const timezone = value.timezone;
28055
+ const weekdayNames = [
28056
+ "Sunday",
28057
+ "Monday",
28058
+ "Tuesday",
28059
+ "Wednesday",
28060
+ "Thursday",
28061
+ "Friday",
28062
+ "Saturday"
28063
+ ];
28064
+ if (dayOfMonth === "*" && dayOfWeek === "*") {
28065
+ return `Runs every day at ${time3} in ${timezone}`;
28066
+ }
28067
+ if (dayOfMonth === "*" && dayOfWeek === "1-5") {
28068
+ return `Runs every weekday at ${time3} in ${timezone}`;
28069
+ }
28070
+ if (dayOfMonth === "*") {
28071
+ const daysOfWeek = parseSimpleDayOfWeekList(dayOfWeek);
28072
+ if (!daysOfWeek || daysOfWeek.length === 0) {
28073
+ return `Runs on cron schedule ${value.expression} (${value.timezone})`;
28074
+ }
28075
+ const dayNames = daysOfWeek.map((day) => weekdayNames[day] ?? String(day));
28076
+ return `Runs every ${formatList(dayNames)} at ${time3} in ${timezone}`;
28077
+ }
28078
+ if (dayOfWeek === "*") {
28079
+ const numericDayOfMonth = parseIntegerToken(dayOfMonth, 1, 31);
28080
+ if (numericDayOfMonth == null) {
28081
+ return `Runs on cron schedule ${value.expression} (${value.timezone})`;
28082
+ }
28083
+ return `Runs every month on the ${formatOrdinal(numericDayOfMonth)} at ${time3} in ${timezone}`;
28084
+ }
28085
+ return `Runs on cron schedule ${value.expression} (${value.timezone})`;
28086
+ }
28087
+ function getScheduleTriggerDescription(params) {
28088
+ const { value, timeFormat } = params;
28089
+ if (typeof value === "string") {
28090
+ return describeIntervalSchedule(value);
28091
+ }
28092
+ return describeCronSchedule(value, timeFormat);
28093
+ }
27917
28094
 
27918
28095
  // ../../packages/core/dist/esm/schemas/manifest.schema.js
27919
28096
  var uuidv7Regex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-7[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/i;
@@ -28289,9 +28466,9 @@ var partialManifestSchema = manifestSchemaBase.partial().extend({
28289
28466
  var templateVariableRegex = /\{\{\s*[\w.]+\s*\}\}/g;
28290
28467
  var codeStepReferenceRegex = /\bsteps\.([a-zA-Z][a-zA-Z0-9]*)(?:\.([a-zA-Z_][\w.]*))?/g;
28291
28468
  var backtickStepReferenceRegex = /`steps\.([a-zA-Z][a-zA-Z0-9]*)(?:\.([a-zA-Z_][\w.]*))?`/g;
28292
- function extractStepReferences(text, regex) {
28469
+ function extractStepReferences(text2, regex) {
28293
28470
  const references = [];
28294
- for (const match of text.matchAll(regex)) {
28471
+ for (const match of text2.matchAll(regex)) {
28295
28472
  const stepId = match[1];
28296
28473
  if (!stepId)
28297
28474
  continue;
@@ -28337,8 +28514,8 @@ function validateTemplateVariable({ variable, context, stepId, currentStepGuard,
28337
28514
  if (parts.length === 0) {
28338
28515
  return null;
28339
28516
  }
28340
- const [root15, ...rest] = parts;
28341
- if (root15 === "trigger") {
28517
+ const [root16, ...rest] = parts;
28518
+ if (root16 === "trigger") {
28342
28519
  if (rest.length === 0) {
28343
28520
  return `Step "${stepId}" ${sourceType} references "{{trigger}}" without a property. Use {{trigger.<property>}} syntax (e.g., {{trigger.payload}}, {{trigger.metadata}}).`;
28344
28521
  }
@@ -28361,7 +28538,7 @@ function validateTemplateVariable({ variable, context, stepId, currentStepGuard,
28361
28538
  }
28362
28539
  return null;
28363
28540
  }
28364
- if (root15 === "steps") {
28541
+ if (root16 === "steps") {
28365
28542
  const referencedStepId = rest[0];
28366
28543
  if (!referencedStepId) {
28367
28544
  return `Step "${stepId}" ${sourceType} references "steps" but is missing the step identifier in template variable "{{${variable}}}". Use {{steps.<stepId>}} syntax.`;
@@ -28940,6 +29117,8 @@ var automationSchema = external_exports.object({
28940
29117
  draftId: external_exports.string().nullable(),
28941
29118
  manifest: external_exports.union([manifestSchema, external_exports.record(external_exports.string(), external_exports.unknown())]).nullable(),
28942
29119
  updatedAt: external_exports.iso.datetime(),
29120
+ // The person who created the automation; null only from an API instance that predates it.
29121
+ createdBy: RolloutCompatibleNullableStringSchema,
28943
29122
  // The last person who changed the automation; null until someone has.
28944
29123
  updatedBy: RolloutCompatibleNullableStringSchema,
28945
29124
  // null means the automation belongs to the creator's personal space
@@ -29148,6 +29327,17 @@ var finalizeAutomationDraftResponseSchema = external_exports.object({
29148
29327
  var testAutomationDraftResponseSchema = external_exports.object({
29149
29328
  success: external_exports.literal(true)
29150
29329
  });
29330
+ var AUTOMATION_OPEN_DRAFT_CONFLICT_CODE = "automation_open_draft_conflict";
29331
+ var AutomationOpenDraftConflictSchema = external_exports.object({
29332
+ code: external_exports.literal(AUTOMATION_OPEN_DRAFT_CONFLICT_CODE),
29333
+ message: external_exports.string(),
29334
+ draftId: external_exports.string()
29335
+ });
29336
+ var AUTOMATION_DRAFT_NOT_READY_CODE = "automation_draft_not_ready";
29337
+ var AutomationDraftNotReadySchema = external_exports.object({
29338
+ code: external_exports.literal(AUTOMATION_DRAFT_NOT_READY_CODE),
29339
+ message: external_exports.string()
29340
+ });
29151
29341
 
29152
29342
  // ../../packages/core/dist/esm/schemas/automation-draft-connection.schema.js
29153
29343
  var CreateAutomationDraftConnectionSchema = external_exports.object({
@@ -29791,7 +29981,143 @@ function assertKnownTimezone(timezone) {
29791
29981
  }
29792
29982
 
29793
29983
  // ../../packages/core/dist/esm/schemas/manifest.validation.js
29984
+ var import_ajv = __toESM(require_ajv(), 1);
29794
29985
  var import_ajv_formats = __toESM(require_dist(), 1);
29986
+ function validateManifest(manifest) {
29987
+ const allErrors = [];
29988
+ try {
29989
+ const validatedManifest = manifestSchema.parse(manifest);
29990
+ const triggerValidation = validateTriggerSchemas(validatedManifest);
29991
+ if (!triggerValidation.isValid) {
29992
+ allErrors.push(...triggerValidation.errors);
29993
+ }
29994
+ const stepValidation = validateStepSchemas(validatedManifest);
29995
+ if (!stepValidation.isValid) {
29996
+ allErrors.push(...stepValidation.errors);
29997
+ }
29998
+ const payloadValidation = validateWebhookPayloadStructure(validatedManifest);
29999
+ if (!payloadValidation.isValid) {
30000
+ allErrors.push(...payloadValidation.errors);
30001
+ }
30002
+ return {
30003
+ isValid: allErrors.length === 0,
30004
+ errors: allErrors
30005
+ };
30006
+ } catch (error62) {
30007
+ if (error62 instanceof external_exports.ZodError) {
30008
+ const zodErrors = error62.issues.map((err) => `${err.path.join(".")}: ${err.message}`);
30009
+ return { isValid: false, errors: zodErrors };
30010
+ }
30011
+ const message = error62 instanceof Error ? error62.message : "Unknown validation error";
30012
+ return { isValid: false, errors: [message] };
30013
+ }
30014
+ }
30015
+ function validatePartialManifest(manifest) {
30016
+ try {
30017
+ const data = partialManifestSchema.parse(manifest);
30018
+ return { isValid: true, errors: [], data };
30019
+ } catch (error62) {
30020
+ if (error62 instanceof external_exports.ZodError) {
30021
+ const errors = error62.issues.map((err) => `${err.path.join(".")}: ${err.message}`);
30022
+ return { isValid: false, errors };
30023
+ }
30024
+ const message = error62 instanceof Error ? error62.message : "Unknown validation error";
30025
+ return { isValid: false, errors: [message] };
30026
+ }
30027
+ }
30028
+ function compileSchema(schema, schemaName) {
30029
+ const ajv = new import_ajv.Ajv({ strict: true, validateFormats: true });
30030
+ import_ajv_formats.default.default(ajv);
30031
+ try {
30032
+ ajv.compile(schema);
30033
+ return { isValid: true };
30034
+ } catch (error62) {
30035
+ const message = error62 instanceof Error ? error62.message : String(error62);
30036
+ return {
30037
+ isValid: false,
30038
+ error: `${schemaName} is invalid JSON Schema: ${message}. Common issue: when using array keywords like "contains", you must explicitly declare "type": "array".`
30039
+ };
30040
+ }
30041
+ }
30042
+ function validateTriggerSchemas(manifest) {
30043
+ const errors = [];
30044
+ const triggers = getManifestTriggers(manifest);
30045
+ if (triggers.length === 0) {
30046
+ return { isValid: true, errors: [] };
30047
+ }
30048
+ for (const trigger of triggers) {
30049
+ if (trigger.type === "webhook" || trigger.type === "api") {
30050
+ const triggerLabel = trigger.type === "webhook" ? `Webhook trigger (${trigger.type === "webhook" ? trigger.event : ""})` : "API trigger";
30051
+ const outputResult = compileSchema(trigger.outputSchema, `${triggerLabel} outputSchema`);
30052
+ if (!outputResult.isValid && outputResult.error) {
30053
+ errors.push(outputResult.error);
30054
+ }
30055
+ if (trigger.inputSchema) {
30056
+ const inputResult = compileSchema(trigger.inputSchema, `${triggerLabel} inputSchema`);
30057
+ if (!inputResult.isValid && inputResult.error) {
30058
+ errors.push(inputResult.error);
30059
+ }
30060
+ }
30061
+ }
30062
+ }
30063
+ return {
30064
+ isValid: errors.length === 0,
30065
+ errors
30066
+ };
30067
+ }
30068
+ function validateStepSchemas(manifest) {
30069
+ const errors = [];
30070
+ if (!manifest.steps || !Array.isArray(manifest.steps)) {
30071
+ return { isValid: true, errors: [] };
30072
+ }
30073
+ for (const step of manifest.steps) {
30074
+ const outputResult = compileSchema(step.outputSchema, `Step "${step.id}" outputSchema`);
30075
+ if (!outputResult.isValid && outputResult.error) {
30076
+ errors.push(outputResult.error);
30077
+ }
30078
+ if (step.exitOn) {
30079
+ const exitOnResult = compileSchema(step.exitOn, `Step "${step.id}" exitOn`);
30080
+ if (!exitOnResult.isValid && exitOnResult.error) {
30081
+ errors.push(exitOnResult.error);
30082
+ }
30083
+ }
30084
+ }
30085
+ return {
30086
+ isValid: errors.length === 0,
30087
+ errors
30088
+ };
30089
+ }
30090
+ function validateWebhookPayloadStructure(manifest) {
30091
+ const errors = [];
30092
+ const triggers = getManifestTriggers(manifest);
30093
+ const webhookTriggers = triggers.filter((t) => t.type === "webhook");
30094
+ if (webhookTriggers.length === 0) {
30095
+ return { isValid: true, errors: [] };
30096
+ }
30097
+ for (const trigger of webhookTriggers) {
30098
+ if (trigger.type !== "webhook")
30099
+ continue;
30100
+ const eventLabel = trigger.event;
30101
+ const triggerOutputSchema = trigger.outputSchema;
30102
+ if (!triggerOutputSchema) {
30103
+ errors.push(`Webhook trigger "${eventLabel}" is missing outputSchema`);
30104
+ continue;
30105
+ }
30106
+ if (!triggerOutputSchema.properties || typeof triggerOutputSchema.properties !== "object") {
30107
+ errors.push(`Webhook trigger "${eventLabel}" outputSchema must have a "properties" field with a "payload" object. The webhook event data is wrapped in a payload field.`);
30108
+ continue;
30109
+ }
30110
+ const payloadSchema = triggerOutputSchema.properties.payload;
30111
+ if (!payloadSchema || typeof payloadSchema !== "object") {
30112
+ errors.push(`Webhook trigger "${eventLabel}" outputSchema must have a "payload" property. All webhook event data is wrapped in { payload: {...}, metadata: {...} }.`);
30113
+ continue;
30114
+ }
30115
+ if (!Array.isArray(triggerOutputSchema.required) || !triggerOutputSchema.required.includes("payload")) {
30116
+ errors.push(`Webhook trigger "${eventLabel}" outputSchema must include "payload" in the "required" array. The payload wrapper is mandatory.`);
30117
+ }
30118
+ }
30119
+ return { isValid: errors.length === 0, errors };
30120
+ }
29795
30121
 
29796
30122
  // ../../packages/core/dist/esm/schemas/notification.schema.js
29797
30123
  var NOTIFICATION_TYPES = ["notification", "prompt"];
@@ -30594,13 +30920,13 @@ function buildUrl(baseUrl, path, query) {
30594
30920
  return url2.toString();
30595
30921
  }
30596
30922
  async function readResponseBody(response) {
30597
- const text = await response.text();
30598
- if (text.length === 0)
30923
+ const text2 = await response.text();
30924
+ if (text2.length === 0)
30599
30925
  return void 0;
30600
30926
  try {
30601
- return JSON.parse(text);
30927
+ return JSON.parse(text2);
30602
30928
  } catch {
30603
- return text;
30929
+ return text2;
30604
30930
  }
30605
30931
  }
30606
30932
  async function request(args) {
@@ -30789,6 +31115,16 @@ var automationDraftsEndpoints = {
30789
31115
  };
30790
31116
 
30791
31117
  // ../../packages/sdk/dist/esm/clients/automation-drafts/automation-drafts-client.js
31118
+ function toCreateQuery(translate) {
31119
+ return translate === void 0 ? void 0 : { translate };
31120
+ }
31121
+ function getDraftNotReadyError(error62) {
31122
+ if (!(error62 instanceof AutomationsRequestError) || error62.httpStatusCode !== 400) {
31123
+ return null;
31124
+ }
31125
+ const parsed = AutomationDraftNotReadySchema.safeParse(error62.responseData);
31126
+ return parsed.success ? parsed.data : null;
31127
+ }
30792
31128
  var AutomationDraftsClient = class extends BaseClient {
30793
31129
  async list(args = {}, options) {
30794
31130
  const { cursor, limit } = CursorPaginationSchema.parse(args);
@@ -30811,11 +31147,13 @@ var AutomationDraftsClient = class extends BaseClient {
30811
31147
  }
30812
31148
  async create(manifest, options) {
30813
31149
  const body = partialManifestSchema.parse(manifest);
31150
+ const { translate, ...requestOptions } = options ?? {};
30814
31151
  const data = await this.request({
30815
31152
  method: "POST",
30816
31153
  path: automationDraftsEndpoints.list,
31154
+ query: toCreateQuery(translate),
30817
31155
  body,
30818
- options
31156
+ options: requestOptions
30819
31157
  });
30820
31158
  return automationDraftWithValidationSchema.parse(data);
30821
31159
  }
@@ -30918,6 +31256,13 @@ var automationsEndpoints = {
30918
31256
 
30919
31257
  // ../../packages/sdk/dist/esm/clients/automations/automations-client.js
30920
31258
  var createDraftResponseSchema = external_exports.object({ draft: automationDraftSchema });
31259
+ function getOpenDraftConflictError(error62) {
31260
+ if (!(error62 instanceof AutomationsRequestError) || error62.httpStatusCode !== 409) {
31261
+ return null;
31262
+ }
31263
+ const parsed = AutomationOpenDraftConflictSchema.safeParse(error62.responseData);
31264
+ return parsed.success ? parsed.data : null;
31265
+ }
30921
31266
  var AutomationsClient = class extends BaseClient {
30922
31267
  async list(args = {}, options) {
30923
31268
  const { cursor, limit } = CursorPaginationSchema.parse(args);
@@ -31096,11 +31441,23 @@ var WorkspaceAutomationRunsClient = class extends BaseClient {
31096
31441
 
31097
31442
  // ../../packages/sdk/dist/esm/clients/workspace-automation-draft-connections/endpoints.js
31098
31443
  var workspaceAutomationDraftConnectionsEndpoints = {
31099
- list: (workspaceId, draftId) => `/workspaces/${encodeURIComponent(workspaceId)}/automation-drafts/${encodeURIComponent(draftId)}/connections`
31444
+ list: (workspaceId, draftId) => root6(workspaceId, draftId),
31445
+ status: (workspaceId, draftId) => `${root6(workspaceId, draftId)}/status`
31100
31446
  };
31447
+ function root6(workspaceId, draftId) {
31448
+ return `/workspaces/${encodeURIComponent(workspaceId)}/automation-drafts/${encodeURIComponent(draftId)}/connections`;
31449
+ }
31101
31450
 
31102
31451
  // ../../packages/sdk/dist/esm/clients/workspace-automation-draft-connections/workspace-automation-draft-connections-client.js
31103
31452
  var WorkspaceAutomationDraftConnectionsClient = class extends BaseClient {
31453
+ async list(workspaceId, draftId, options) {
31454
+ const data = await this.request({
31455
+ method: "GET",
31456
+ path: workspaceAutomationDraftConnectionsEndpoints.list(IdSchema.parse(workspaceId), IdSchema.parse(draftId)),
31457
+ options
31458
+ });
31459
+ return GetAutomationDraftConnectionsResponseSchema.parse(data);
31460
+ }
31104
31461
  async upsert(workspaceId, draftId, body, options) {
31105
31462
  const parsedBody = CreateAutomationDraftConnectionSchema.parse(body);
31106
31463
  const data = await this.request({
@@ -31111,14 +31468,23 @@ var WorkspaceAutomationDraftConnectionsClient = class extends BaseClient {
31111
31468
  });
31112
31469
  return AutomationDraftConnectionSchema.parse(data);
31113
31470
  }
31471
+ async getStatus(workspaceId, draftId, options) {
31472
+ const data = await this.request({
31473
+ method: "GET",
31474
+ path: workspaceAutomationDraftConnectionsEndpoints.status(IdSchema.parse(workspaceId), IdSchema.parse(draftId)),
31475
+ options
31476
+ });
31477
+ return GetAutomationDraftConnectionValidationResponseSchema.parse(data);
31478
+ }
31114
31479
  };
31115
31480
 
31116
31481
  // ../../packages/sdk/dist/esm/clients/workspace-automation-drafts/endpoints.js
31117
31482
  var workspaceAutomationDraftsEndpoints = {
31118
- list: (workspaceId) => `${root6(workspaceId)}`,
31119
- detail: (workspaceId, id) => `${root6(workspaceId)}/${encodeURIComponent(id)}`
31483
+ list: (workspaceId) => `${root7(workspaceId)}`,
31484
+ detail: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}`,
31485
+ finalize: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/finalize`
31120
31486
  };
31121
- function root6(workspaceId) {
31487
+ function root7(workspaceId) {
31122
31488
  return `/workspaces/${encodeURIComponent(workspaceId)}/automation-drafts`;
31123
31489
  }
31124
31490
 
@@ -31142,6 +31508,29 @@ var WorkspaceAutomationDraftsClient = class extends BaseClient {
31142
31508
  });
31143
31509
  return automationDraftWithValidationSchema.parse(data);
31144
31510
  }
31511
+ async create(workspaceId, manifest, options) {
31512
+ const body = partialManifestSchema.parse(manifest);
31513
+ const { translate, ...requestOptions } = options ?? {};
31514
+ const data = await this.request({
31515
+ method: "POST",
31516
+ path: workspaceAutomationDraftsEndpoints.list(IdSchema.parse(workspaceId)),
31517
+ // Only sent when set, so a default create is unchanged on the wire.
31518
+ query: translate === void 0 ? void 0 : { translate },
31519
+ body,
31520
+ options: requestOptions
31521
+ });
31522
+ return automationDraftWithValidationSchema.parse(data);
31523
+ }
31524
+ async update(workspaceId, draftId, manifest, options) {
31525
+ const body = partialManifestSchema.parse(manifest);
31526
+ const data = await this.request({
31527
+ method: "PUT",
31528
+ path: workspaceAutomationDraftsEndpoints.detail(IdSchema.parse(workspaceId), IdSchema.parse(draftId)),
31529
+ body,
31530
+ options
31531
+ });
31532
+ return automationDraftWithValidationSchema.parse(data);
31533
+ }
31145
31534
  /** Deletes the draft. Only its owner can; the API answers 404 otherwise. */
31146
31535
  async delete(workspaceId, draftId, options) {
31147
31536
  await this.request({
@@ -31150,6 +31539,15 @@ var WorkspaceAutomationDraftsClient = class extends BaseClient {
31150
31539
  options
31151
31540
  });
31152
31541
  }
31542
+ /** Publishes the draft as a workspace automation, or updates the one it edits. */
31543
+ async finalize(workspaceId, draftId, options) {
31544
+ const data = await this.request({
31545
+ method: "POST",
31546
+ path: workspaceAutomationDraftsEndpoints.finalize(IdSchema.parse(workspaceId), IdSchema.parse(draftId)),
31547
+ options
31548
+ });
31549
+ return finalizeAutomationDraftResponseSchema.parse(data);
31550
+ }
31153
31551
  };
31154
31552
 
31155
31553
  // ../../packages/sdk/dist/esm/clients/workspace-chat/endpoints.js
@@ -31173,15 +31571,16 @@ var WorkspaceChatClient = class extends BaseClient {
31173
31571
 
31174
31572
  // ../../packages/sdk/dist/esm/clients/workspace-automations/endpoints.js
31175
31573
  var workspaceAutomationsEndpoints = {
31176
- list: (workspaceId) => `${root7(workspaceId)}`,
31177
- detail: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}`,
31178
- metadata: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/metadata`,
31179
- schedule: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/schedule`,
31180
- visibility: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/visibility`,
31181
- move: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/move`,
31182
- trigger: (workspaceId, id) => `${root7(workspaceId)}/${encodeURIComponent(id)}/trigger`
31574
+ list: (workspaceId) => `${root8(workspaceId)}`,
31575
+ detail: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}`,
31576
+ metadata: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}/metadata`,
31577
+ schedule: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}/schedule`,
31578
+ visibility: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}/visibility`,
31579
+ move: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}/move`,
31580
+ trigger: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}/trigger`,
31581
+ draft: (workspaceId, id) => `${root8(workspaceId)}/${encodeURIComponent(id)}/draft`
31183
31582
  };
31184
- function root7(workspaceId) {
31583
+ function root8(workspaceId) {
31185
31584
  return `/workspaces/${encodeURIComponent(workspaceId)}/automations`;
31186
31585
  }
31187
31586
 
@@ -31279,12 +31678,33 @@ var WorkspaceAutomationsClient = class extends BaseClient {
31279
31678
  options
31280
31679
  });
31281
31680
  }
31681
+ /** The edit draft currently open for the automation, if any (404 otherwise). */
31682
+ async getDraft(workspaceId, id, options) {
31683
+ const data = await this.request({
31684
+ method: "GET",
31685
+ path: workspaceAutomationsEndpoints.draft(IdSchema.parse(workspaceId), IdSchema.parse(id)),
31686
+ options
31687
+ });
31688
+ return automationDraftSchema.parse(data);
31689
+ }
31690
+ /**
31691
+ * Opens an edit draft seeded from the published manifest. Answers 409 when
31692
+ * one is already open; see `getOpenDraftConflictError`.
31693
+ */
31694
+ async createDraft(workspaceId, id, options) {
31695
+ const data = await this.request({
31696
+ method: "POST",
31697
+ path: workspaceAutomationsEndpoints.draft(IdSchema.parse(workspaceId), IdSchema.parse(id)),
31698
+ options
31699
+ });
31700
+ return createDraftResponseSchema.parse(data);
31701
+ }
31282
31702
  };
31283
31703
 
31284
31704
  // ../../packages/sdk/dist/esm/clients/workspaces/endpoints.js
31285
- var root8 = "/workspaces";
31705
+ var root9 = "/workspaces";
31286
31706
  var workspacesEndpoints = {
31287
- list: root8
31707
+ list: root9
31288
31708
  };
31289
31709
 
31290
31710
  // ../../packages/sdk/dist/esm/clients/workspaces/workspaces-client.js
@@ -31306,12 +31726,12 @@ var WorkspacesClient = class extends BaseClient {
31306
31726
  };
31307
31727
 
31308
31728
  // ../../packages/sdk/dist/esm/clients/chat/endpoints.js
31309
- var root9 = "/chat/conversations";
31729
+ var root10 = "/chat/conversations";
31310
31730
  var chatEndpoints = {
31311
- conversations: root9,
31312
- conversation: (id) => `${root9}/${encodeURIComponent(id)}`,
31313
- messages: (id) => `${root9}/${encodeURIComponent(id)}/messages`,
31314
- usagePreview: (id) => `${root9}/${encodeURIComponent(id)}/usage-preview`
31731
+ conversations: root10,
31732
+ conversation: (id) => `${root10}/${encodeURIComponent(id)}`,
31733
+ messages: (id) => `${root10}/${encodeURIComponent(id)}/messages`,
31734
+ usagePreview: (id) => `${root10}/${encodeURIComponent(id)}/usage-preview`
31315
31735
  };
31316
31736
 
31317
31737
  // ../../packages/sdk/dist/esm/clients/chat/chat-client.js
@@ -31385,15 +31805,15 @@ var ChatClient = class extends BaseClient {
31385
31805
  };
31386
31806
 
31387
31807
  // ../../packages/sdk/dist/esm/clients/connections/endpoints.js
31388
- var root10 = "/connections";
31808
+ var root11 = "/connections";
31389
31809
  var connectionsEndpoints = {
31390
- list: root10,
31391
- detail: (id) => `${root10}/${encodeURIComponent(id)}`,
31392
- token: (id) => `${root10}/${encodeURIComponent(id)}/token`,
31393
- dependentAutomations: (connectorId) => `${root10}/${encodeURIComponent(connectorId)}/automations`,
31394
- create: (connectorId, capability) => `${root10}/${encodeURIComponent(connectorId)}/${encodeURIComponent(capability)}`,
31395
- localOAuth: (connectorId, capability) => `${root10}/${encodeURIComponent(connectorId)}/${encodeURIComponent(capability)}/local-oauth`,
31396
- checkManifest: `${root10}/check-manifest`
31810
+ list: root11,
31811
+ detail: (id) => `${root11}/${encodeURIComponent(id)}`,
31812
+ token: (id) => `${root11}/${encodeURIComponent(id)}/token`,
31813
+ dependentAutomations: (connectorId) => `${root11}/${encodeURIComponent(connectorId)}/automations`,
31814
+ create: (connectorId, capability) => `${root11}/${encodeURIComponent(connectorId)}/${encodeURIComponent(capability)}`,
31815
+ localOAuth: (connectorId, capability) => `${root11}/${encodeURIComponent(connectorId)}/${encodeURIComponent(capability)}/local-oauth`,
31816
+ checkManifest: `${root11}/check-manifest`
31397
31817
  };
31398
31818
 
31399
31819
  // ../../packages/sdk/dist/esm/clients/connections/connections-client.js
@@ -31580,12 +32000,12 @@ function createClientContext(authToken, options = {}, apiOrigin = "automations")
31580
32000
  }
31581
32001
 
31582
32002
  // ../../packages/sdk/dist/esm/clients/notifications/endpoints.js
31583
- var root11 = "/notifications";
32003
+ var root12 = "/notifications";
31584
32004
  var notificationsEndpoints = {
31585
- list: root11,
31586
- pendingPromptAutomations: `${root11}/pending-prompt-automations`,
31587
- detail: (id) => `${root11}/${encodeURIComponent(id)}`,
31588
- respond: (id) => `${root11}/${encodeURIComponent(id)}/respond`
32005
+ list: root12,
32006
+ pendingPromptAutomations: `${root12}/pending-prompt-automations`,
32007
+ detail: (id) => `${root12}/${encodeURIComponent(id)}`,
32008
+ respond: (id) => `${root12}/${encodeURIComponent(id)}/respond`
31589
32009
  };
31590
32010
  var pushRoot = "/push-subscriptions";
31591
32011
  var pushSubscriptionsEndpoints = {
@@ -31709,11 +32129,11 @@ var NotificationsClient = class extends BaseClient {
31709
32129
  };
31710
32130
 
31711
32131
  // ../../packages/sdk/dist/esm/clients/user-settings/endpoints.js
31712
- var root12 = "/settings";
32132
+ var root13 = "/settings";
31713
32133
  var userSettingsEndpoints = {
31714
- onboarding: `${root12}/onboarding`,
31715
- preferences: `${root12}/preferences`,
31716
- terms: `${root12}/terms`
32134
+ onboarding: `${root13}/onboarding`,
32135
+ preferences: `${root13}/preferences`,
32136
+ terms: `${root13}/terms`
31717
32137
  };
31718
32138
 
31719
32139
  // ../../packages/sdk/dist/esm/clients/user-settings/user-settings-client.js
@@ -31875,11 +32295,11 @@ var UsageBillingClient = class extends BaseClient {
31875
32295
  };
31876
32296
 
31877
32297
  // ../../packages/sdk/dist/esm/clients/webhook-event-subscriptions/endpoints.js
31878
- var root13 = "/webhook-event-subscriptions";
32298
+ var root14 = "/webhook-event-subscriptions";
31879
32299
  var webhookEventSubscriptionsEndpoints = {
31880
- list: root13,
31881
- detail: (id) => `${root13}/${encodeURIComponent(id)}`,
31882
- deliveries: (id) => `${root13}/${encodeURIComponent(id)}/deliveries`
32300
+ list: root14,
32301
+ detail: (id) => `${root14}/${encodeURIComponent(id)}`,
32302
+ deliveries: (id) => `${root14}/${encodeURIComponent(id)}/deliveries`
31883
32303
  };
31884
32304
 
31885
32305
  // ../../packages/sdk/dist/esm/clients/webhook-event-subscriptions/webhook-event-subscriptions-client.js
@@ -31952,12 +32372,12 @@ var WebhookEventSubscriptionsClient = class extends BaseClient {
31952
32372
  };
31953
32373
 
31954
32374
  // ../../packages/sdk/dist/esm/clients/webhook-subscriptions/endpoints.js
31955
- function root14(automationId) {
32375
+ function root15(automationId) {
31956
32376
  return `/automations/${encodeURIComponent(automationId)}/subscriptions`;
31957
32377
  }
31958
32378
  var webhookSubscriptionsEndpoints = {
31959
- list: (automationId) => root14(automationId),
31960
- detail: (automationId, subscriptionId) => `${root14(automationId)}/${encodeURIComponent(subscriptionId)}`
32379
+ list: (automationId) => root15(automationId),
32380
+ detail: (automationId, subscriptionId) => `${root15(automationId)}/${encodeURIComponent(subscriptionId)}`
31961
32381
  };
31962
32382
 
31963
32383
  // ../../packages/sdk/dist/esm/clients/webhook-subscriptions/webhook-subscriptions-client.js
@@ -32145,6 +32565,7 @@ function summarizeAutomationListItem(dto) {
32145
32565
  visibility: dto.visibility,
32146
32566
  isOwner: dto.isOwner,
32147
32567
  ...dto.workspaceId ? { workspaceId: dto.workspaceId } : {},
32568
+ ...dto.createdBy ? { createdBy: dto.createdBy } : {},
32148
32569
  ...dto.updatedBy ? { updatedBy: dto.updatedBy } : {},
32149
32570
  ...dto.disabledReason ? { disabledReason: dto.disabledReason } : {},
32150
32571
  triggers: triggers.flatMap((trigger) => summarizeTrigger(trigger) ?? []),
@@ -33815,10 +34236,10 @@ function formatAutomation(automation) {
33815
34236
  ...automation.workspaceId === null ? [] : [
33816
34237
  `Workspace: ${automation.workspaceId}`,
33817
34238
  `Visibility: ${automation.visibility}`,
33818
- `Created by: ${automation.isOwner ? "you" : "another member"}`,
33819
- // A shared automation can be changed by its creator or a workspace
33820
- // admin, so the last person to do so is worth naming; a bare id,
33821
- // as `Triggered by` is on runs.
34239
+ // Bare ids, as `Triggered by` is on runs. A shared automation can be
34240
+ // changed by its creator or a workspace admin, so the last person
34241
+ // to do so is worth naming too.
34242
+ `Created by: ${automation.isOwner ? "you" : automation.createdBy ?? "another member"}`,
33822
34243
  ...automation.updatedBy === null ? [] : [`Last changed by: ${automation.updatedBy}`]
33823
34244
  ],
33824
34245
  `Enabled: ${automation.enabled}`,
@@ -33951,8 +34372,8 @@ function getResourceName(manifest) {
33951
34372
  }
33952
34373
  function getMessageSummary(message) {
33953
34374
  if (!Array.isArray(message.parts)) return "(unstructured message parts)";
33954
- const text = message.parts.filter(isTextPart).map((part) => part.text).join("");
33955
- if (text) return text;
34375
+ const text2 = message.parts.filter(isTextPart).map((part) => part.text).join("");
34376
+ if (text2) return text2;
33956
34377
  const partTypes = message.parts.filter(isRecord2).map((part) => typeof part.type === "string" ? part.type : "unknown");
33957
34378
  return partTypes.length > 0 ? `[${partTypes.join(", ")}]` : "(no visible text)";
33958
34379
  }
@@ -34307,6 +34728,36 @@ async function runStreamingCommand(command, handlers) {
34307
34728
  }
34308
34729
  }
34309
34730
 
34731
+ // src/lib/connection-selection.ts
34732
+ function parseConnectionSelectionOption(value) {
34733
+ const separatorIndex = value.indexOf("=");
34734
+ if (separatorIndex <= 0 || separatorIndex === value.length - 1) {
34735
+ throw new Error(
34736
+ `Invalid connection selection "${value}". Use connector[:mcp|trigger]=connection-id.`
34737
+ );
34738
+ }
34739
+ const selector = value.slice(0, separatorIndex);
34740
+ const connectionId = value.slice(separatorIndex + 1);
34741
+ const selectorParts = selector.split(":");
34742
+ if (selectorParts.length > 2) {
34743
+ throw new Error(`Invalid connection selection "${value}".`);
34744
+ }
34745
+ const [connectorId, rawConnectionType] = selectorParts;
34746
+ if (!connectorId) throw new Error(`Invalid connection selection "${value}".`);
34747
+ if (rawConnectionType && rawConnectionType !== "mcp" && rawConnectionType !== "trigger") {
34748
+ throw new Error(`Invalid connection type "${rawConnectionType}".`);
34749
+ }
34750
+ const connectionType = rawConnectionType === "mcp" || rawConnectionType === "trigger" ? rawConnectionType : void 0;
34751
+ return {
34752
+ connectorId,
34753
+ connectionType,
34754
+ connectionId
34755
+ };
34756
+ }
34757
+ function collectOption(value, previous) {
34758
+ return [...previous, value];
34759
+ }
34760
+
34310
34761
  // ../../packages/sdk/dist/esm/chat-turn/connection-requirements.js
34311
34762
  var CONNECTION_LOOKUP_CONCURRENCY = 4;
34312
34763
  function deduplicateConnectionRequirements(requirements) {
@@ -34415,11 +34866,11 @@ var toolUpdateMemoryResultSchema = external_exports.object({
34415
34866
  });
34416
34867
 
34417
34868
  // ../../packages/sdk/dist/esm/chat-turn/messages.js
34418
- function createUserMessage(text) {
34869
+ function createUserMessage(text2) {
34419
34870
  return {
34420
34871
  id: globalThis.crypto.randomUUID(),
34421
34872
  role: "user",
34422
- parts: [{ type: "text", text }]
34873
+ parts: [{ type: "text", text: text2 }]
34423
34874
  };
34424
34875
  }
34425
34876
  function toUiMessage(message) {
@@ -34944,8 +35395,8 @@ Interrupted. Resume with: tda chat continue ${sanitizeTerminalText(event.convers
34944
35395
  this.assistantLineOpen = false;
34945
35396
  break;
34946
35397
  case "session_status": {
34947
- const text = sanitizeTerminalText(String(event.humanText ?? ""));
34948
- this.stream.write(text.endsWith("\n") ? text : `${text}
35398
+ const text2 = sanitizeTerminalText(String(event.humanText ?? ""));
35399
+ this.stream.write(text2.endsWith("\n") ? text2 : `${text2}
34949
35400
  `);
34950
35401
  break;
34951
35402
  }
@@ -35476,9 +35927,9 @@ var ChatService = class {
35476
35927
  input: input2,
35477
35928
  pendingAction,
35478
35929
  signal,
35479
- onText: (text) => {
35930
+ onText: (text2) => {
35480
35931
  markActivity();
35481
- this.output.emit({ type: "assistant_text", conversationId, text });
35932
+ this.output.emit({ type: "assistant_text", conversationId, text: text2 });
35482
35933
  },
35483
35934
  onToolActivity: (activity) => {
35484
35935
  markActivity();
@@ -35659,31 +36110,6 @@ function getResumeCommand(summary) {
35659
36110
  }
35660
36111
  return `tda chat continue ${summary.conversationId} "<message>"`;
35661
36112
  }
35662
- function parseConnectionSelectionOption(value) {
35663
- const separatorIndex = value.indexOf("=");
35664
- if (separatorIndex <= 0 || separatorIndex === value.length - 1) {
35665
- throw new Error(
35666
- `Invalid connection selection "${value}". Use connector[:mcp|trigger]=connection-id.`
35667
- );
35668
- }
35669
- const selector = value.slice(0, separatorIndex);
35670
- const connectionId = value.slice(separatorIndex + 1);
35671
- const selectorParts = selector.split(":");
35672
- if (selectorParts.length > 2) {
35673
- throw new Error(`Invalid connection selection "${value}".`);
35674
- }
35675
- const [connectorId, rawConnectionType] = selectorParts;
35676
- if (!connectorId) throw new Error(`Invalid connection selection "${value}".`);
35677
- if (rawConnectionType && rawConnectionType !== "mcp" && rawConnectionType !== "trigger") {
35678
- throw new Error(`Invalid connection type "${rawConnectionType}".`);
35679
- }
35680
- const connectionType = rawConnectionType === "mcp" || rawConnectionType === "trigger" ? rawConnectionType : void 0;
35681
- return {
35682
- connectorId,
35683
- connectionType,
35684
- connectionId
35685
- };
35686
- }
35687
36113
 
35688
36114
  // src/commands/chat/index.ts
35689
36115
  function registerChatCommand(program) {
@@ -35699,7 +36125,7 @@ function registerChatCommand(program) {
35699
36125
  chat.command("continue").description("Continue a persisted conversation").argument("<conversation-id>", "Conversation ID emitted by start").argument("[message...]", "Answer or follow-up message").option(
35700
36126
  "--connection <connector[:type]=connection-id>",
35701
36127
  "Resolve a pending connection selection; repeat for multiple connectors",
35702
- collect,
36128
+ collectOption,
35703
36129
  []
35704
36130
  ).action(
35705
36131
  async (conversationId, messageParts, options, command) => {
@@ -35782,9 +36208,6 @@ async function runCommand(command, operation) {
35782
36208
  }
35783
36209
  });
35784
36210
  }
35785
- function collect(value, previous) {
35786
- return [...previous, value];
35787
- }
35788
36211
 
35789
36212
  // src/commands/conversation/index.ts
35790
36213
  import { Option as Option3 } from "commander";
@@ -36356,6 +36779,343 @@ function registerConnectorCommand(program) {
36356
36779
  registerConnectorMutationCommands(connector);
36357
36780
  }
36358
36781
 
36782
+ // src/lib/manifest-input.ts
36783
+ import { CliError as CliError3, getErrorMessage as getErrorMessage6 } from "@doist/cli-core";
36784
+ import { Option as Option6 } from "commander";
36785
+ import { readFile as readFile2 } from "node:fs/promises";
36786
+ import { text } from "node:stream/consumers";
36787
+ function addManifestInputOptions(command) {
36788
+ return command.addOption(
36789
+ new Option6("--file <path>", "Read the manifest from this JSON file").conflicts("stdin")
36790
+ ).option("--stdin", "Read the manifest as JSON from standard input");
36791
+ }
36792
+ async function readManifestInput(options, input2 = process.stdin) {
36793
+ const source = await readSource(options, input2);
36794
+ try {
36795
+ return JSON.parse(source.content);
36796
+ } catch (error62) {
36797
+ throw new CliError3(
36798
+ "MANIFEST_UNREADABLE",
36799
+ `${source.label} is not valid JSON: ${getErrorMessage6(error62)}`
36800
+ );
36801
+ }
36802
+ }
36803
+ function parsePartialManifestInput(value) {
36804
+ const validation = validatePartialManifest(value);
36805
+ if (!validation.isValid) {
36806
+ throw new CliError3(
36807
+ "MANIFEST_INVALID",
36808
+ `Manifest is invalid: ${validation.errors.join("; ")}`
36809
+ );
36810
+ }
36811
+ return validation.data;
36812
+ }
36813
+ async function readSource(options, input2) {
36814
+ if (options.file !== void 0) {
36815
+ try {
36816
+ return { label: options.file, content: await readFile2(options.file, "utf8") };
36817
+ } catch (error62) {
36818
+ throw new CliError3(
36819
+ "MANIFEST_UNREADABLE",
36820
+ `Could not read ${options.file}: ${getErrorMessage6(error62)}`
36821
+ );
36822
+ }
36823
+ }
36824
+ if (options.stdin) {
36825
+ try {
36826
+ return { label: "Standard input", content: await text(input2) };
36827
+ } catch (error62) {
36828
+ throw new CliError3(
36829
+ "MANIFEST_UNREADABLE",
36830
+ `Could not read standard input: ${getErrorMessage6(error62)}`
36831
+ );
36832
+ }
36833
+ }
36834
+ throw new CliError3("MANIFEST_UNREADABLE", "Provide the manifest with --file <path> or --stdin.");
36835
+ }
36836
+
36837
+ // src/commands/draft/draft-service.ts
36838
+ import { CliError as CliError4, getErrorMessage as getErrorMessage7 } from "@doist/cli-core";
36839
+
36840
+ // src/lib/manifest-diff.ts
36841
+ function stableStringify(value) {
36842
+ return JSON.stringify(sortKeys(value));
36843
+ }
36844
+ function isDeepEqual(left, right) {
36845
+ return stableStringify(left) === stableStringify(right);
36846
+ }
36847
+ function diffManifests(before, after) {
36848
+ const previous = asManifest(before);
36849
+ const next = asManifest(after);
36850
+ const changedProperties = [.../* @__PURE__ */ new Set([...Object.keys(previous), ...Object.keys(next)])].filter((key) => key !== "steps").filter((key) => !isDeepEqual(previous[key], next[key])).sort();
36851
+ const previousSteps = stepsById(previous.steps);
36852
+ const nextSteps = stepsById(next.steps);
36853
+ const added = [...nextSteps.keys()].filter((id) => !previousSteps.has(id));
36854
+ const removed = [...previousSteps.keys()].filter((id) => !nextSteps.has(id));
36855
+ const changed = [...nextSteps].filter(([id, step]) => previousSteps.has(id) && !isDeepEqual(previousSteps.get(id), step)).map(([id]) => id);
36856
+ const sharedBefore = [...previousSteps.keys()].filter((id) => nextSteps.has(id));
36857
+ const sharedAfter = [...nextSteps.keys()].filter((id) => previousSteps.has(id));
36858
+ const reordered = sharedBefore.some((id, index) => sharedAfter[index] !== id);
36859
+ return {
36860
+ changedProperties,
36861
+ steps: { added, removed, changed, reordered },
36862
+ isEmpty: changedProperties.length === 0 && added.length === 0 && removed.length === 0 && changed.length === 0 && !reordered
36863
+ };
36864
+ }
36865
+ function asManifest(value) {
36866
+ return isRecord3(value) ? value : {};
36867
+ }
36868
+ function stepsById(steps) {
36869
+ const byId = /* @__PURE__ */ new Map();
36870
+ if (!Array.isArray(steps)) return byId;
36871
+ steps.forEach((step, index) => {
36872
+ const id = isRecord3(step) && typeof step.id === "string" ? step.id : `#${index}`;
36873
+ byId.set(id, step);
36874
+ });
36875
+ return byId;
36876
+ }
36877
+ function sortKeys(value) {
36878
+ if (Array.isArray(value)) return value.map(sortKeys);
36879
+ if (!isRecord3(value)) return value;
36880
+ return Object.fromEntries(
36881
+ Object.keys(value).sort().map((key) => [key, sortKeys(value[key])])
36882
+ );
36883
+ }
36884
+ function isRecord3(value) {
36885
+ return typeof value === "object" && value !== null && !Array.isArray(value);
36886
+ }
36887
+
36888
+ // src/commands/draft/draft-service.ts
36889
+ function resolveDraftApi(api, workspaceId, signal) {
36890
+ const createOptions = { signal, translate: false };
36891
+ if (workspaceId === null) {
36892
+ return {
36893
+ scope: null,
36894
+ get: (draftId) => api.automationDrafts.get(draftId, { signal }),
36895
+ create: (manifest) => api.automationDrafts.create(manifest, createOptions),
36896
+ update: (draftId, manifest) => api.automationDrafts.update(draftId, manifest, { signal }),
36897
+ createAutomationDraft: (automationId) => api.automations.createDraft(automationId, { signal }),
36898
+ upsertConnection: (draftId, body) => api.automationDraftConnections.upsert(draftId, body, { signal }),
36899
+ getConnectionStatus: async (draftId) => (await api.automationDraftConnections.getStatus(draftId, { signal })).validation,
36900
+ finalize: (draftId) => api.automationDrafts.finalize(draftId, { signal }),
36901
+ getAutomation: (automationId) => api.automations.get(automationId, { signal })
36902
+ };
36903
+ }
36904
+ return {
36905
+ scope: workspaceId,
36906
+ get: (draftId) => api.workspaceAutomationDrafts.get(workspaceId, draftId, { signal }),
36907
+ create: (manifest) => api.workspaceAutomationDrafts.create(workspaceId, manifest, createOptions),
36908
+ update: (draftId, manifest) => api.workspaceAutomationDrafts.update(workspaceId, draftId, manifest, { signal }),
36909
+ createAutomationDraft: (automationId) => api.workspaceAutomations.createDraft(workspaceId, automationId, { signal }),
36910
+ upsertConnection: (draftId, body) => api.workspaceAutomationDraftConnections.upsert(workspaceId, draftId, body, { signal }),
36911
+ getConnectionStatus: async (draftId) => (await api.workspaceAutomationDraftConnections.getStatus(workspaceId, draftId, {
36912
+ signal
36913
+ })).validation,
36914
+ finalize: (draftId) => api.workspaceAutomationDrafts.finalize(workspaceId, draftId, { signal }),
36915
+ getAutomation: (automationId) => api.workspaceAutomations.get(workspaceId, automationId, { signal })
36916
+ };
36917
+ }
36918
+ async function createDraft(draftApi, { manifest, automationId }) {
36919
+ const partialManifest = parsePartialManifestInput(manifest);
36920
+ if (automationId === void 0) {
36921
+ const result = await draftApi.create(partialManifest);
36922
+ return { action: "created", target: toTarget(result.draft), ...result };
36923
+ }
36924
+ const { draft } = await openEditDraft(draftApi, automationId);
36925
+ try {
36926
+ const result = await draftApi.update(draft.id, partialManifest);
36927
+ return { action: "created", target: toTarget(result.draft), ...result };
36928
+ } catch (error62) {
36929
+ if (!isManifestRejection(error62)) throw error62;
36930
+ throw new CliError4(
36931
+ "DRAFT_MANIFEST_REJECTED",
36932
+ `Opened draft ${draft.id} for automation ${automationId}, but the manifest was rejected: ${getErrorMessage7(error62)}`,
36933
+ { hints: draftHints(draftApi.scope, draft.id) }
36934
+ );
36935
+ }
36936
+ }
36937
+ function isManifestRejection(error62) {
36938
+ return error62 instanceof AutomationsRequestError && (error62.httpStatusCode === 400 || error62.httpStatusCode === 422);
36939
+ }
36940
+ async function updateDraft(draftApi, { draftId, manifest }) {
36941
+ const partialManifest = parsePartialManifestInput(manifest);
36942
+ const result = await draftApi.update(draftId, partialManifest);
36943
+ return { action: "updated", target: toTarget(result.draft), ...result };
36944
+ }
36945
+ async function openEditDraft(draftApi, automationId) {
36946
+ try {
36947
+ return await draftApi.createAutomationDraft(automationId);
36948
+ } catch (error62) {
36949
+ const conflict = getOpenDraftConflictError(error62);
36950
+ if (!conflict) throw error62;
36951
+ throw new CliError4(
36952
+ "DRAFT_CONFLICT",
36953
+ `Automation ${automationId} already has an open draft ${conflict.draftId}.`,
36954
+ { hints: draftHints(draftApi.scope, conflict.draftId) }
36955
+ );
36956
+ }
36957
+ }
36958
+ function draftHints(scope, draftId) {
36959
+ const scopeFlag = scope === null ? "--personal" : `--workspace ${scope}`;
36960
+ return [
36961
+ `Apply the file to it: tda draft update ${draftId} --file <path> ${scopeFlag}`,
36962
+ `Or discard it first: tda draft delete ${draftId} --yes ${scopeFlag}`
36963
+ ];
36964
+ }
36965
+ function toTarget(draft) {
36966
+ return draft.automationId === null ? { kind: "new" } : { kind: "automation", automationId: draft.automationId };
36967
+ }
36968
+ async function connectDraft(draftApi, api, {
36969
+ draftId,
36970
+ selections,
36971
+ auto
36972
+ }) {
36973
+ const bound = [];
36974
+ const required2 = selections.length > 0 ? getRequiredConnectorsFromManifest(
36975
+ (await draftApi.get(draftId)).draft.partialManifest
36976
+ ) : /* @__PURE__ */ new Map();
36977
+ for (const selection of selections) {
36978
+ const types = required2.get(selection.connectorId);
36979
+ if (!types || selection.connectionType && !types.has(selection.connectionType)) {
36980
+ const slot = selection.connectionType ? `${selection.connectorId} (${selection.connectionType})` : selection.connectorId;
36981
+ throw new Error(
36982
+ `Connector ${slot} is not used by draft ${draftId}. Required: ${describeRequired(required2)}.`
36983
+ );
36984
+ }
36985
+ const connectionTypes = selection.connectionType ? [selection.connectionType] : [...types];
36986
+ for (const connectionType of connectionTypes) {
36987
+ await draftApi.upsertConnection(draftId, {
36988
+ connectorId: selection.connectorId,
36989
+ connectionType,
36990
+ connectionId: selection.connectionId
36991
+ });
36992
+ bound.push({ ...selection, connectionType, mode: "explicit" });
36993
+ }
36994
+ }
36995
+ const unresolved = [];
36996
+ if (auto) {
36997
+ const status = await draftApi.getConnectionStatus(draftId);
36998
+ for (const connector of status.connectors) {
36999
+ for (const connectionType of ["mcp", "trigger"]) {
37000
+ const slot = connector[connectionType];
37001
+ if (!slot.required || slot.status !== "missing") continue;
37002
+ const { connections } = await api.connections.list({
37003
+ connectorId: connector.id,
37004
+ capability: connectionType,
37005
+ status: "authorized"
37006
+ });
37007
+ const [only] = connections;
37008
+ if (connections.length === 1 && only) {
37009
+ await draftApi.upsertConnection(draftId, {
37010
+ connectorId: connector.id,
37011
+ connectionType,
37012
+ connectionId: only.id
37013
+ });
37014
+ bound.push({
37015
+ connectorId: connector.id,
37016
+ connectionType,
37017
+ connectionId: only.id,
37018
+ mode: "auto"
37019
+ });
37020
+ continue;
37021
+ }
37022
+ unresolved.push({
37023
+ connectorId: connector.id,
37024
+ connectionType,
37025
+ reason: connections.length === 0 ? "no_connection" : "multiple_connections",
37026
+ candidateConnectionIds: connections.map((connection) => connection.id)
37027
+ });
37028
+ }
37029
+ }
37030
+ }
37031
+ const { isValid, missing } = await draftApi.getConnectionStatus(draftId);
37032
+ return { action: "connected", draftId, bound, unresolved, isValid, missing };
37033
+ }
37034
+ function describeRequired(required2) {
37035
+ if (required2.size === 0) return "none";
37036
+ return [...required2].map(([connectorId, types]) => `${connectorId} (${[...types].join(", ")})`).join(", ");
37037
+ }
37038
+ async function publishDraft(draftApi, { draftId, confirmed }) {
37039
+ const { summary, manifest } = await summarizeForPublish(draftApi, draftId);
37040
+ if (!confirmed) {
37041
+ return { action: "publish_preview", summary };
37042
+ }
37043
+ let published;
37044
+ try {
37045
+ published = await draftApi.finalize(draftId);
37046
+ } catch (error62) {
37047
+ const notReady = getDraftNotReadyError(error62);
37048
+ if (!notReady) throw error62;
37049
+ throw new CliError4("DRAFT_NOT_READY", notReady.message, {
37050
+ hints: [
37051
+ `See the issues: tda draft view ${draftId}`,
37052
+ `Bind connections: tda draft connect ${draftId} --auto`
37053
+ ]
37054
+ });
37055
+ }
37056
+ const automation = await draftApi.getAutomation(published.automation.id);
37057
+ const expected = normaliseManifest(manifest);
37058
+ const actual = normaliseManifest(automation.manifest);
37059
+ const verified = isDeepEqual(expected, actual);
37060
+ return {
37061
+ action: "published",
37062
+ summary,
37063
+ automation,
37064
+ verified,
37065
+ mismatch: verified ? null : diffManifests(expected, actual)
37066
+ };
37067
+ }
37068
+ async function summarizeForPublish(draftApi, draftId) {
37069
+ const [detail, connections] = await Promise.all([
37070
+ draftApi.get(draftId),
37071
+ draftApi.getConnectionStatus(draftId)
37072
+ ]);
37073
+ const { draft } = detail;
37074
+ const target = toTarget(draft);
37075
+ const published = target.kind === "automation" ? await draftApi.getAutomation(target.automationId) : null;
37076
+ const diff = published ? diffManifests(
37077
+ normaliseManifest(published.manifest),
37078
+ normaliseManifest(draft.partialManifest)
37079
+ ) : null;
37080
+ const summary = {
37081
+ draftId,
37082
+ name: getResourceName(draft.partialManifest),
37083
+ scope: draft.workspaceId === null ? { kind: "personal" } : {
37084
+ kind: "workspace",
37085
+ workspaceId: draft.workspaceId,
37086
+ // A new workspace automation publishes team-visible; an
37087
+ // edit keeps whatever the automation already has.
37088
+ visibility: published?.visibility ?? "workspace"
37089
+ },
37090
+ target,
37091
+ validation: { state: detail.state, issues: detail.issues },
37092
+ connections: {
37093
+ isValid: connections.isValid,
37094
+ connected: connections.connected.map(
37095
+ ({ connectorId, connectionType, connectionId }) => ({
37096
+ connectorId,
37097
+ connectionType,
37098
+ connectionId
37099
+ })
37100
+ ),
37101
+ missing: connections.missing
37102
+ },
37103
+ schedule: describeSchedule(draft.partialManifest),
37104
+ diff
37105
+ };
37106
+ return { summary, manifest: draft.partialManifest };
37107
+ }
37108
+ function describeSchedule(manifest) {
37109
+ if (!hasTriggerType(manifest)) return null;
37110
+ const schedule = getManifestTriggers(manifest).find((trigger) => trigger.type === "schedule");
37111
+ if (!schedule || schedule.type !== "schedule") return null;
37112
+ return getScheduleTriggerDescription({ value: schedule.value, timeFormat: "24h" });
37113
+ }
37114
+ function normaliseManifest(manifest) {
37115
+ const parsed = manifestSchema.safeParse(manifest);
37116
+ return parsed.success ? parsed.data : manifest;
37117
+ }
37118
+
36359
37119
  // src/commands/draft/format.ts
36360
37120
  function formatDraftDelete(result) {
36361
37121
  if (result.action === "delete_preview") {
@@ -36367,10 +37127,144 @@ function formatDraftDelete(result) {
36367
37127
  }
36368
37128
  return `Deleted draft ${result.draftId}.`;
36369
37129
  }
37130
+ function formatDraftChange(result) {
37131
+ const verb = result.action === "created" ? "Created" : "Updated";
37132
+ const target = result.target.kind === "new" ? "for a new automation" : `to update automation ${result.target.automationId}`;
37133
+ return [
37134
+ `${verb} draft ${result.draft.id} ${target}.`,
37135
+ `Validation: ${result.state}`,
37136
+ `Issues: ${result.issues.length > 0 ? result.issues.join("; ") : "none"}`
37137
+ ].join("\n");
37138
+ }
37139
+ function formatDraftConnect(result) {
37140
+ const lines = [`Draft ${result.draftId} connections:`];
37141
+ if (result.bound.length === 0) {
37142
+ lines.push(" (nothing bound)");
37143
+ }
37144
+ for (const binding of result.bound) {
37145
+ const how = binding.mode === "auto" ? "auto (only authorised connection)" : "explicit";
37146
+ lines.push(
37147
+ ` ${binding.connectorId} ${binding.connectionType} ${binding.connectionId} ${how}`
37148
+ );
37149
+ }
37150
+ if (result.unresolved.length > 0) {
37151
+ lines.push("Unresolved:");
37152
+ for (const slot of result.unresolved) {
37153
+ lines.push(
37154
+ slot.reason === "no_connection" ? ` ${slot.connectorId} ${slot.connectionType} no authorised connection; run: tda connector connect ${slot.connectorId} --capability ${slot.connectionType}` : ` ${slot.connectorId} ${slot.connectionType} ${slot.candidateConnectionIds.length} authorised connections; pick one: --connection ${slot.connectorId}:${slot.connectionType}=<connection-id> (${slot.candidateConnectionIds.join(", ")})`
37155
+ );
37156
+ }
37157
+ }
37158
+ lines.push(
37159
+ result.isValid ? "Connections: ready" : `Connections: missing ${result.missing.map((entry) => `${entry.connectorName} ${entry.connectionType} (${entry.reason})`).join(", ")}`
37160
+ );
37161
+ return lines.join("\n");
37162
+ }
37163
+ function formatDraftPublish(result) {
37164
+ if (result.action === "publish_preview") {
37165
+ return [...describePublishSummary(result.summary), "Use --yes to publish."].join("\n");
37166
+ }
37167
+ const { summary, automation } = result;
37168
+ const how = summary.target.kind === "new" ? "new automation" : "updated";
37169
+ return [
37170
+ `Published draft ${summary.draftId} as automation ${automation.id} (${how}).`,
37171
+ result.verified ? "Verified: published manifest matches the draft." : `Warning: published manifest differs from the draft: ${describeDiff(result.mismatch)}.`
37172
+ ].join("\n");
37173
+ }
37174
+ function summarizeDraftPublish(result) {
37175
+ if (result.action === "publish_preview") return result;
37176
+ return { ...result, automation: summarizeAutomation(result.automation) };
37177
+ }
37178
+ function describePublishSummary(summary) {
37179
+ const lines = [
37180
+ `Draft: ${summary.name} (${summary.draftId})`,
37181
+ summary.scope.kind === "personal" ? "Scope: personal" : `Scope: workspace ${summary.scope.workspaceId} (${describeVisibility2(summary)})`,
37182
+ summary.target.kind === "new" ? "Action: create a new automation" : `Action: update automation ${summary.target.automationId}`,
37183
+ summary.validation.issues.length === 0 ? `Validation: ${summary.validation.state}` : `Validation: ${summary.validation.state}; ${summary.validation.issues.join("; ")}`,
37184
+ summary.connections.isValid ? "Connections: ready" : `Connections: missing ${summary.connections.missing.map((entry) => `${entry.connectorName} ${entry.connectionType} (${entry.reason})`).join(", ")}`,
37185
+ `Schedule: ${summary.schedule ?? "none (runs on its trigger)"}`
37186
+ ];
37187
+ if (summary.diff) {
37188
+ lines.push(
37189
+ summary.diff.isEmpty ? "Changes vs published automation: none" : `Changes vs published automation: ${describeDiff(summary.diff)}`
37190
+ );
37191
+ }
37192
+ return lines;
37193
+ }
37194
+ function describeVisibility2(summary) {
37195
+ if (summary.scope.kind !== "workspace") return "";
37196
+ const visibility = summary.scope.visibility === "workspace" ? "visible to the workspace" : "private";
37197
+ return summary.target.kind === "new" ? `publishes ${visibility}` : `stays ${visibility}`;
37198
+ }
37199
+ function describeDiff(diff) {
37200
+ if (!diff || diff.isEmpty) return "none";
37201
+ const parts = [];
37202
+ if (diff.changedProperties.length > 0) {
37203
+ parts.push(`properties ${diff.changedProperties.join(", ")}`);
37204
+ }
37205
+ if (diff.steps.added.length > 0) parts.push(`steps added ${diff.steps.added.join(", ")}`);
37206
+ if (diff.steps.removed.length > 0) parts.push(`steps removed ${diff.steps.removed.join(", ")}`);
37207
+ if (diff.steps.changed.length > 0) parts.push(`steps changed ${diff.steps.changed.join(", ")}`);
37208
+ if (diff.steps.reordered) parts.push("steps reordered");
37209
+ return parts.join("; ");
37210
+ }
37211
+
37212
+ // src/commands/draft/validate-command.ts
37213
+ import { CliError as CliError5 } from "@doist/cli-core";
37214
+
37215
+ // src/lib/local-command.ts
37216
+ async function runLocalCommand(command, operation, presentation, execution = {}) {
37217
+ let mode = "human";
37218
+ try {
37219
+ mode = getOutputMode(getGlobalOptions(command));
37220
+ const result = await withSpinner({ text: execution.spinner ?? "Loading..." }, operation);
37221
+ stopEarlySpinner();
37222
+ writeResult(mode, result, presentation);
37223
+ } catch (error62) {
37224
+ writeFailure(mode, "error", renderFailure(error62, { mode }));
37225
+ process.exitCode = 1;
37226
+ }
37227
+ }
37228
+
37229
+ // src/commands/draft/validate-command.ts
37230
+ function registerDraftValidateCommand(draft) {
37231
+ addManifestInputOptions(
37232
+ draft.command("validate").description("Check a manifest file against the full manifest schema, offline")
37233
+ ).action(async (options, command) => {
37234
+ await runLocalCommand(
37235
+ command,
37236
+ async () => validateManifestInput(await readManifestInput(options)),
37237
+ { human: formatManifestValidation },
37238
+ { spinner: "Validating manifest..." }
37239
+ );
37240
+ });
37241
+ }
37242
+ function validateManifestInput(manifest) {
37243
+ const validation = validateManifest(manifest);
37244
+ if (!validation.isValid) {
37245
+ throw new CliError5(
37246
+ "MANIFEST_INVALID",
37247
+ `Manifest is invalid: ${validation.errors.join("; ")}`
37248
+ );
37249
+ }
37250
+ const parsed = manifestSchema.parse(manifest);
37251
+ return {
37252
+ action: "validated",
37253
+ name: parsed.name,
37254
+ steps: parsed.steps.length,
37255
+ triggers: getManifestTriggers(parsed).map((trigger) => trigger.type)
37256
+ };
37257
+ }
37258
+ function formatManifestValidation(result) {
37259
+ const steps = `${result.steps} step${result.steps === 1 ? "" : "s"}`;
37260
+ const triggers = result.triggers.length === 0 ? "no triggers" : `trigger ${result.triggers.join(", ")}`;
37261
+ return `Manifest "${result.name}" is valid: ${steps}, ${triggers}.`;
37262
+ }
36370
37263
 
36371
37264
  // src/commands/draft/index.ts
36372
37265
  function registerDraftCommand(program) {
36373
- const draft = program.command("draft").description("Inspect and delete automation drafts");
37266
+ const draft = program.command("draft").description("Author and inspect automation drafts");
37267
+ registerDraftValidateCommand(draft);
36374
37268
  addWorkspaceScopeOptions(
36375
37269
  addCursorPaginationOptions(
36376
37270
  draft.command("list").description("List drafts").option(
@@ -36414,6 +37308,85 @@ function registerDraftCommand(program) {
36414
37308
  { spinner: "Loading draft..." }
36415
37309
  );
36416
37310
  });
37311
+ addWorkspaceScopeOptions(
37312
+ addManifestInputOptions(
37313
+ draft.command("create").description("Create a draft from a manifest file").option(
37314
+ "--automation <automation-id>",
37315
+ "Open an edit draft for this automation and apply the manifest to it"
37316
+ )
37317
+ )
37318
+ ).action(async (options, command) => {
37319
+ await runApiCommand(
37320
+ command,
37321
+ async ({ api, signal }) => {
37322
+ const manifest = await readManifestInput(options);
37323
+ const draftApi = resolveDraftApi(api, await resolveWorkspaceScope(options), signal);
37324
+ return createDraft(draftApi, { manifest, automationId: options.automation });
37325
+ },
37326
+ { human: formatDraftChange },
37327
+ { spinner: "Creating draft..." }
37328
+ );
37329
+ });
37330
+ addWorkspaceScopeOptions(
37331
+ addManifestInputOptions(
37332
+ draft.command("update").description("Replace a draft's manifest with a manifest file").argument("<draft-id>", "Draft ID")
37333
+ )
37334
+ ).action(async (draftId, options, command) => {
37335
+ await runApiCommand(
37336
+ command,
37337
+ async ({ api, signal }) => {
37338
+ const manifest = await readManifestInput(options);
37339
+ const draftApi = resolveDraftApi(api, await resolveWorkspaceScope(options), signal);
37340
+ return updateDraft(draftApi, { draftId, manifest });
37341
+ },
37342
+ { human: formatDraftChange },
37343
+ { spinner: "Updating draft..." }
37344
+ );
37345
+ });
37346
+ addWorkspaceScopeOptions(
37347
+ draft.command("connect").description("Bind the user's service connections to a draft").argument("<draft-id>", "Draft ID").option(
37348
+ "--connection <connector[:type]=connection-id>",
37349
+ "Bind this connection; repeat for multiple connectors",
37350
+ collectOption,
37351
+ []
37352
+ ).option(
37353
+ "--auto",
37354
+ "Bind every remaining required connector that has exactly one authorised connection"
37355
+ )
37356
+ ).action(async (draftId, options, command) => {
37357
+ await runApiCommand(
37358
+ command,
37359
+ async ({ api, signal }) => {
37360
+ if (options.connection.length === 0 && options.auto !== true) {
37361
+ throw new Error(
37362
+ "Provide --connection connector[:type]=connection-id or --auto."
37363
+ );
37364
+ }
37365
+ const selections = options.connection.map(parseConnectionSelectionOption);
37366
+ const draftApi = resolveDraftApi(api, await resolveWorkspaceScope(options), signal);
37367
+ return connectDraft(draftApi, api, {
37368
+ draftId,
37369
+ selections,
37370
+ auto: options.auto === true
37371
+ });
37372
+ },
37373
+ { human: formatDraftConnect },
37374
+ { spinner: "Connecting..." }
37375
+ );
37376
+ });
37377
+ addWorkspaceScopeOptions(
37378
+ draft.command("publish").description("Publish a draft after previewing what it will do").argument("<draft-id>", "Draft ID").option("--yes", "Confirm publication")
37379
+ ).action(async (draftId, options, command) => {
37380
+ await runApiCommand(
37381
+ command,
37382
+ async ({ api, signal }) => {
37383
+ const draftApi = resolveDraftApi(api, await resolveWorkspaceScope(options), signal);
37384
+ return publishDraft(draftApi, { draftId, confirmed: options.yes === true });
37385
+ },
37386
+ { human: formatDraftPublish, json: summarizeDraftPublish },
37387
+ { spinner: options.yes === true ? "Publishing..." : "Loading draft..." }
37388
+ );
37389
+ });
36417
37390
  addWorkspaceScopeOptions(
36418
37391
  draft.command("delete").description("Delete a draft after previewing which one it is").argument("<draft-id>", "Draft ID").option("--yes", "Confirm deletion")
36419
37392
  ).action(async (draftId, options, command) => {
@@ -36452,7 +37425,7 @@ function streamDraftList(options, fetchPage) {
36452
37425
  }
36453
37426
 
36454
37427
  // src/commands/run/index.ts
36455
- import { Option as Option6 } from "commander";
37428
+ import { Option as Option7 } from "commander";
36456
37429
  function registerRunCommand(program) {
36457
37430
  const run = program.command("run").description("Inspect automation runs");
36458
37431
  addWorkspaceScopeOptions(
@@ -36460,7 +37433,7 @@ function registerRunCommand(program) {
36460
37433
  run.command("list").description("List runs for an automation").argument("<automation-id>", "Automation ID")
36461
37434
  )
36462
37435
  ).addOption(
36463
- new Option6("--status <status>", "Only show runs with this status").choices([
37436
+ new Option7("--status <status>", "Only show runs with this status").choices([
36464
37437
  ...AUTOMATION_RUN_STATUSES
36465
37438
  ])
36466
37439
  ).option(
@@ -36544,26 +37517,12 @@ function registerRunCommand(program) {
36544
37517
  );
36545
37518
  }
36546
37519
 
36547
- // src/lib/local-command.ts
36548
- async function runLocalCommand(command, operation, presentation, execution = {}) {
36549
- let mode = "human";
36550
- try {
36551
- mode = getOutputMode(getGlobalOptions(command));
36552
- const result = await withSpinner({ text: execution.spinner ?? "Loading..." }, operation);
36553
- stopEarlySpinner();
36554
- writeResult(mode, result, presentation);
36555
- } catch (error62) {
36556
- writeFailure(mode, "error", renderFailure(error62, { mode }));
36557
- process.exitCode = 1;
36558
- }
36559
- }
36560
-
36561
37520
  // src/commands/skill/shared.ts
36562
- import { CliError as CliError3 } from "@doist/cli-core";
37521
+ import { CliError as CliError6 } from "@doist/cli-core";
36563
37522
  function requireInstaller(agent) {
36564
37523
  const installer = getInstaller(agent);
36565
37524
  if (!installer) {
36566
- throw new CliError3("UNKNOWN_AGENT", `Unknown agent: ${agent}.`, {
37525
+ throw new CliError6("UNKNOWN_AGENT", `Unknown agent: ${agent}.`, {
36567
37526
  hints: [`Available agents: ${AGENT_NAMES.join(", ")}.`]
36568
37527
  });
36569
37528
  }
@@ -36641,7 +37600,7 @@ async function uninstallSkill(agent, options, command) {
36641
37600
  }
36642
37601
 
36643
37602
  // src/commands/skill/update.ts
36644
- import { CliError as CliError4 } from "@doist/cli-core";
37603
+ import { CliError as CliError7 } from "@doist/cli-core";
36645
37604
  async function updateSkill(agent, options, command) {
36646
37605
  await runLocalCommand(
36647
37606
  command,
@@ -36667,7 +37626,7 @@ async function updateAllSkills(options, command) {
36667
37626
  async () => {
36668
37627
  const result = await updateAllInstalledSkills(options.local === true);
36669
37628
  if (result.errors.length > 0) {
36670
- throw new CliError4(
37629
+ throw new CliError7(
36671
37630
  "UPDATE_FAILED",
36672
37631
  `Could not update ${result.errors.length} skill file(s).`,
36673
37632
  { hints: result.errors.map((error62) => `${error62.agent}: ${error62.message}`) }
@@ -36828,13 +37787,13 @@ async function findWorkspace(api, workspaceId, signal) {
36828
37787
  // src/lib/command-output.ts
36829
37788
  function configureCommandOutput(command) {
36830
37789
  return command.configureOutput({
36831
- writeOut: (text) => {
37790
+ writeOut: (text2) => {
36832
37791
  stopEarlySpinner();
36833
- process.stdout.write(text);
37792
+ process.stdout.write(text2);
36834
37793
  },
36835
- writeErr: (text) => {
37794
+ writeErr: (text2) => {
36836
37795
  stopEarlySpinner();
36837
- process.stderr.write(text);
37796
+ process.stderr.write(text2);
36838
37797
  }
36839
37798
  });
36840
37799
  }
@@ -36846,7 +37805,7 @@ function createProgram() {
36846
37805
  `Target environment: ${ENVIRONMENT_NAMES.join(", ")}`,
36847
37806
  parseEnvironmentOption,
36848
37807
  initialEnvironmentName()
36849
- ).option("--api-url <url>", "Automations API base URL (overrides --env)").option("-H, --header <name:value>", "Additional API header", collect2, []).option("--json", "Emit one final JSON document").option("--ndjson", "Emit newline-delimited JSON").option("--no-interactive", "Complete one server turn and exit").option("--no-open", "Print connection setup URLs without opening a browser").option("--no-spinner", "Disable the loading spinner").showHelpAfterError();
37808
+ ).option("--api-url <url>", "Automations API base URL (overrides --env)").option("-H, --header <name:value>", "Additional API header", collect, []).option("--json", "Emit one final JSON document").option("--ndjson", "Emit newline-delimited JSON").option("--no-interactive", "Complete one server turn and exit").option("--no-open", "Print connection setup URLs without opening a browser").option("--no-spinner", "Disable the loading spinner").showHelpAfterError();
36850
37809
  configureCommandOutput(program);
36851
37810
  registerAuthCommand(program);
36852
37811
  registerAutomationCommand(program);
@@ -36860,7 +37819,7 @@ function createProgram() {
36860
37819
  registerWorkspaceCommand(program);
36861
37820
  return program;
36862
37821
  }
36863
- function collect2(value, previous) {
37822
+ function collect(value, previous) {
36864
37823
  return [...previous, value];
36865
37824
  }
36866
37825
  if (isEntrypoint()) {