@duvoai/cli 1.22.0 → 1.24.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/bin/duvo.js CHANGED
@@ -2647,6 +2647,11 @@ var DEFAULT_AGENT_CONFIG = {
2647
2647
  browserProvider: DEFAULT_BROWSER_PROVIDER
2648
2648
  }
2649
2649
  };
2650
+ var AUTOMATION_REVISION_STATUS = {
2651
+ DRAFT: "draft",
2652
+ LIVE: "live",
2653
+ HISTORIC: "historic"
2654
+ };
2650
2655
  var BUILD_STATUS = {
2651
2656
  DRAFT: "draft",
2652
2657
  LIVE: "live",
@@ -6944,8 +6949,20 @@ var updateIntegrationRequestSchema = z27.object({
6944
6949
  shared: z27.boolean().optional()
6945
6950
  });
6946
6951
  var testIntegrationRequestSchema = z27.object({
6947
- server_url: z27.url().describe("MCP server URL to test"),
6948
- headers: z27.record(z27.string(), z27.string()).optional().describe("Optional HTTP headers for authentication")
6952
+ server_url: z27.url().optional().describe("Raw MCP server URL to probe (for custom MCP servers)"),
6953
+ integration_slug: IntegrationSlugSchema.optional().describe(
6954
+ "Catalog integration slug. The backend resolves the MCP server URL and dummy auth headers server-side \u2014 no server_url or headers needed."
6955
+ ),
6956
+ headers: z27.record(z27.string(), z27.string()).optional().describe(
6957
+ "Optional HTTP headers for authentication (raw server_url mode only)"
6958
+ )
6959
+ }).refine(
6960
+ (data) => Boolean(data.server_url) !== Boolean(data.integration_slug),
6961
+ {
6962
+ message: "Provide exactly one of server_url or integration_slug"
6963
+ }
6964
+ ).refine((data) => !(data.integration_slug && data.headers), {
6965
+ message: "headers are not allowed with integration_slug \u2014 the backend builds dummy auth headers server-side"
6949
6966
  });
6950
6967
  var SUGGESTION_TYPES = [
6951
6968
  "aop",
@@ -7213,12 +7230,12 @@ var artifactDetailResponseSchema = z31.object({
7213
7230
  // teammates when the Pulse is published to the team with `edit` permission,
7214
7231
  // and for a member individually granted `edit` via a per-member share. Drives
7215
7232
  // the chat/version affordances; ownership actions stay gated on `is_creator`.
7216
- can_edit: z31.boolean(),
7217
- messages: z31.array(artifactMessageSchema)
7233
+ can_edit: z31.boolean()
7218
7234
  });
7219
7235
  var artifactMessageListResponseSchema = z31.object({
7220
7236
  data: z31.array(artifactMessageSchema),
7221
- total: z31.number().int().nonnegative()
7237
+ total: z31.number().int().nonnegative(),
7238
+ has_more: z31.boolean()
7222
7239
  });
7223
7240
  var artifactRevisionSchema = z31.object({
7224
7241
  id: z31.guid(),
@@ -8849,6 +8866,117 @@ var updateAutomationResponseApiSchema = z50.object({
8849
8866
  var deleteAutomationResponseApiSchema = z50.object({
8850
8867
  success: z50.boolean()
8851
8868
  });
8869
+ var automationRevisionStatusApiSchema = z50.enum(
8870
+ AUTOMATION_REVISION_STATUS
8871
+ );
8872
+ var automationRevisionSummaryApiSchema = z50.object({
8873
+ id: z50.guid().describe("Unique revision identifier"),
8874
+ automation_id: z50.guid().describe("ID of the automation this revision belongs to"),
8875
+ revision_number: z50.int().nullable().describe(
8876
+ "Sequential revision number, assigned on activation (null for a draft)"
8877
+ ),
8878
+ status: automationRevisionStatusApiSchema.describe(
8879
+ "Lifecycle status: draft, live, or historic"
8880
+ ),
8881
+ base_revision_id: z50.guid().nullable().describe(
8882
+ "Revision this draft was branched from (null when it has no base)"
8883
+ ),
8884
+ name: z50.string().nullable().describe("Optional human-readable revision name"),
8885
+ description: z50.string().nullable().describe("Optional revision description"),
8886
+ is_live: z50.boolean().describe("True when this is the automation's active revision"),
8887
+ is_stale_base: z50.boolean().describe(
8888
+ "True when a draft's base is no longer the active revision and must be resolved before activation"
8889
+ ),
8890
+ agent_count: z50.int().describe("Number of agent bindings in the revision"),
8891
+ queue_count: z50.int().describe("Number of queue bindings in the revision"),
8892
+ trigger_count: z50.int().describe("Number of trigger bindings in the revision"),
8893
+ modified_agent_ids: z50.array(z50.guid()).describe("Agents whose referenced build differs from the base revision"),
8894
+ created_at: z50.string().describe("ISO 8601 creation timestamp"),
8895
+ updated_at: z50.string().describe("ISO 8601 last-modified timestamp")
8896
+ });
8897
+ var automationRevisionsListApiSchema = z50.object({
8898
+ revisions: z50.array(automationRevisionSummaryApiSchema).describe("Revisions for the automation, newest first"),
8899
+ /**
8900
+ * True when older revisions exist beyond the returned window. The list is
8901
+ * capped (newest-first); older revisions remain inspectable individually via
8902
+ * `GET /automations/:automation_id/revisions/:revision_id`.
8903
+ */
8904
+ has_more: z50.boolean().describe("True when older revisions exist beyond the returned window")
8905
+ });
8906
+ var automationRevisionAgentBindingApiSchema = z50.object({
8907
+ agent_id: z50.guid().describe("Agent identifier"),
8908
+ build_id: z50.guid().describe("Build referenced for the agent in this revision")
8909
+ });
8910
+ var automationRevisionQueueBindingApiSchema = z50.object({
8911
+ case_queue_id: z50.guid().describe("Queue identifier"),
8912
+ agent_id: z50.guid().nullable().describe(
8913
+ "Agent the queue routes to in this revision (null when unrouted)"
8914
+ ),
8915
+ enabled: z50.boolean().describe("Whether the queue's routing is enabled"),
8916
+ concurrency: z50.int().nullable().describe("Per-revision concurrency limit (null for the queue default)"),
8917
+ name: z50.string().nullable().describe(
8918
+ "Per-revision queue name override (null to keep the queue's own name)"
8919
+ ),
8920
+ description: z50.string().nullable().describe("Per-revision queue description override")
8921
+ });
8922
+ var automationRevisionTriggerBindingApiSchema = z50.object({
8923
+ trigger_id: z50.guid().describe("Stable trigger identity"),
8924
+ enabled: z50.boolean().describe("Whether the trigger is enabled in this revision"),
8925
+ filter_config: z50.record(z50.string(), z50.unknown()).describe("Per-revision trigger filter configuration")
8926
+ });
8927
+ var automationRevisionDetailApiSchema = automationRevisionSummaryApiSchema.extend({
8928
+ agents: z50.array(automationRevisionAgentBindingApiSchema).describe("Agent bindings in the revision"),
8929
+ queues: z50.array(automationRevisionQueueBindingApiSchema).describe("Queue routing bindings in the revision"),
8930
+ triggers: z50.array(automationRevisionTriggerBindingApiSchema).describe("Trigger config bindings in the revision")
8931
+ });
8932
+ var automationRevisionDetailResponseApiSchema = z50.object({
8933
+ revision: automationRevisionDetailApiSchema.describe(
8934
+ "The revision with its full manifest"
8935
+ )
8936
+ });
8937
+ var automationRevisionResponseApiSchema = z50.object({
8938
+ revision: automationRevisionSummaryApiSchema.describe("The revision summary")
8939
+ });
8940
+ var AUTOMATION_REVISION_NAME_MAX_LENGTH = 200;
8941
+ var AUTOMATION_REVISION_DESCRIPTION_MAX_LENGTH = 2e3;
8942
+ var revisionNameFieldSchema = z50.string().trim().min(1).max(AUTOMATION_REVISION_NAME_MAX_LENGTH);
8943
+ var revisionDescriptionFieldSchema = z50.string().trim().max(AUTOMATION_REVISION_DESCRIPTION_MAX_LENGTH);
8944
+ var createAutomationRevisionBodyApiSchema = z50.object({
8945
+ base_revision_id: z50.guid().optional().describe("Revision to branch from (defaults to the active revision)"),
8946
+ name: revisionNameFieldSchema.optional().describe("Optional draft name"),
8947
+ description: revisionDescriptionFieldSchema.optional().describe("Optional draft description")
8948
+ });
8949
+ var setAutomationRevisionAgentBodyApiSchema = z50.object({
8950
+ agent_id: z50.guid().describe("Agent to bind in the revision"),
8951
+ build_id: z50.guid().describe("Build to reference for the agent")
8952
+ });
8953
+ var setAutomationRevisionQueueBodyApiSchema = z50.object({
8954
+ case_queue_id: z50.guid().describe("Queue to route in the revision"),
8955
+ agent_id: z50.guid().nullable().optional().describe(
8956
+ "Agent the queue routes to (null clears routing; omit to keep current)"
8957
+ ),
8958
+ enabled: z50.boolean().optional().describe(
8959
+ "Whether routing is enabled (omit to keep current; default true when new)"
8960
+ ),
8961
+ concurrency: z50.int().nonnegative().nullable().optional().describe(
8962
+ "Per-revision concurrency limit (null for queue default; omit to keep current)"
8963
+ ),
8964
+ name: revisionNameFieldSchema.nullable().optional().describe("Per-revision name override (null clears; omit to keep current)"),
8965
+ description: revisionDescriptionFieldSchema.nullable().optional().describe(
8966
+ "Per-revision description override (null clears; omit to keep current)"
8967
+ )
8968
+ });
8969
+ var activateAutomationRevisionBodyApiSchema = z50.object({
8970
+ repin_pending_cases: z50.boolean().optional().describe(
8971
+ "Re-pin the automation's pending, unclaimed cases onto the newly activated revision"
8972
+ )
8973
+ });
8974
+ var activateAutomationRevisionResponseApiSchema = z50.object({
8975
+ revision: automationRevisionSummaryApiSchema.describe(
8976
+ "The newly activated revision"
8977
+ ),
8978
+ repinned_case_count: z50.int().describe("Number of pending cases re-pinned onto the activated revision")
8979
+ });
8852
8980
  var DataResidencySchema = z51.enum(["us", "eu", "apac"]);
8853
8981
  var DataHandlingSchema = z51.enum(["standard", "zdr"]);
8854
8982
  var browserPageSchema = z52.object({
@@ -23483,7 +23611,12 @@ var TABLE_COLUMNS23 = [
23483
23611
  }
23484
23612
  ];
23485
23613
  function registerConnectionsProbe(connections) {
23486
- connections.command("probe").description("Probe an MCP server URL and list its available tools").requiredOption("--url <url>", "MCP server URL to probe").option(
23614
+ connections.command("probe").description(
23615
+ "Probe an MCP server and list its available tools. Use --url for custom MCP servers or --slug for catalog integrations (the backend resolves the URL)."
23616
+ ).option("--url <url>", "MCP server URL to probe (for custom MCP servers)").option(
23617
+ "--slug <slug>",
23618
+ "Catalog integration slug (backend resolves the URL and auth headers)"
23619
+ ).option(
23487
23620
  "--header <KEY=VALUE>",
23488
23621
  "HTTP header to send (repeatable)",
23489
23622
  (value, previous) => [
@@ -23491,14 +23624,13 @@ function registerConnectionsProbe(connections) {
23491
23624
  value
23492
23625
  ]
23493
23626
  ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function probeAction(options) {
23494
- const url = options.url.trim();
23495
- if (url.length === 0) {
23496
- throw new CliError("--url must not be empty");
23627
+ const url = options.url?.trim();
23628
+ const slug = options.slug?.trim();
23629
+ if (Boolean(url) === Boolean(slug)) {
23630
+ throw new CliError("Provide exactly one of --url or --slug");
23497
23631
  }
23498
- const body = {
23499
- server_url: url
23500
- };
23501
- if (options.header && options.header.length > 0) {
23632
+ const body = slug ? { integration_slug: slug } : { server_url: url };
23633
+ if (!slug && options.header && options.header.length > 0) {
23502
23634
  body.headers = parseHeaderPairs("--header", options.header);
23503
23635
  }
23504
23636
  const config = await requireAuthenticatedConfig(this);
@@ -26423,18 +26555,22 @@ var TABLE_COLUMNS31 = [
26423
26555
  { header: "CREATED", cell: /* @__PURE__ */ __name((row) => row.created_at, "cell") }
26424
26556
  ];
26425
26557
  function registerPulseMessages(pulse) {
26426
- pulse.command("messages <id>").description("List a Pulse dashboard's chat transcript (creator only)").option("--limit <n>", `page size (${MIN_LIMIT12}-${MAX_LIMIT12})`).option("--offset <n>", "number of messages to skip").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function messagesAction(id, options) {
26558
+ pulse.command("messages <id>").description("List a Pulse dashboard's chat transcript (creator only)").option("--limit <n>", `page size (${MIN_LIMIT12}-${MAX_LIMIT12})`).option(
26559
+ "--before <messageId>",
26560
+ "return the page of messages older than this message id (omit for the most recent page)"
26561
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function messagesAction(id, options) {
26427
26562
  const pulseId = trimRequired(id, "<id>");
26428
26563
  const limit = parseLimit(options.limit, {
26429
26564
  defaultValue: DEFAULT_LIMIT12,
26430
26565
  min: MIN_LIMIT12,
26431
26566
  max: MAX_LIMIT12
26432
26567
  });
26433
- const offset = parseOffset(options.offset);
26434
26568
  const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
26435
26569
  const searchParams = new URLSearchParams();
26436
26570
  searchParams.append("limit", String(limit));
26437
- searchParams.append("offset", String(offset));
26571
+ if (options.before) {
26572
+ searchParams.append("before", trimRequired(options.before, "--before"));
26573
+ }
26438
26574
  const raw = await httpRequest({
26439
26575
  method: "GET",
26440
26576
  path: `/v2/artifacts/${encodeURIComponent(pulseId)}/messages`,
@@ -26452,13 +26588,18 @@ function registerPulseMessages(pulse) {
26452
26588
  `Unexpected response from the API: ${parsed.error.message}`
26453
26589
  );
26454
26590
  }
26455
- const { data, total } = parsed.data;
26591
+ const { data, total, has_more: hasMore } = parsed.data;
26456
26592
  if (data.length === 0) {
26457
26593
  console.log("No messages yet.");
26458
26594
  return;
26459
26595
  }
26460
26596
  console.log(renderTable(TABLE_COLUMNS31, data));
26461
- console.log(`Showing ${data.length} of ${total} \xB7 offset ${offset}`);
26597
+ console.log(`Showing ${data.length} of ${total}`);
26598
+ if (hasMore) {
26599
+ console.log(
26600
+ `Older messages available. Rerun with --before ${data[0]?.id} to load them.`
26601
+ );
26602
+ }
26462
26603
  console.log(
26463
26604
  "Run with --json to see full message payloads, including the tool call id `duvo pulse answer` needs."
26464
26605
  );
@@ -30973,7 +31114,7 @@ __name(resolveActiveTeamId, "resolveActiveTeamId");
30973
31114
  var version = resolveVersion();
30974
31115
  function resolveVersion() {
30975
31116
  if (true) {
30976
- return "1.22.0";
31117
+ return "1.24.0";
30977
31118
  }
30978
31119
  const packageJsonPath = join3(
30979
31120
  dirname3(fileURLToPath2(import.meta.url)),
@@ -31167,7 +31308,7 @@ function isNewerVersion(candidate, current) {
31167
31308
  __name(isNewerVersion, "isNewerVersion");
31168
31309
  function loadPackageMeta() {
31169
31310
  if (true) {
31170
- return { name: "@duvoai/cli", version: "1.22.0" };
31311
+ return { name: "@duvoai/cli", version: "1.24.0" };
31171
31312
  }
31172
31313
  const require2 = createRequire(import.meta.url);
31173
31314
  const raw = require2("../package.json");