@duvoai/cli 1.27.0 → 1.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/duvo.js CHANGED
@@ -2255,6 +2255,16 @@ var AGENT_RUN_STATUSES = [
2255
2255
  "interrupted"
2256
2256
  // User interrupted
2257
2257
  ];
2258
+ var TERMINAL_AGENT_RUN_STATUSES = [
2259
+ "completed",
2260
+ "failed",
2261
+ "interrupted"
2262
+ ];
2263
+ function isTerminalAgentRunStatus(status) {
2264
+ return TERMINAL_AGENT_RUN_STATUSES.includes(status);
2265
+ }
2266
+ __name(isTerminalAgentRunStatus, "isTerminalAgentRunStatus");
2267
+ __name2(isTerminalAgentRunStatus, "isTerminalAgentRunStatus");
2258
2268
  var agentRunStatusSchema = z10.enum(AGENT_RUN_STATUSES);
2259
2269
  var AGENT_RUN_SOURCES = [
2260
2270
  "app",
@@ -2503,7 +2513,7 @@ var canExecuteConcurrentResultSchema = z11.object({
2503
2513
  var BrowsingProviderSchema = z12.enum(["google", "anthropic"]);
2504
2514
  var PLATFORM_DEFAULT_MODELS = {
2505
2515
  agent: {
2506
- model: "claude-sonnet-5"
2516
+ model: "claude-sonnet-5[1m]"
2507
2517
  },
2508
2518
  browsing: {
2509
2519
  provider: "google",
@@ -2512,6 +2522,7 @@ var PLATFORM_DEFAULT_MODELS = {
2512
2522
  };
2513
2523
  var CLAUDE_MODEL_IDS = [
2514
2524
  "claude-sonnet-5",
2525
+ "claude-sonnet-5[1m]",
2515
2526
  "claude-opus-4-8",
2516
2527
  "claude-opus-4-8[1m]"
2517
2528
  ];
@@ -2555,6 +2566,10 @@ var AVAILABLE_AGENT_MODELS = {
2555
2566
  displayName: "Claude Sonnet 5",
2556
2567
  description: "Fast and capable for everyday tasks"
2557
2568
  },
2569
+ "claude-sonnet-5[1m]": {
2570
+ displayName: "Claude Sonnet 5",
2571
+ description: "Fast and capable for everyday tasks"
2572
+ },
2558
2573
  "claude-opus-4-8": {
2559
2574
  displayName: "Claude Opus 4.8",
2560
2575
  description: "Our most capable model \u2014 best for complex work"
@@ -2572,21 +2587,28 @@ var BrowsingModelIdSchema = z12.enum([
2572
2587
  "claude-sonnet-4-5",
2573
2588
  "claude-opus-4-1"
2574
2589
  ]);
2575
- var LEGACY_DEFAULT_MODEL = "claude-sonnet-5";
2590
+ var LEGACY_DEFAULT_MODEL = "claude-sonnet-5[1m]";
2576
2591
  var LEGACY_MODEL_REMAP = {
2577
- "claude-sonnet-4-6": "claude-sonnet-5",
2578
- "claude-sonnet-4-6[1m]": "claude-sonnet-5",
2592
+ // Bare Sonnet 5 is still schema-valid (stored configs keep parsing) but is
2593
+ // upgraded to the [1m]-suffixed ID at resolve time so the pinned CLI budgets
2594
+ // the real 1M window instead of its 200K unknown-model fallback.
2595
+ "claude-sonnet-5": "claude-sonnet-5[1m]",
2596
+ "claude-sonnet-4-6": "claude-sonnet-5[1m]",
2597
+ "claude-sonnet-4-6[1m]": "claude-sonnet-5[1m]",
2579
2598
  "claude-opus-4-6": "claude-opus-4-8",
2580
2599
  "claude-opus-4-6[1m]": "claude-opus-4-8[1m]",
2581
2600
  "claude-opus-4-7": "claude-opus-4-8",
2582
2601
  "claude-opus-4-7[1m]": "claude-opus-4-8[1m]"
2583
2602
  };
2584
2603
  function mapModelToClaudeModel(model) {
2604
+ const remapped = model != null && model !== "" ? LEGACY_MODEL_REMAP[model] : void 0;
2605
+ if (remapped) {
2606
+ return remapped;
2607
+ }
2585
2608
  if (model && CLAUDE_MODEL_IDS.includes(model)) {
2586
2609
  return model;
2587
2610
  }
2588
- const remapped = model != null && model !== "" ? LEGACY_MODEL_REMAP[model] : void 0;
2589
- return remapped ?? LEGACY_DEFAULT_MODEL;
2611
+ return LEGACY_DEFAULT_MODEL;
2590
2612
  }
2591
2613
  __name(mapModelToClaudeModel, "mapModelToClaudeModel");
2592
2614
  __name2(mapModelToClaudeModel, "mapModelToClaudeModel");
@@ -3186,7 +3208,63 @@ var clarityProcessListItemSchema = z15.object({
3186
3208
  contributors: z15.array(z15.object({ userId: z15.string(), userName: z15.string() })).optional(),
3187
3209
  createdAt: z15.coerce.date(),
3188
3210
  updatedAt: z15.coerce.date(),
3189
- createdByName: z15.string().optional()
3211
+ createdByName: z15.string().optional(),
3212
+ /** Team-scoped lists only; absent on org portfolio rows. */
3213
+ folderId: z15.guid().nullable().optional(),
3214
+ /**
3215
+ * Read-time folder suggestion: set when the process is unfiled and its
3216
+ * landscape leaf sits under a group node a team folder links to.
3217
+ */
3218
+ suggestedFolderId: z15.guid().nullable().optional()
3219
+ });
3220
+ var clarityProcessFolderSchema = z15.object({
3221
+ id: z15.guid(),
3222
+ teamId: z15.guid(),
3223
+ name: z15.string(),
3224
+ /** Linked landscape group node, or null for plain custom folders. */
3225
+ landscapeNodeId: z15.guid().nullable(),
3226
+ /** Once true, landscape group renames no longer propagate to this folder. */
3227
+ nameOverridden: z15.boolean(),
3228
+ sortOrder: z15.number().int(),
3229
+ createdAt: z15.coerce.date(),
3230
+ updatedAt: z15.coerce.date()
3231
+ });
3232
+ var clarityProcessFolderListItemSchema = clarityProcessFolderSchema.extend({
3233
+ processCount: z15.number(),
3234
+ /** Unfiled team processes whose landscape group matches this folder's link. */
3235
+ suggestedCount: z15.number()
3236
+ });
3237
+ var clarityProcessFolderListResponseSchema = z15.object({
3238
+ folders: z15.array(clarityProcessFolderListItemSchema)
3239
+ });
3240
+ var claritySuccessResponseSchema = z15.object({
3241
+ success: z15.boolean()
3242
+ });
3243
+ var clarityProcessFolderResponseSchema = z15.object({
3244
+ folder: clarityProcessFolderSchema
3245
+ });
3246
+ var clarityMoveProcessesToFolderResponseSchema = z15.object({
3247
+ movedCount: z15.number()
3248
+ });
3249
+ var claritySetupFoldersFromLandscapeResponseSchema = z15.object({
3250
+ folders: z15.array(clarityProcessFolderSchema),
3251
+ createdCount: z15.number()
3252
+ });
3253
+ var clarityFileSuggestedProcessesResponseSchema = z15.object({
3254
+ filedCount: z15.number()
3255
+ });
3256
+ var clarityLandscapeGroupSchema = z15.object({
3257
+ id: z15.guid(),
3258
+ name: z15.string(),
3259
+ sortOrder: z15.number().int(),
3260
+ processCount: z15.number()
3261
+ });
3262
+ var clarityLandscapeGroupListResponseSchema = z15.object({
3263
+ groups: z15.array(clarityLandscapeGroupSchema),
3264
+ /** Team processes whose landscape leaf sits under no group node. */
3265
+ unclassifiedCount: z15.number(),
3266
+ /** True when the bounded read could not return every group. */
3267
+ truncated: z15.boolean()
3190
3268
  });
3191
3269
  var CLARITY_PROCESS_LIST_ORDERS = [
3192
3270
  "updated_desc",
@@ -3337,7 +3415,9 @@ var clarityLandscapeCaptureRequestSchema = z15.object({
3337
3415
  });
3338
3416
  }
3339
3417
  });
3340
- var clarityProcessLandscapeNodeSchema = z15.object({
3418
+ var CLARITY_PROCESS_LANDSCAPE_REDACTED_NODE_HINT = "restricted_process";
3419
+ var clarityProcessLandscapeFullNodeSchema = z15.object({
3420
+ access: z15.literal("full"),
3341
3421
  id: z15.guid(),
3342
3422
  parentId: z15.guid().nullable(),
3343
3423
  processId: z15.guid().nullable(),
@@ -3360,7 +3440,27 @@ var clarityProcessLandscapeNodeSchema = z15.object({
3360
3440
  captureSuggestions: z15.array(clarityLandscapeCaptureSuggestionSchema).default([]),
3361
3441
  captureRequests: z15.array(clarityLandscapeCaptureRequestSchema).default([]),
3362
3442
  labels: z15.array(clarityProcessAssignedLabelSchema).default([])
3363
- });
3443
+ }).strict();
3444
+ var clarityProcessLandscapePublicNodeSchema = clarityProcessLandscapeFullNodeSchema.omit({ access: true }).partial({
3445
+ teamAssignmentSuggestions: true,
3446
+ captureSuggestions: true,
3447
+ captureRequests: true
3448
+ });
3449
+ var clarityProcessLandscapeRedactedNodeSchema = z15.object({
3450
+ access: z15.literal("redacted"),
3451
+ hint: z15.literal(CLARITY_PROCESS_LANDSCAPE_REDACTED_NODE_HINT),
3452
+ id: z15.guid(),
3453
+ parentId: z15.guid().nullable(),
3454
+ sortOrder: z15.number(),
3455
+ depth: z15.number()
3456
+ }).strict();
3457
+ var clarityProcessLandscapeNodeSchema = z15.discriminatedUnion(
3458
+ "access",
3459
+ [
3460
+ clarityProcessLandscapeFullNodeSchema,
3461
+ clarityProcessLandscapeRedactedNodeSchema
3462
+ ]
3463
+ );
3364
3464
  var clarityProcessLandscapeUnlinkedProcessSchema = clarityProcessLandscapeSummarySchema.extend({
3365
3465
  teamId: z15.guid(),
3366
3466
  teamName: z15.string().nullable(),
@@ -3372,7 +3472,8 @@ var clarityProcessLandscapeLinkSchema = z15.object({
3372
3472
  targetNodeId: z15.guid(),
3373
3473
  type: z15.enum(["hands_off_to", "shares_step_with", "variant_of"]),
3374
3474
  state: z15.enum(["suggested", "confirmed"]),
3375
- confidence: z15.number().nullable()
3475
+ confidence: z15.number().nullable(),
3476
+ rationale: z15.string().nullable().default(null)
3376
3477
  });
3377
3478
  var clarityProcessLandscapeStatsSchema = z15.object({
3378
3479
  totalNodes: z15.number(),
@@ -3386,6 +3487,7 @@ var landscapeGenerationResultSummarySchema = z15.object({
3386
3487
  createdNodeCount: z15.number().int().nonnegative(),
3387
3488
  reparentedNodeCount: z15.number().int().nonnegative(),
3388
3489
  attachedProcessCount: z15.number().int().nonnegative(),
3490
+ suggestedRelationshipCount: z15.number().int().nonnegative().default(0),
3389
3491
  unchangedWriteCount: z15.number().int().nonnegative(),
3390
3492
  failedWriteCount: z15.number().int().nonnegative()
3391
3493
  });
@@ -3408,6 +3510,9 @@ var clarityProcessLandscapeResponseSchema = z15.object({
3408
3510
  generation: clarityProcessLandscapeGenerationSchema,
3409
3511
  truncated: z15.boolean()
3410
3512
  });
3513
+ var clarityProcessLandscapePublicResponseSchema = clarityProcessLandscapeResponseSchema.extend({
3514
+ nodes: z15.array(clarityProcessLandscapePublicNodeSchema)
3515
+ });
3411
3516
  var clarityProcessPersonSchema = z15.object({
3412
3517
  id: z15.guid(),
3413
3518
  userId: z15.guid().nullable(),
@@ -5021,9 +5126,15 @@ var clarityProcessLandscapeGenerationStatusChangedEventDataSchema = z21.object({
5021
5126
  status: clarityProcessLandscapeGenerationSchema.shape.status.exclude([
5022
5127
  "idle"
5023
5128
  ]),
5024
- error: z21.string().optional(),
5025
5129
  result: landscapeGenerationResultSummarySchema.optional()
5026
5130
  });
5131
+ var clarityProcessLandscapeChangedEventDataSchema = z21.object({
5132
+ organizationId: z21.guid()
5133
+ });
5134
+ var clarityProcessLandscapeOrganizeStatusChangedEventDataSchema = z21.object({
5135
+ organizationId: z21.guid(),
5136
+ status: z21.enum(["completed", "failed"])
5137
+ });
5027
5138
  var clarityProcessLandscapeRoomPayloadSchema = z21.object({
5028
5139
  organizationId: z21.guid()
5029
5140
  });
@@ -6903,7 +7014,6 @@ var integrationResponseSchema = z27.object({
6903
7014
  server_url: z27.string().optional(),
6904
7015
  transport_type: TransportTypeSchema.optional(),
6905
7016
  auth_method: z27.string().nullable().optional(),
6906
- composio_mcp_id: z27.string().nullable().default(null),
6907
7017
  custom_integration_id: z27.string().nullable().optional(),
6908
7018
  icon_url: z27.string().nullable().optional(),
6909
7019
  oauth_provider: z27.string().nullable().optional(),
@@ -6912,7 +7022,7 @@ var integrationResponseSchema = z27.object({
6912
7022
  * to start the OAuth flow via
6913
7023
  * `POST /v1/connections/oauth/native/:provider/start`. Derived
6914
7024
  * server-side from the integration `type`; null when no native provider
6915
- * exists for the type (default-provider, composio, custom MCP).
7025
+ * exists for the type (default-provider, custom MCP).
6916
7026
  */
6917
7027
  oauth_provider_key: z27.string().nullable().optional(),
6918
7028
  oauth_scopes: z27.array(z27.string()).nullable().optional(),
@@ -7001,15 +7111,6 @@ var checkDcrSupportResponseSchema = z27.object({
7001
7111
  var authorizationUrlResponseSchema = z27.object({
7002
7112
  authorization_url: z27.string().describe("OAuth provider authorization URL to open in a browser")
7003
7113
  });
7004
- var startComposioConnectionResponseSchema = z27.object({
7005
- redirect_url: z27.string().nullable().describe(
7006
- "Browser URL the user must visit to complete authorization. Null when the connection was completed synchronously (e.g. for API_KEY auth that did not require a browser flow)."
7007
- ),
7008
- status: z27.string().nullable().describe("Composio connection status, e.g. INITIATED or ACTIVE."),
7009
- connected_account_id: z27.string().describe(
7010
- "Composio connected-account ID, passed to /v1/connections/composio/finalize to complete the flow."
7011
- )
7012
- });
7013
7114
  var createCustomIntegrationRequestSchema = z27.object({
7014
7115
  name: z27.string().min(1, "Name is required"),
7015
7116
  auth_method: z27.enum(["url", "apikey", "headers", "oauth"]),
@@ -7046,7 +7147,6 @@ var updateIntegrationRequestSchema = z27.object({
7046
7147
  plaintext: z27.record(z27.string(), z27.string()).optional(),
7047
7148
  secret: z27.record(z27.string(), z27.string()).optional()
7048
7149
  }).nullable().optional(),
7049
- composio_mcp_id: z27.string().nullable().optional(),
7050
7150
  // Toggle team sharing. `true` makes the instance team-shared
7051
7151
  // (`user_id = NULL`); `false` reverts it to personal owned by the caller.
7052
7152
  // Rejected when the org-level "Connections sharing" setting is OFF and
@@ -7252,6 +7352,14 @@ var artifactVisibilitySchema = z31.enum([
7252
7352
  "teams"
7253
7353
  ]);
7254
7354
  var artifactPublishPermissionSchema = z31.enum(["view", "edit"]);
7355
+ var artifactRefreshFrequencySchema = z31.enum([
7356
+ "every_15_minutes",
7357
+ "every_30_minutes",
7358
+ "hourly",
7359
+ "every_6_hours",
7360
+ "daily",
7361
+ "weekly"
7362
+ ]);
7255
7363
  var artifactSchema = z31.object({
7256
7364
  id: z31.guid(),
7257
7365
  team_id: z31.guid(),
@@ -7274,6 +7382,13 @@ var artifactSchema = z31.object({
7274
7382
  // image. Optional so older/other clients (and fixtures) tolerate its absence;
7275
7383
  // the backend always includes it (string or null).
7276
7384
  thumbnail_url: z31.string().nullable().optional(),
7385
+ // Background auto-refresh cadence, or null when off. Optional so older
7386
+ // clients and fixtures tolerate its absence; the backend always includes it.
7387
+ refresh_frequency: artifactRefreshFrequencySchema.nullable().optional(),
7388
+ // When the last scheduled refresh was dispatched / the next one is due.
7389
+ // Null until a schedule is set (next) or has fired at least once (last).
7390
+ last_refresh_at: z31.string().nullable().optional(),
7391
+ next_refresh_at: z31.string().nullable().optional(),
7277
7392
  created_at: z31.string(),
7278
7393
  updated_at: z31.string()
7279
7394
  });
@@ -7402,8 +7517,12 @@ var answerArtifactQuestionResponseSchema = z31.object({
7402
7517
  ok: z31.literal(true)
7403
7518
  });
7404
7519
  var updateArtifactBodySchema = z31.object({
7405
- title: z31.string().trim().min(1).max(120)
7406
- }).strict();
7520
+ title: z31.string().trim().min(1).max(120).optional(),
7521
+ refresh_frequency: artifactRefreshFrequencySchema.nullable().optional()
7522
+ }).strict().refine(
7523
+ (body) => body.title !== void 0 || body.refresh_frequency !== void 0,
7524
+ { message: "At least one field is required" }
7525
+ );
7407
7526
  var publishArtifactBodySchema = z31.object({
7408
7527
  visibility: z31.enum(["private", "team", "organization"]),
7409
7528
  // The audience permission to apply when publishing. Applies to the Pulse's
@@ -8329,6 +8448,16 @@ var adminOrgAddMemberRequestSchema = z40.object({
8329
8448
  var adminOrgAddMemberResponseSchema = z40.object({
8330
8449
  member: adminOrgMemberSchema
8331
8450
  });
8451
+ var adminOrgInviteMemberRequestSchema = z40.object({
8452
+ email: z40.email(),
8453
+ role: z40.enum(ORG_ROLES.ALL),
8454
+ frontendUrl: z40.url().optional()
8455
+ });
8456
+ var adminOrgInviteMemberResponseSchema = z40.object({
8457
+ success: z40.literal(true),
8458
+ invitationId: z40.guid(),
8459
+ emailSent: z40.boolean()
8460
+ });
8332
8461
  var adminOrgUpdateMemberRoleRequestSchema = z40.object({
8333
8462
  role: z40.enum(ORG_ROLES.ALL)
8334
8463
  });
@@ -8707,6 +8836,7 @@ var agentApiSchema = z42.object({
8707
8836
  team_id: z42.string().nullable(),
8708
8837
  thread_id: z42.string().nullable(),
8709
8838
  folder_id: z42.string().nullable().optional(),
8839
+ automation_id: z42.guid().nullable().optional(),
8710
8840
  created_at: z42.string().nullable(),
8711
8841
  updated_at: z42.string().nullable(),
8712
8842
  created_by: z42.object({
@@ -9074,6 +9204,33 @@ var automationRevisionDetailResponseApiSchema = z50.object({
9074
9204
  var automationRevisionResponseApiSchema = z50.object({
9075
9205
  revision: automationRevisionSummaryApiSchema.describe("The revision summary")
9076
9206
  });
9207
+ var automationFlowAgentApiSchema = z50.object({
9208
+ id: z50.guid().describe("Agent identifier"),
9209
+ name: z50.string().describe("Agent name")
9210
+ });
9211
+ var automationFlowQueueApiSchema = z50.object({
9212
+ id: z50.guid().describe("Queue identifier"),
9213
+ name: z50.string().describe("Queue name (per-revision override or canonical)"),
9214
+ item_count: z50.int().describe("Active (non-deleted) case count in the queue"),
9215
+ producer_agent_ids: z50.array(z50.guid()).describe("Agents that add cases to this queue"),
9216
+ consumer_agent_ids: z50.array(z50.guid()).describe("Agents that process cases from this queue"),
9217
+ routed_consumer_agent_id: z50.guid().nullable().describe(
9218
+ "Consumer the revision routes new cases to (null when unrouted or disabled)"
9219
+ )
9220
+ });
9221
+ var automationFlowHandoverApiSchema = z50.object({
9222
+ source_agent_id: z50.guid().describe("Agent that hands work over"),
9223
+ target_agent_id: z50.guid().describe("Agent that receives the handover")
9224
+ });
9225
+ var automationFlowApiSchema = z50.object({
9226
+ revision_id: z50.guid().describe("Revision this flow was computed for"),
9227
+ agents: z50.array(automationFlowAgentApiSchema).describe("Agent nodes in the flow"),
9228
+ queues: z50.array(automationFlowQueueApiSchema).describe("Queue nodes in the flow"),
9229
+ handovers: z50.array(automationFlowHandoverApiSchema).describe("Agent \u2192 agent handover edges")
9230
+ });
9231
+ var automationFlowResponseApiSchema = z50.object({
9232
+ flow: automationFlowApiSchema.describe("The revision's flow graph")
9233
+ });
9077
9234
  var AUTOMATION_REVISION_NAME_MAX_LENGTH = 200;
9078
9235
  var AUTOMATION_REVISION_DESCRIPTION_MAX_LENGTH = 2e3;
9079
9236
  var revisionNameFieldSchema = z50.string().trim().min(1).max(AUTOMATION_REVISION_NAME_MAX_LENGTH);
@@ -9114,6 +9271,82 @@ var activateAutomationRevisionResponseApiSchema = z50.object({
9114
9271
  ),
9115
9272
  repinned_case_count: z50.int().describe("Number of pending cases re-pinned onto the activated revision")
9116
9273
  });
9274
+ var automationEntrypointRunApiSchema = z50.object({
9275
+ id: z50.guid().describe("Agent run ID of the entrypoint run"),
9276
+ agent_id: z50.guid().describe("Agent that ran"),
9277
+ build_id: z50.guid().describe("Build the run executed"),
9278
+ agent_name: z50.string().nullable().describe("Display name of the agent that ran"),
9279
+ status: agentRunStatusSchema.describe("Run status"),
9280
+ source: z50.string().nullable().describe("How the run was started (schedule, slack, manual, api, \u2026)"),
9281
+ automation_revision_id: z50.guid().nullable().describe("Revision the run was pinned to (null for legacy runs)"),
9282
+ run_count: z50.int().describe(
9283
+ "Total runs in this run's chain, including the entrypoint run itself"
9284
+ ),
9285
+ produced_case_count: z50.int().describe(
9286
+ "Cases produced by runs in this chain. Non-zero means the chain has something to expand even when run_count is 1 (an unclaimed produced case)"
9287
+ ),
9288
+ eval_summaries: evalSummarySchema.nullable().describe("Evaluation summary for the run, when available"),
9289
+ created_at: z50.string().describe("ISO 8601 creation timestamp"),
9290
+ started_at: z50.string().nullable().describe("ISO 8601 start timestamp"),
9291
+ completed_at: z50.string().nullable().describe("ISO 8601 completion timestamp"),
9292
+ updated_at: z50.string().describe("ISO 8601 last-modified timestamp")
9293
+ });
9294
+ var automationEntrypointRunsListApiSchema = z50.object({
9295
+ runs: z50.array(automationEntrypointRunApiSchema).describe("Entrypoint runs, newest first"),
9296
+ total: z50.int().describe("Total entrypoint runs matching the query"),
9297
+ limit: z50.int().describe("Page size used"),
9298
+ offset: z50.int().describe("Offset used")
9299
+ });
9300
+ var automationRunChainNodeApiSchema = z50.object({
9301
+ id: z50.guid().describe("Agent run ID"),
9302
+ agent_id: z50.guid().describe("Agent that ran"),
9303
+ build_id: z50.guid().describe("Build the run executed"),
9304
+ agent_name: z50.string().nullable().describe("Display name of the agent"),
9305
+ automation_revision_id: z50.guid().nullable().describe("Revision the run was pinned to (null for legacy runs)"),
9306
+ parent_agent_run_id: z50.guid().nullable().describe(
9307
+ "Run that directly caused this run (null for the entrypoint run)"
9308
+ ),
9309
+ parent_relationship: z50.string().nullable().describe(
9310
+ "Why this run was created from its parent (produced_case, handover, retry, \u2026)"
9311
+ ),
9312
+ status: agentRunStatusSchema.describe("Run status"),
9313
+ source: z50.string().nullable().describe("How the run was started"),
9314
+ case_queue_item_id: z50.guid().nullable().describe(
9315
+ "Case this run claimed, when it was triggered by claiming one (nests the run under that case in the tree)"
9316
+ ),
9317
+ eval_summaries: evalSummarySchema.nullable().describe("Evaluation summary for the run, when available"),
9318
+ created_at: z50.string().describe("ISO 8601 creation timestamp"),
9319
+ started_at: z50.string().nullable().describe("ISO 8601 start timestamp"),
9320
+ completed_at: z50.string().nullable().describe("ISO 8601 completion timestamp")
9321
+ });
9322
+ var automationRunChainCaseNodeApiSchema = z50.object({
9323
+ id: z50.guid().describe("Case (case_queue_item) ID"),
9324
+ title: z50.string().nullable().describe("Case title"),
9325
+ queue_id: z50.guid().describe("Queue the case belongs to"),
9326
+ queue_name: z50.string().nullable().describe("Display name of the queue the case was added to"),
9327
+ status: z50.enum([
9328
+ "pending",
9329
+ "in_progress",
9330
+ "needs_input",
9331
+ "postponed",
9332
+ "completed",
9333
+ "failed"
9334
+ ]).describe("Derived case display status"),
9335
+ producer_run_id: z50.guid().describe("Run that produced this case \u2014 its parent in the tree"),
9336
+ created_at: z50.string().describe("ISO 8601 creation timestamp")
9337
+ });
9338
+ var automationRunChainResponseApiSchema = z50.object({
9339
+ entrypoint_run_id: z50.guid().describe(
9340
+ "The chain's entrypoint run \u2014 resolved from the requested run, which may be any run in the chain"
9341
+ ),
9342
+ runs: z50.array(automationRunChainNodeApiSchema).describe("All runs in the chain, oldest first"),
9343
+ cases: z50.array(automationRunChainCaseNodeApiSchema).describe(
9344
+ "Cases produced by runs in the chain, each nested under its producer run"
9345
+ ),
9346
+ truncated: z50.boolean().describe(
9347
+ "True when the chain exceeded the server cap and only the first runs are returned, so the rendered tree is incomplete"
9348
+ )
9349
+ });
9117
9350
  var BROWSER_EGRESS_MODES = [
9118
9351
  "provider",
9119
9352
  "direct",
@@ -9706,6 +9939,10 @@ var caseQueueSchema = z60.object({
9706
9939
  // Optional (additive) so existing CaseQueue consumers and fixtures across the
9707
9940
  // FE/CLI don't break; the backend always populates it on real responses.
9708
9941
  automation_id: z60.guid().nullable().optional(),
9942
+ // Optional (additive), populated by the get-queue route. Consumers use it to
9943
+ // confirm a queue belongs to the acting team before building team-scoped
9944
+ // links (e.g. the automation-shell redirect resolver).
9945
+ team_id: z60.string().nullable().optional(),
9709
9946
  created_at: z60.string(),
9710
9947
  /**
9711
9948
  * True when at least one case in this queue has ever had an approval
@@ -9973,6 +10210,11 @@ var FEATURE_FLAG_CATALOGUE = {
9973
10210
  defaultValue: false,
9974
10211
  description: "Enables the Clarity meeting notetaker (Recall.ai bot). When disabled, the 'Meeting Notetaker' option is hidden in the Add Content menu and the POST /clarity/processes/:id/captures/meeting invite route returns 404; the Recall webhook callback is unaffected. Off-by-default for staged rollout."
9975
10212
  },
10213
+ CLARITY_REALTIME_SDP_PROXY: {
10214
+ key: "clarity_realtime_sdp_proxy",
10215
+ defaultValue: false,
10216
+ description: "Routes the Clarity interview WebRTC signaling (SDP offer/answer exchange) through the Duvo backend instead of the browser calling api.openai.com directly, so interviews can start on corporate networks that domain-block OpenAI. Voice/screen media still flows browser-to-OpenAI over WebRTC. Off-by-default for staged rollout; does not help networks that block UDP (those need a TURN relay)."
10217
+ },
9976
10218
  CLARITY_SIGNAVIO_SWIMLANES_EXPORT: {
9977
10219
  key: "clarity_signavio_swimlanes_export",
9978
10220
  defaultValue: false,
@@ -10058,6 +10300,11 @@ var FEATURE_FLAG_CATALOGUE = {
10058
10300
  defaultValue: false,
10059
10301
  description: "Enables portfolio intelligence analysis in the Clarity sidebar, providing cross-process insights and recommendations."
10060
10302
  },
10303
+ PULSE_SCHEDULED_REFRESH: {
10304
+ key: "pulse_scheduled_refresh",
10305
+ defaultValue: false,
10306
+ description: "Enables Pulse scheduled background auto-refresh: the Auto-refresh menu in the Pulse header, the `refresh_frequency` field on PATCH /artifacts/:id, and dispatching by the scheduled-refresh cron (already-armed schedules pause while off). The manual Refresh data button is unaffected. Off-by-default for staged rollout."
10307
+ },
10061
10308
  SHARED_CONNECTIONS: {
10062
10309
  key: "shared_connections",
10063
10310
  defaultValue: false,
@@ -11389,6 +11636,53 @@ function deriveHostnameFromInput(input) {
11389
11636
  }
11390
11637
  __name(deriveHostnameFromInput, "deriveHostnameFromInput");
11391
11638
  __name2(deriveHostnameFromInput, "deriveHostnameFromInput");
11639
+ function isHostLikeIdentifier(value) {
11640
+ const host = deriveHostnameFromInput(value);
11641
+ if (!host) {
11642
+ return false;
11643
+ }
11644
+ if (/\s/.test(host)) {
11645
+ return false;
11646
+ }
11647
+ return host.includes(".") || host === "localhost";
11648
+ }
11649
+ __name(isHostLikeIdentifier, "isHostLikeIdentifier");
11650
+ __name2(isHostLikeIdentifier, "isHostLikeIdentifier");
11651
+ function normalizeAppName(value) {
11652
+ return value.trim().toLowerCase().replace(/\s+/g, " ");
11653
+ }
11654
+ __name(normalizeAppName, "normalizeAppName");
11655
+ __name2(normalizeAppName, "normalizeAppName");
11656
+ function normalizeCredentialIdentifier(input) {
11657
+ const trimmed = (input || "").trim();
11658
+ if (!trimmed) {
11659
+ return "";
11660
+ }
11661
+ return isHostLikeIdentifier(trimmed) ? deriveDomain(trimmed) : trimmed;
11662
+ }
11663
+ __name(normalizeCredentialIdentifier, "normalizeCredentialIdentifier");
11664
+ __name2(normalizeCredentialIdentifier, "normalizeCredentialIdentifier");
11665
+ function identifiersMatch(a, b) {
11666
+ if (!a || !b) {
11667
+ return false;
11668
+ }
11669
+ const aIsHost = isHostLikeIdentifier(a);
11670
+ const bIsHost = isHostLikeIdentifier(b);
11671
+ if (aIsHost && bIsHost) {
11672
+ const hostA = deriveDomain(a);
11673
+ const hostB = deriveDomain(b);
11674
+ if (!hostA || !hostB) {
11675
+ return false;
11676
+ }
11677
+ return hostA === hostB || hostA.endsWith(`.${hostB}`) || hostB.endsWith(`.${hostA}`);
11678
+ }
11679
+ if (!aIsHost && !bIsHost) {
11680
+ return normalizeAppName(a) === normalizeAppName(b);
11681
+ }
11682
+ return false;
11683
+ }
11684
+ __name(identifiersMatch, "identifiersMatch");
11685
+ __name2(identifiersMatch, "identifiersMatch");
11392
11686
  var AGENT_MENTION_REGEX_SOURCE = `<DUVO:AGENT\\s+id="((?:[^"\\\\]|\\\\.)*)"\\s+name="((?:[^"\\\\]|\\\\.)*)">`;
11393
11687
  function unescapeAttrValue(value) {
11394
11688
  return value.replace(/\\(.)/g, "$1");
@@ -16198,7 +16492,6 @@ var integrationSchema = z89.object({
16198
16492
  server_url: z89.string().optional(),
16199
16493
  transport_type: z89.string().optional(),
16200
16494
  auth_method: z89.string().nullish(),
16201
- composio_mcp_id: z89.string().nullish(),
16202
16495
  custom_integration_id: z89.string().nullish(),
16203
16496
  icon_url: z89.string().nullish(),
16204
16497
  oauth_provider: z89.string().nullish(),
@@ -21319,7 +21612,8 @@ var processSummarySchema = z99.object({
21319
21612
  id: z99.string(),
21320
21613
  name: z99.string()
21321
21614
  }).passthrough();
21322
- var landscapeNodeSchema = z99.object({
21615
+ var landscapeFullNodeSchema = z99.object({
21616
+ access: z99.literal("full").default("full"),
21323
21617
  id: z99.string(),
21324
21618
  parentId: z99.string().nullable(),
21325
21619
  processId: z99.string().nullable(),
@@ -21327,6 +21621,18 @@ var landscapeNodeSchema = z99.object({
21327
21621
  ownerLabel: z99.string().nullable(),
21328
21622
  process: processSummarySchema.nullable()
21329
21623
  }).passthrough();
21624
+ var landscapeRedactedNodeSchema = z99.object({
21625
+ access: z99.literal("redacted"),
21626
+ hint: z99.literal("restricted_process"),
21627
+ id: z99.string(),
21628
+ parentId: z99.string().nullable(),
21629
+ sortOrder: z99.number(),
21630
+ depth: z99.number()
21631
+ }).strict();
21632
+ var landscapeNodeSchema = z99.union([
21633
+ landscapeFullNodeSchema,
21634
+ landscapeRedactedNodeSchema
21635
+ ]);
21330
21636
  var unlinkedProcessSchema = processSummarySchema.extend({
21331
21637
  teamId: z99.string(),
21332
21638
  teamName: z99.string().nullable()
@@ -21408,10 +21714,14 @@ var LANDSCAPE_COLUMNS = [
21408
21714
  maxWidth: 36
21409
21715
  },
21410
21716
  { header: "TYPE", cell: getLandscapeNodeType },
21411
- { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell"), maxWidth: 28 },
21717
+ {
21718
+ header: "NAME",
21719
+ cell: /* @__PURE__ */ __name((row) => row.access === "redacted" ? "Restricted process" : row.name, "cell"),
21720
+ maxWidth: 28
21721
+ },
21412
21722
  {
21413
21723
  header: "PROCESS",
21414
- cell: /* @__PURE__ */ __name((row) => row.process?.name ?? "-", "cell"),
21724
+ cell: /* @__PURE__ */ __name((row) => row.access === "redacted" ? "-" : row.process?.name ?? "-", "cell"),
21415
21725
  maxWidth: 28
21416
21726
  }
21417
21727
  ];
@@ -21575,7 +21885,7 @@ function registerClarityLandscape(clarity) {
21575
21885
  }
21576
21886
  renderCaptures(response, "No landscape captures found.");
21577
21887
  }, "capturesAction"));
21578
- landscape.command("propose-process").description("Propose a new process node in the Clarity process landscape").requiredOption("--name <name>", "proposed process name").option("--description <text>", "proposed process description").option("--parent <node-id>", "parent area node id").option("--org <org-id>", ORG_FLAG_DESCRIPTION).option("--json", "output JSON").action(/* @__PURE__ */ __name(async function proposeProcessAction(options) {
21888
+ landscape.command("propose-process").description("Create a process node in the Clarity process landscape").requiredOption("--name <name>", "process name").option("--description <text>", "process description").option("--parent <node-id>", "parent area node id").option("--team <team-id>", "owning team id").option("--org <org-id>", ORG_FLAG_DESCRIPTION).option("--json", "output JSON").action(/* @__PURE__ */ __name(async function proposeProcessAction(options) {
21579
21889
  const config = await requireAuthenticatedConfig(this);
21580
21890
  const path = resolveOrgPath(this, PROPOSED_PROCESSES_RESOURCE_PATH);
21581
21891
  const raw = await httpRequest({
@@ -21583,10 +21893,13 @@ function registerClarityLandscape(clarity) {
21583
21893
  path,
21584
21894
  apiKey: config.apiKey,
21585
21895
  apiBaseUrl: config.apiBaseUrl,
21586
- body: buildProposeProcessBody(options)
21896
+ body: buildProposeProcessBody({
21897
+ ...options,
21898
+ team: this.optsWithGlobals().team
21899
+ })
21587
21900
  });
21588
21901
  const node = nodeResponseSchema.parse(raw);
21589
- renderNodeMutationResult("Proposed process", node, options);
21902
+ renderNodeMutationResult("Process created", node, options);
21590
21903
  }, "proposeProcessAction"));
21591
21904
  }
21592
21905
  __name(registerClarityLandscape, "registerClarityLandscape");
@@ -21632,7 +21945,8 @@ function buildProposeProcessBody(options) {
21632
21945
  return {
21633
21946
  name: options.name,
21634
21947
  ...options.description !== void 0 ? { description: options.description } : {},
21635
- ...options.parent !== void 0 ? { parentId: options.parent } : {}
21948
+ ...options.parent !== void 0 ? { parentId: options.parent } : {},
21949
+ ...options.team !== void 0 ? { teamId: options.team } : {}
21636
21950
  };
21637
21951
  }
21638
21952
  __name(buildProposeProcessBody, "buildProposeProcessBody");
@@ -21758,6 +22072,9 @@ function renderNodeMutationResult(label, node, options) {
21758
22072
  }
21759
22073
  __name(renderNodeMutationResult, "renderNodeMutationResult");
21760
22074
  function searchableLandscapeNodeText(node) {
22075
+ if (node.access === "redacted") {
22076
+ return [node.id, node.parentId ?? ""];
22077
+ }
21761
22078
  return [
21762
22079
  node.id,
21763
22080
  node.parentId ?? "",
@@ -21770,6 +22087,9 @@ function searchableLandscapeNodeText(node) {
21770
22087
  }
21771
22088
  __name(searchableLandscapeNodeText, "searchableLandscapeNodeText");
21772
22089
  function getLandscapeNodeType(node) {
22090
+ if (node.access === "redacted") {
22091
+ return PROCESS_NODE_TYPE;
22092
+ }
21773
22093
  return node.processId ? PROCESS_NODE_TYPE : AREA_NODE_TYPE;
21774
22094
  }
21775
22095
  __name(getLandscapeNodeType, "getLandscapeNodeType");
@@ -22395,6 +22715,7 @@ var processLinkSchema = z101.object({
22395
22715
  type: processLinkTypeSchema,
22396
22716
  state: processLinkStateSchema,
22397
22717
  confidence: z101.number().nullable(),
22718
+ rationale: z101.string().nullable().default(null),
22398
22719
  created_at: z101.string(),
22399
22720
  updated_at: z101.string()
22400
22721
  });
@@ -22428,6 +22749,11 @@ var PROCESS_LINK_COLUMNS = [
22428
22749
  {
22429
22750
  header: "CONF",
22430
22751
  cell: /* @__PURE__ */ __name((row) => row.confidence === null ? "-" : row.confidence.toFixed(2), "cell")
22752
+ },
22753
+ {
22754
+ header: "RATIONALE",
22755
+ cell: /* @__PURE__ */ __name((row) => row.rationale ?? "-", "cell"),
22756
+ maxWidth: 60
22431
22757
  }
22432
22758
  ];
22433
22759
  function registerClarityProcessLinks(clarity) {
@@ -22594,6 +22920,9 @@ function renderProcessLinks(response) {
22594
22920
  return;
22595
22921
  }
22596
22922
  console.log(renderTable(PROCESS_LINK_COLUMNS, response.process_links));
22923
+ console.log(
22924
+ "Source and target nodes can belong to different teams in this organization."
22925
+ );
22597
22926
  console.log("");
22598
22927
  console.log(
22599
22928
  `Showing ${response.process_links.length} of ${response.total} \xB7 offset ${response.offset}`
@@ -23836,10 +24165,7 @@ function registerConnectionsUpdate(connections) {
23836
24165
  ...previous ?? [],
23837
24166
  value
23838
24167
  ]
23839
- ).option("--clear-headers", "remove all configured headers").option("--composio-mcp-id <id>", "associate a Composio MCP server ID").option(
23840
- "--clear-composio-mcp-id",
23841
- "remove the Composio MCP server association"
23842
- ).option("--share", "share this connection with the team (manager+ only)").option("--unshare", "revert this connection to personal").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function updateAction(id, options) {
24168
+ ).option("--clear-headers", "remove all configured headers").option("--share", "share this connection with the team (manager+ only)").option("--unshare", "revert this connection to personal").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function updateAction(id, options) {
23843
24169
  if (options.share && options.unshare) {
23844
24170
  throw new CliError("Pass either --share or --unshare, not both.");
23845
24171
  }
@@ -23848,11 +24174,6 @@ function registerConnectionsUpdate(connections) {
23848
24174
  "Pass either --clear-headers or --header / --secret-header, not both."
23849
24175
  );
23850
24176
  }
23851
- if (options.composioMcpId !== void 0 && Boolean(options.clearComposioMcpId)) {
23852
- throw new CliError(
23853
- "Pass either --composio-mcp-id or --clear-composio-mcp-id, not both."
23854
- );
23855
- }
23856
24177
  const body = {};
23857
24178
  if (options.name !== void 0) {
23858
24179
  const trimmed = options.name.trim();
@@ -23891,15 +24212,6 @@ function registerConnectionsUpdate(connections) {
23891
24212
  }
23892
24213
  body.headers = headers;
23893
24214
  }
23894
- if (options.composioMcpId !== void 0) {
23895
- const trimmed = options.composioMcpId.trim();
23896
- if (trimmed.length === 0) {
23897
- throw new CliError("--composio-mcp-id must not be empty");
23898
- }
23899
- body.composio_mcp_id = trimmed;
23900
- } else if (options.clearComposioMcpId) {
23901
- body.composio_mcp_id = null;
23902
- }
23903
24215
  if (options.share) {
23904
24216
  body.shared = true;
23905
24217
  } else if (options.unshare) {
@@ -23907,7 +24219,7 @@ function registerConnectionsUpdate(connections) {
23907
24219
  }
23908
24220
  if (Object.keys(body).length === 0) {
23909
24221
  throw new CliError(
23910
- "Provide at least one field to update (--name, --server-url, --auth-method, --header, --secret-header, --clear-headers, --composio-mcp-id, --clear-composio-mcp-id, --share, --unshare)."
24222
+ "Provide at least one field to update (--name, --server-url, --auth-method, --header, --secret-header, --clear-headers, --share, --unshare)."
23911
24223
  );
23912
24224
  }
23913
24225
  const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
@@ -25574,184 +25886,6 @@ async function revokeOAuthProfile(profile) {
25574
25886
  }
25575
25887
  __name(revokeOAuthProfile, "revokeOAuthProfile");
25576
25888
 
25577
- // src/commands/oauth/composio/connect.ts
25578
- function registerOauthComposioConnect(composio) {
25579
- composio.command("connect").description(
25580
- "Finalize a Composio-backed connection after the start step has produced a connected_account_id."
25581
- ).requiredOption(
25582
- "--app <slug>",
25583
- "Composio app slug (e.g. 'slack', 'googlesheets')"
25584
- ).requiredOption(
25585
- "--name <name>",
25586
- "human-readable name to display for the connection"
25587
- ).requiredOption(
25588
- "--connected-account-id <id>",
25589
- "Composio connected-account ID returned by `duvo oauth composio start`"
25590
- ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function connectComposioAction(options) {
25591
- const config = await requireAuthenticatedConfig(this);
25592
- const { apiKey, apiBaseUrl } = config;
25593
- const teamId = await resolveRequiredTeamId(config, {
25594
- override: getTeamFlag(this)
25595
- });
25596
- if (!options.app || options.app.trim().length === 0) {
25597
- throw new CliError("--app must not be empty");
25598
- }
25599
- if (!options.name || options.name.trim().length === 0) {
25600
- throw new CliError("--name must not be empty");
25601
- }
25602
- if (!options.connectedAccountId || options.connectedAccountId.trim().length === 0) {
25603
- throw new CliError("--connected-account-id must not be empty");
25604
- }
25605
- const body = {
25606
- app: options.app.trim(),
25607
- integration_name: options.name.trim(),
25608
- connected_account_id: options.connectedAccountId.trim()
25609
- };
25610
- const raw = await httpRequest({
25611
- method: "POST",
25612
- path: buildTeamPath(teamId, "/connections/composio/finalize"),
25613
- apiKey,
25614
- apiBaseUrl,
25615
- body
25616
- });
25617
- if (options.json) {
25618
- printJson(raw);
25619
- return;
25620
- }
25621
- const parsed = connectIntegrationResponseSchema.safeParse(raw);
25622
- if (!parsed.success) {
25623
- throw new CliError(
25624
- `Unexpected response from the API: ${parsed.error.message}`
25625
- );
25626
- }
25627
- const { integration_id, mcp_url } = parsed.data;
25628
- console.log(green("Connection created!"));
25629
- console.log();
25630
- console.log(
25631
- renderKeyValue([
25632
- { label: "Integration ID", value: integration_id },
25633
- { label: "MCP URL", value: mcp_url }
25634
- ])
25635
- );
25636
- }, "connectComposioAction"));
25637
- }
25638
- __name(registerOauthComposioConnect, "registerOauthComposioConnect");
25639
-
25640
- // src/commands/oauth/composio/start.ts
25641
- function collectKeyValue(value, previous) {
25642
- return [...previous, value];
25643
- }
25644
- __name(collectKeyValue, "collectKeyValue");
25645
- function parseAuthFields(raw) {
25646
- if (!raw || raw.length === 0) {
25647
- return void 0;
25648
- }
25649
- const result = {};
25650
- for (const entry of raw) {
25651
- const index = entry.indexOf("=");
25652
- if (index <= 0) {
25653
- throw new CliError(
25654
- `--auth-field must be in KEY=VALUE format (got "${entry}")`
25655
- );
25656
- }
25657
- const key = entry.slice(0, index).trim();
25658
- const value = entry.slice(index + 1);
25659
- if (key.length === 0) {
25660
- throw new CliError(`--auth-field key must not be empty (got "${entry}")`);
25661
- }
25662
- result[key] = value;
25663
- }
25664
- return result;
25665
- }
25666
- __name(parseAuthFields, "parseAuthFields");
25667
- function registerOauthComposioStart(composio) {
25668
- composio.command("start").description(
25669
- "Start a Composio-backed OAuth connection. Returns a redirect URL to open in a browser; afterwards run `duvo oauth composio connect` to finalize."
25670
- ).requiredOption(
25671
- "--auth-config <id>",
25672
- "Composio auth-config ID for the toolkit"
25673
- ).requiredOption(
25674
- "--callback-url <url>",
25675
- "where to send the user's browser after they finish the Composio consent screen"
25676
- ).option(
25677
- "--auth-scheme <scheme>",
25678
- "Composio auth scheme (e.g. OAUTH2, API_KEY, BEARER_TOKEN); required when using --auth-field"
25679
- ).option(
25680
- "--auth-field <key=value>",
25681
- "auth field for non-OAuth schemes; repeat for multiple",
25682
- collectKeyValue,
25683
- []
25684
- ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function startComposioAction(options) {
25685
- const config = await requireAuthenticatedConfig(this);
25686
- const { apiKey, apiBaseUrl } = config;
25687
- const teamId = await resolveRequiredTeamId(config, {
25688
- override: getTeamFlag(this)
25689
- });
25690
- if (!options.authConfig || options.authConfig.trim().length === 0) {
25691
- throw new CliError("--auth-config must not be empty");
25692
- }
25693
- if (!options.callbackUrl || options.callbackUrl.trim().length === 0) {
25694
- throw new CliError("--callback-url must not be empty");
25695
- }
25696
- const authFields = parseAuthFields(options.authField);
25697
- const trimmedAuthScheme = options.authScheme?.trim();
25698
- if (authFields && !trimmedAuthScheme) {
25699
- throw new CliError(
25700
- "--auth-scheme is required when --auth-field is provided"
25701
- );
25702
- }
25703
- const body = {
25704
- auth_config_id: options.authConfig.trim(),
25705
- callback_url: options.callbackUrl.trim()
25706
- };
25707
- if (options.authScheme !== void 0) {
25708
- if (trimmedAuthScheme === void 0 || trimmedAuthScheme.length === 0) {
25709
- throw new CliError("--auth-scheme must not be empty");
25710
- }
25711
- body.auth_scheme = trimmedAuthScheme;
25712
- }
25713
- if (authFields) {
25714
- body.auth_fields = authFields;
25715
- }
25716
- const raw = await httpRequest({
25717
- method: "POST",
25718
- path: buildTeamPath(teamId, "/connections/composio/start"),
25719
- apiKey,
25720
- apiBaseUrl,
25721
- body
25722
- });
25723
- if (options.json) {
25724
- printJson(raw);
25725
- return;
25726
- }
25727
- const parsed = startComposioConnectionResponseSchema.safeParse(raw);
25728
- if (!parsed.success) {
25729
- throw new CliError(
25730
- `Unexpected response from the API: ${parsed.error.message}`
25731
- );
25732
- }
25733
- const { redirect_url, status, connected_account_id } = parsed.data;
25734
- console.log(
25735
- renderKeyValue([
25736
- { label: "Connected Account ID", value: connected_account_id },
25737
- { label: "Status", value: status ?? "" },
25738
- { label: "Redirect URL", value: redirect_url ?? "" }
25739
- ])
25740
- );
25741
- }, "startComposioAction"));
25742
- }
25743
- __name(registerOauthComposioStart, "registerOauthComposioStart");
25744
-
25745
- // src/commands/oauth/composio/index.ts
25746
- function registerOauthComposio(oauth) {
25747
- const composio = oauth.command("composio").description(
25748
- "Composio-backed OAuth flows. Run `start` to get a redirect URL, then `connect` to finalize."
25749
- );
25750
- registerOauthComposioStart(composio);
25751
- registerOauthComposioConnect(composio);
25752
- }
25753
- __name(registerOauthComposio, "registerOauthComposio");
25754
-
25755
25889
  // src/commands/oauth/mcp/authorize.ts
25756
25890
  function registerOauthMcpAuthorize(mcp) {
25757
25891
  mcp.command("authorize").description(
@@ -25876,10 +26010,10 @@ function registerOauthMcpCheck(mcp) {
25876
26010
  __name(registerOauthMcpCheck, "registerOauthMcpCheck");
25877
26011
 
25878
26012
  // src/commands/oauth/mcp/probe.ts
25879
- function collectKeyValue2(value, previous) {
26013
+ function collectKeyValue(value, previous) {
25880
26014
  return [...previous, value];
25881
26015
  }
25882
- __name(collectKeyValue2, "collectKeyValue");
26016
+ __name(collectKeyValue, "collectKeyValue");
25883
26017
  function parseHeaders(raw) {
25884
26018
  if (!raw || raw.length === 0) {
25885
26019
  return void 0;
@@ -25912,7 +26046,7 @@ function registerOauthMcpProbe(mcp) {
25912
26046
  ).option(
25913
26047
  "--header <key=value>",
25914
26048
  "optional HTTP header for authentication; repeat for multiple",
25915
- collectKeyValue2,
26049
+ collectKeyValue,
25916
26050
  []
25917
26051
  ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function probeMcpAction(url, options) {
25918
26052
  const trimmedUrl = url.trim();
@@ -26046,7 +26180,6 @@ __name(registerOauthNative, "registerOauthNative");
26046
26180
  function registerOauth(program) {
26047
26181
  const oauth = program.command("oauth").description("Start and probe OAuth flows for Duvo connections");
26048
26182
  registerOauthNative(oauth);
26049
- registerOauthComposio(oauth);
26050
26183
  registerOauthMcp(oauth);
26051
26184
  }
26052
26185
  __name(registerOauth, "registerOauth");
@@ -26889,6 +27022,69 @@ function registerPulsePdf(pulse) {
26889
27022
  }
26890
27023
  __name(registerPulsePdf, "registerPulsePdf");
26891
27024
 
27025
+ // src/commands/pulse/refresh-schedule.ts
27026
+ var OFF = "off";
27027
+ var FREQUENCY_CHOICES = [...artifactRefreshFrequencySchema.options, OFF].join(
27028
+ ", "
27029
+ );
27030
+ function parseFrequency2(raw) {
27031
+ if (raw === OFF) {
27032
+ return null;
27033
+ }
27034
+ const parsed = artifactRefreshFrequencySchema.safeParse(raw);
27035
+ if (!parsed.success) {
27036
+ throw new CliError(`--frequency must be one of: ${FREQUENCY_CHOICES}.`);
27037
+ }
27038
+ return parsed.data;
27039
+ }
27040
+ __name(parseFrequency2, "parseFrequency");
27041
+ function registerPulseRefreshSchedule(pulse) {
27042
+ pulse.command("refresh-schedule <id>").description(
27043
+ "Set how often a Pulse dashboard auto-refreshes in the background (creator only)"
27044
+ ).requiredOption(
27045
+ "--frequency <frequency>",
27046
+ `the auto-refresh cadence: ${FREQUENCY_CHOICES}`
27047
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function refreshScheduleAction(id, options) {
27048
+ const pulseId = trimRequired(id, "<id>");
27049
+ const frequency = parseFrequency2(
27050
+ trimRequired(options.frequency ?? "", "--frequency")
27051
+ );
27052
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
27053
+ const raw = await httpRequest({
27054
+ method: "PATCH",
27055
+ path: `/v2/artifacts/${encodeURIComponent(pulseId)}`,
27056
+ apiKey,
27057
+ apiBaseUrl,
27058
+ body: { refresh_frequency: frequency }
27059
+ });
27060
+ if (options.json) {
27061
+ printJson(raw);
27062
+ return;
27063
+ }
27064
+ const parsed = artifactSchema.safeParse(raw);
27065
+ if (!parsed.success) {
27066
+ throw new CliError(
27067
+ `Unexpected response from the API: ${parsed.error.message}`
27068
+ );
27069
+ }
27070
+ console.log(
27071
+ frequency ? green("Pulse auto-refresh scheduled.") : green("Pulse auto-refresh turned off.")
27072
+ );
27073
+ console.log();
27074
+ console.log(
27075
+ renderKeyValue([
27076
+ { label: "ID", value: parsed.data.id },
27077
+ { label: "Frequency", value: parsed.data.refresh_frequency ?? OFF },
27078
+ {
27079
+ label: "Next refresh",
27080
+ value: parsed.data.next_refresh_at ?? "\u2014"
27081
+ }
27082
+ ])
27083
+ );
27084
+ }, "refreshScheduleAction"));
27085
+ }
27086
+ __name(registerPulseRefreshSchedule, "registerPulseRefreshSchedule");
27087
+
26892
27088
  // src/commands/pulse/refresh.ts
26893
27089
  function registerPulseRefresh(pulse) {
26894
27090
  pulse.command("refresh <id>").description(
@@ -27256,6 +27452,7 @@ function registerPulse(program) {
27256
27452
  registerPulseStop(pulse);
27257
27453
  registerPulseRefresh(pulse);
27258
27454
  registerPulseRename(pulse);
27455
+ registerPulseRefreshSchedule(pulse);
27259
27456
  registerPulseShare(pulse);
27260
27457
  registerPulseDuplicate(pulse);
27261
27458
  registerPulseMove(pulse);
@@ -29558,7 +29755,7 @@ __name(registerSandboxes, "registerSandboxes");
29558
29755
 
29559
29756
  // src/commands/secrets/parse-key-value.ts
29560
29757
  var ENV_VAR_KEY_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
29561
- function collectKeyValue3(flag, raw, previous) {
29758
+ function collectKeyValue2(flag, raw, previous) {
29562
29759
  const equalsIndex = raw.indexOf("=");
29563
29760
  if (equalsIndex <= 0) {
29564
29761
  throw new CliError(`${flag} must be in the form KEY=VALUE (got "${raw}")`);
@@ -29578,7 +29775,7 @@ function collectKeyValue3(flag, raw, previous) {
29578
29775
  accumulator[key] = value;
29579
29776
  return accumulator;
29580
29777
  }
29581
- __name(collectKeyValue3, "collectKeyValue");
29778
+ __name(collectKeyValue2, "collectKeyValue");
29582
29779
  function collectRename(flag, raw, previous) {
29583
29780
  const equalsIndex = raw.indexOf("=");
29584
29781
  if (equalsIndex <= 0) {
@@ -29632,7 +29829,7 @@ function registerSecretsCreate(secrets) {
29632
29829
  ).option("--shared", "create as team-shared (requires manager role)").requiredOption(
29633
29830
  "--value <KEY=VALUE>",
29634
29831
  "env var to store (repeat for multiple)",
29635
- collectKeyValue3.bind(null, "--value"),
29832
+ collectKeyValue2.bind(null, "--value"),
29636
29833
  void 0
29637
29834
  ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function createAction(options) {
29638
29835
  const name = trimRequired(options.name ?? "", "--name");
@@ -29823,7 +30020,7 @@ function registerSecretsUpdate(secrets) {
29823
30020
  ).option("--name <name>", "new name").option("--service-slug <slug>", "set the service slug").option("--clear-service-slug", "remove the service slug").option("--shared", "promote to team-shared (requires manager role)").option("--personal", "demote to personal (requires manager role)").option(
29824
30021
  "--set <KEY=VALUE>",
29825
30022
  "add or overwrite an env var (repeatable)",
29826
- collectKeyValue3.bind(null, "--set"),
30023
+ collectKeyValue2.bind(null, "--set"),
29827
30024
  void 0
29828
30025
  ).option(
29829
30026
  "--remove <KEY>",
@@ -31443,7 +31640,7 @@ __name(resolveActiveTeamId, "resolveActiveTeamId");
31443
31640
  var version = resolveVersion();
31444
31641
  function resolveVersion() {
31445
31642
  if (true) {
31446
- return "1.27.0";
31643
+ return "1.28.1";
31447
31644
  }
31448
31645
  const packageJsonPath = join3(
31449
31646
  dirname3(fileURLToPath2(import.meta.url)),
@@ -31637,7 +31834,7 @@ function isNewerVersion(candidate, current) {
31637
31834
  __name(isNewerVersion, "isNewerVersion");
31638
31835
  function loadPackageMeta() {
31639
31836
  if (true) {
31640
- return { name: "@duvoai/cli", version: "1.27.0" };
31837
+ return { name: "@duvoai/cli", version: "1.28.1" };
31641
31838
  }
31642
31839
  const require2 = createRequire(import.meta.url);
31643
31840
  const raw = require2("../package.json");