@duvoai/cli 1.45.2 → 1.45.3

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
@@ -1126,20 +1126,24 @@ var customerPortalResponseSchema = z22.object({
1126
1126
  var PRODUCT = {
1127
1127
  AUTOMATION: "automation",
1128
1128
  CLARITY: "clarity",
1129
+ PULSE: "pulse",
1129
1130
  PLATFORM: "platform"
1130
1131
  };
1131
1132
  var PRODUCT_KEYS = [
1132
1133
  PRODUCT.AUTOMATION,
1133
1134
  PRODUCT.CLARITY,
1135
+ PRODUCT.PULSE,
1134
1136
  PRODUCT.PLATFORM
1135
1137
  ];
1136
1138
  var CUSTOMER_VISIBLE_PRODUCTS = [
1137
1139
  PRODUCT.AUTOMATION,
1138
- PRODUCT.CLARITY
1140
+ PRODUCT.CLARITY,
1141
+ PRODUCT.PULSE
1139
1142
  ];
1140
1143
  var PRODUCT_FEATURE_COMPATIBILITY = {
1141
1144
  [PRODUCT.AUTOMATION]: [],
1142
1145
  [PRODUCT.CLARITY]: [PLAN_FEATURE.CLARITY],
1146
+ [PRODUCT.PULSE]: [],
1143
1147
  [PRODUCT.PLATFORM]: []
1144
1148
  };
1145
1149
  var CAPABILITY = {
@@ -1238,7 +1242,7 @@ __name(getLimitsFromPlan, "getLimitsFromPlan");
1238
1242
  __name2(getLimitsFromPlan, "getLimitsFromPlan");
1239
1243
  var PLAN_PRESET_ENTITLEMENTS = {
1240
1244
  free_v1: {
1241
- products: [PRODUCT.AUTOMATION],
1245
+ products: [PRODUCT.AUTOMATION, PRODUCT.PULSE],
1242
1246
  capabilities: [
1243
1247
  CAPABILITY.BROWSER_AUTOMATION,
1244
1248
  CAPABILITY.CUSTOM_MCP_SERVERS,
@@ -1248,7 +1252,7 @@ var PLAN_PRESET_ENTITLEMENTS = {
1248
1252
  limits: getLimitsFromPlan(PLAN_VERSIONS.free_v1)
1249
1253
  },
1250
1254
  pro_v1: {
1251
- products: [PRODUCT.AUTOMATION, PRODUCT.CLARITY],
1255
+ products: [PRODUCT.AUTOMATION, PRODUCT.CLARITY, PRODUCT.PULSE],
1252
1256
  capabilities: [
1253
1257
  CAPABILITY.BROWSER_AUTOMATION,
1254
1258
  CAPABILITY.ADVANCED_INTEGRATIONS,
@@ -1264,7 +1268,12 @@ var PLAN_PRESET_ENTITLEMENTS = {
1264
1268
  limits: getLimitsFromPlan(PLAN_VERSIONS.pro_v1)
1265
1269
  },
1266
1270
  enterprise_v1: {
1267
- products: [PRODUCT.AUTOMATION, PRODUCT.CLARITY, PRODUCT.PLATFORM],
1271
+ products: [
1272
+ PRODUCT.AUTOMATION,
1273
+ PRODUCT.CLARITY,
1274
+ PRODUCT.PULSE,
1275
+ PRODUCT.PLATFORM
1276
+ ],
1268
1277
  capabilities: [
1269
1278
  CAPABILITY.BROWSER_AUTOMATION,
1270
1279
  CAPABILITY.ADVANCED_INTEGRATIONS,
@@ -1629,7 +1638,8 @@ var duvoLifecycleMessageTypeSchema = z10.union([
1629
1638
  ]);
1630
1639
  var duvoMessageTypeSchema = z10.union([
1631
1640
  duvoLifecycleMessageTypeSchema,
1632
- z10.literal("artifact_applied")
1641
+ z10.literal("artifact_applied"),
1642
+ z10.literal("classifier_decision")
1633
1643
  ]);
1634
1644
  var duvoBaseSystemMessageSchema = z10.object({
1635
1645
  id: z10.string(),
@@ -1724,6 +1734,28 @@ var duvoSystemArtifactAppliedMessageSchema = duvoArtifactAppliedBaseSystemMessag
1724
1734
  artifact: agentChatArtifactAppliedSchema
1725
1735
  })
1726
1736
  );
1737
+ var classifierDecisionSchema = z10.union([
1738
+ z10.literal("allowed"),
1739
+ z10.literal("denied"),
1740
+ z10.literal("ask")
1741
+ ]);
1742
+ var classifierDecidedBySchema = z10.union([
1743
+ z10.literal("classifier"),
1744
+ z10.literal("user")
1745
+ ]);
1746
+ var duvoClassifierDecisionMessageSchema = z10.object({
1747
+ id: z10.string(),
1748
+ runtime: agentRuntimeSchema,
1749
+ timestamp: z10.string(),
1750
+ role: z10.literal("duvo"),
1751
+ type: z10.literal("classifier_decision"),
1752
+ tool_call_id: z10.string(),
1753
+ tool_name: z10.string(),
1754
+ decision: classifierDecisionSchema,
1755
+ decided_by: classifierDecidedBySchema,
1756
+ reason: z10.string().optional(),
1757
+ human_request_id: z10.string().optional()
1758
+ });
1727
1759
  var agentRuntimeMessageTypeSchema = z10.union([
1728
1760
  agentMessageTypeSchema,
1729
1761
  duvoMessageTypeSchema
@@ -1735,7 +1767,8 @@ var duvoSystemMessageSchema = z10.union([
1735
1767
  duvoSystemAgentRunCreatedMessageSchema,
1736
1768
  duvoSystemBrowserSessionCreatedMessageSchema,
1737
1769
  duvoSystemSessionErrorMessageSchema,
1738
- duvoSystemArtifactAppliedMessageSchema
1770
+ duvoSystemArtifactAppliedMessageSchema,
1771
+ duvoClassifierDecisionMessageSchema
1739
1772
  ]);
1740
1773
  var sdkMessageSchema = z10.looseObject({
1741
1774
  session_id: z10.string(),
@@ -1756,7 +1789,15 @@ var toolPausedEventSchema = z10.object({
1756
1789
  toolInput: z10.record(z10.string(), z10.unknown()),
1757
1790
  category: pausableToolCategorySchema,
1758
1791
  behavior: z10.union([z10.literal("canUseTool"), z10.literal("interrupt")]),
1759
- timestamp: z10.string().optional()
1792
+ timestamp: z10.string().optional(),
1793
+ // Set when the pause came from the supervised-mode auto-mode classifier
1794
+ // escalating an arbitrary tool call, rather than a registered HITL tool.
1795
+ source: z10.literal("classifier").optional(),
1796
+ // SDK tool_use id of the intercepted call, so the created human_request can
1797
+ // be linked back to the tool-call card in the run UI.
1798
+ toolCallId: z10.string().optional(),
1799
+ // Classifier's human-readable explanation of why it escalated.
1800
+ decisionReason: z10.string().optional()
1760
1801
  });
1761
1802
  var thinkingConfigSchema = z10.union([
1762
1803
  z10.object({ type: z10.literal("disabled") }),
@@ -3251,6 +3292,138 @@ Quoted guidance: ${JSON.stringify(formatted)}`;
3251
3292
  }
3252
3293
  __name(buildProcessGuidanceBlock, "buildProcessGuidanceBlock");
3253
3294
  __name2(buildProcessGuidanceBlock, "buildProcessGuidanceBlock");
3295
+ var TEAM_ROLE = {
3296
+ OWNER: "team:owner",
3297
+ SUPERADMIN: "team:superadmin",
3298
+ ADMIN: "team:admin",
3299
+ MANAGER: "team:manager",
3300
+ BUILDER: "team:builder",
3301
+ MEMBER: "team:member",
3302
+ CLARITY_MEMBER: "team:clarity-member"
3303
+ };
3304
+ var TEAM_ROLE_CONFIG = {
3305
+ [TEAM_ROLE.OWNER]: {
3306
+ displayName: "Owner",
3307
+ parentRole: null
3308
+ },
3309
+ [TEAM_ROLE.SUPERADMIN]: {
3310
+ displayName: "Administrator",
3311
+ parentRole: TEAM_ROLE.OWNER
3312
+ },
3313
+ [TEAM_ROLE.ADMIN]: {
3314
+ displayName: "Manager",
3315
+ parentRole: TEAM_ROLE.SUPERADMIN
3316
+ },
3317
+ [TEAM_ROLE.MANAGER]: {
3318
+ displayName: "Manager",
3319
+ parentRole: TEAM_ROLE.ADMIN
3320
+ },
3321
+ [TEAM_ROLE.BUILDER]: {
3322
+ displayName: "Builder",
3323
+ parentRole: TEAM_ROLE.MANAGER
3324
+ },
3325
+ [TEAM_ROLE.MEMBER]: {
3326
+ displayName: "Member",
3327
+ parentRole: TEAM_ROLE.BUILDER
3328
+ },
3329
+ [TEAM_ROLE.CLARITY_MEMBER]: {
3330
+ displayName: "Clarity Member",
3331
+ parentRole: TEAM_ROLE.MEMBER
3332
+ }
3333
+ };
3334
+ var TEAM_ROLES = {
3335
+ OWNER_ONLY: [TEAM_ROLE.OWNER],
3336
+ SUPERADMIN_AND_ABOVE: [TEAM_ROLE.OWNER, TEAM_ROLE.SUPERADMIN],
3337
+ ADMIN_AND_ABOVE: [
3338
+ TEAM_ROLE.OWNER,
3339
+ TEAM_ROLE.SUPERADMIN,
3340
+ TEAM_ROLE.ADMIN
3341
+ ],
3342
+ MANAGER_AND_ABOVE: [
3343
+ TEAM_ROLE.OWNER,
3344
+ TEAM_ROLE.SUPERADMIN,
3345
+ TEAM_ROLE.ADMIN,
3346
+ TEAM_ROLE.MANAGER
3347
+ ],
3348
+ BUILDER_AND_ABOVE: [
3349
+ TEAM_ROLE.OWNER,
3350
+ TEAM_ROLE.SUPERADMIN,
3351
+ TEAM_ROLE.ADMIN,
3352
+ TEAM_ROLE.MANAGER,
3353
+ TEAM_ROLE.BUILDER
3354
+ ],
3355
+ MEMBER_AND_ABOVE: [
3356
+ TEAM_ROLE.OWNER,
3357
+ TEAM_ROLE.SUPERADMIN,
3358
+ TEAM_ROLE.ADMIN,
3359
+ TEAM_ROLE.MANAGER,
3360
+ TEAM_ROLE.BUILDER,
3361
+ TEAM_ROLE.MEMBER
3362
+ ],
3363
+ ALL: [
3364
+ TEAM_ROLE.OWNER,
3365
+ TEAM_ROLE.SUPERADMIN,
3366
+ TEAM_ROLE.ADMIN,
3367
+ TEAM_ROLE.MANAGER,
3368
+ TEAM_ROLE.BUILDER,
3369
+ TEAM_ROLE.MEMBER,
3370
+ TEAM_ROLE.CLARITY_MEMBER
3371
+ ],
3372
+ /**
3373
+ * Team roles an SSO role mapping — or a connection's default team role — may
3374
+ * newly grant. Excludes `team:admin`: it is deprecated and shares the display
3375
+ * name "Manager" with `team:manager`, so offering both leaves an
3376
+ * administrator picking between two indistinguishable options.
3377
+ *
3378
+ * This governs what is *newly assignable*, not what is accepted: rows already
3379
+ * holding `team:admin` stay valid and the write schema still takes `ALL`.
3380
+ */
3381
+ SSO_ASSIGNABLE: [
3382
+ TEAM_ROLE.OWNER,
3383
+ TEAM_ROLE.SUPERADMIN,
3384
+ TEAM_ROLE.MANAGER,
3385
+ TEAM_ROLE.BUILDER,
3386
+ TEAM_ROLE.MEMBER,
3387
+ TEAM_ROLE.CLARITY_MEMBER
3388
+ ]
3389
+ };
3390
+ function hasMinimumRole(userRole, minimumRole) {
3391
+ if (!isValidTeamRole(userRole)) {
3392
+ return false;
3393
+ }
3394
+ let current = minimumRole;
3395
+ while (current) {
3396
+ if (current === userRole) {
3397
+ return true;
3398
+ }
3399
+ current = TEAM_ROLE_CONFIG[current].parentRole;
3400
+ }
3401
+ return false;
3402
+ }
3403
+ __name(hasMinimumRole, "hasMinimumRole");
3404
+ __name2(hasMinimumRole, "hasMinimumRole");
3405
+ function isValidTeamRole(role) {
3406
+ return Object.values(TEAM_ROLE).includes(role);
3407
+ }
3408
+ __name(isValidTeamRole, "isValidTeamRole");
3409
+ __name2(isValidTeamRole, "isValidTeamRole");
3410
+ function getTeamRoleLabel(role) {
3411
+ if (!isValidTeamRole(role)) {
3412
+ return role;
3413
+ }
3414
+ if (role === TEAM_ROLE.ADMIN) {
3415
+ return `${TEAM_ROLE_CONFIG[role].displayName} (dep. admin)`;
3416
+ }
3417
+ return TEAM_ROLE_CONFIG[role].displayName;
3418
+ }
3419
+ __name(getTeamRoleLabel, "getTeamRoleLabel");
3420
+ __name2(getTeamRoleLabel, "getTeamRoleLabel");
3421
+ var SSO_ASSIGNABLE_TEAM_ROLES = TEAM_ROLES.SSO_ASSIGNABLE;
3422
+ function getSsoAssignableTeamRoleOptions(current) {
3423
+ return isValidTeamRole(current) && !SSO_ASSIGNABLE_TEAM_ROLES.includes(current) ? [...TEAM_ROLES.SSO_ASSIGNABLE, current] : TEAM_ROLES.SSO_ASSIGNABLE;
3424
+ }
3425
+ __name(getSsoAssignableTeamRoleOptions, "getSsoAssignableTeamRoleOptions");
3426
+ __name2(getSsoAssignableTeamRoleOptions, "getSsoAssignableTeamRoleOptions");
3254
3427
  var DEFAULT_CLARITY_PROCESS_LABEL_COLOR_HUE = 215;
3255
3428
  var clarityProcessLabelColorHueSchema = z17.int().min(0).max(360);
3256
3429
  var clarityProcessLabelInputSchema = z17.object({
@@ -4069,6 +4242,9 @@ var clarityProcessLandscapeResponseSchema = z18.object({
4069
4242
  links: z18.array(clarityProcessLandscapeLinkSchema),
4070
4243
  unlinkedProcesses: z18.array(clarityProcessLandscapeUnlinkedProcessSchema),
4071
4244
  stats: clarityProcessLandscapeStatsSchema,
4245
+ generationStatus: clarityProcessLandscapeGenerationStatusSchema.default("idle").describe(
4246
+ "Latest organization-wide generation status. Available to every authorized organization viewer so terminal failures can be communicated without exposing generation input counts."
4247
+ ),
4072
4248
  generation: clarityProcessLandscapeGenerationSchema.nullable().describe(
4073
4249
  "Organization-wide generation status and eligible input counts. Null unless the caller has an Owner or Executive organization role."
4074
4250
  ),
@@ -4120,6 +4296,131 @@ var clarityProcessPersonSchema = z18.object({
4120
4296
  var clarityProcessPeopleResponseSchema = z18.object({
4121
4297
  people: z18.array(clarityProcessPersonSchema)
4122
4298
  });
4299
+ var CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_NODE_COUNT = 20;
4300
+ var CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PEOPLE_COUNT = 20;
4301
+ var CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PAIR_COUNT = 100;
4302
+ function normalizeClarityHierarchyBatchText(value) {
4303
+ const trimmed = value?.trim();
4304
+ return trimmed ? trimmed : null;
4305
+ }
4306
+ __name(normalizeClarityHierarchyBatchText, "normalizeClarityHierarchyBatchText");
4307
+ __name2(normalizeClarityHierarchyBatchText, "normalizeClarityHierarchyBatchText");
4308
+ var clarityHierarchyPeopleBatchPersonSchema = z18.object({
4309
+ name: z18.string().max(200).nullable().transform(normalizeClarityHierarchyBatchText),
4310
+ /** Null adds a name-only placeholder person; no invitation is sent. */
4311
+ email: z18.string().transform((email) => email.trim().toLowerCase()).pipe(z18.email()).nullable(),
4312
+ processRole: z18.string().max(200).nullable().transform(normalizeClarityHierarchyBatchText),
4313
+ teamRole: z18.enum(TEAM_ROLES.ALL)
4314
+ }).strict().refine((person) => person.email !== null || person.name !== null, {
4315
+ message: "Name or email is required"
4316
+ });
4317
+ var clarityHierarchyPeopleBatchRequestSchema = z18.object({
4318
+ nodeIds: z18.array(z18.guid().transform((nodeId) => nodeId.toLowerCase())).min(1).max(CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_NODE_COUNT).refine((nodeIds) => new Set(nodeIds).size === nodeIds.length, {
4319
+ message: "Process node IDs must be unique"
4320
+ }),
4321
+ people: z18.array(clarityHierarchyPeopleBatchPersonSchema).min(1).max(CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PEOPLE_COUNT).refine(
4322
+ (people) => new Set(people.map((person) => person.email ?? `name:${person.name}`)).size === people.length,
4323
+ { message: "People must be unique" }
4324
+ )
4325
+ }).strict().refine(
4326
+ ({ nodeIds, people }) => nodeIds.length * people.length <= CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PAIR_COUNT,
4327
+ {
4328
+ message: `Batch cannot exceed ${CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PAIR_COUNT} node/person assignments`
4329
+ }
4330
+ );
4331
+ var CLARITY_HIERARCHY_PEOPLE_BATCH_ERROR_CODES = [
4332
+ "NODE_NOT_FOUND",
4333
+ "PROCESS_NOT_FOUND",
4334
+ "CONCURRENT_CONFLICT",
4335
+ "ASSIGNMENT_FAILED"
4336
+ ];
4337
+ var clarityHierarchyPeopleBatchInvitationDeliveryStatusSchema = z18.enum(
4338
+ ["sent", "not_needed", "failed"]
4339
+ );
4340
+ var clarityHierarchyPeopleBatchOutcomeKeySchema = z18.object({
4341
+ nodeId: z18.guid(),
4342
+ email: z18.email().nullable(),
4343
+ name: z18.string().nullable()
4344
+ });
4345
+ var clarityHierarchyPeopleBatchAssignedOutcomeSchema = clarityHierarchyPeopleBatchOutcomeKeySchema.extend({
4346
+ outcome: z18.literal("assigned"),
4347
+ processPerson: clarityProcessPersonSchema.strict(),
4348
+ invitationDeliveryStatus: clarityHierarchyPeopleBatchInvitationDeliveryStatusSchema
4349
+ }).strict();
4350
+ var clarityHierarchyPeopleBatchAlreadyPresentOutcomeSchema = clarityHierarchyPeopleBatchOutcomeKeySchema.extend({
4351
+ outcome: z18.literal("already_present"),
4352
+ processPerson: clarityProcessPersonSchema.strict().nullable(),
4353
+ invitationDeliveryStatus: z18.literal("not_needed")
4354
+ }).strict();
4355
+ var clarityHierarchyPeopleBatchFailedOutcomeSchema = clarityHierarchyPeopleBatchOutcomeKeySchema.extend({
4356
+ outcome: z18.literal("failed"),
4357
+ processPerson: clarityProcessPersonSchema.strict().nullable(),
4358
+ invitationDeliveryStatus: z18.literal("not_needed"),
4359
+ error: z18.object({
4360
+ code: z18.enum(CLARITY_HIERARCHY_PEOPLE_BATCH_ERROR_CODES),
4361
+ message: z18.string().min(1),
4362
+ retryable: z18.boolean()
4363
+ }).strict()
4364
+ }).strict();
4365
+ var clarityHierarchyPeopleBatchOutcomeSchema = z18.discriminatedUnion(
4366
+ "outcome",
4367
+ [
4368
+ clarityHierarchyPeopleBatchAssignedOutcomeSchema,
4369
+ clarityHierarchyPeopleBatchAlreadyPresentOutcomeSchema,
4370
+ clarityHierarchyPeopleBatchFailedOutcomeSchema
4371
+ ]
4372
+ );
4373
+ var clarityHierarchyPeopleBatchCountSchema = z18.number().int().nonnegative().max(CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PAIR_COUNT);
4374
+ var clarityHierarchyPeopleBatchResponseSchema = z18.object({
4375
+ outcomes: z18.array(clarityHierarchyPeopleBatchOutcomeSchema).min(1).max(CLARITY_HIERARCHY_PEOPLE_BATCH_MAX_PAIR_COUNT),
4376
+ counts: z18.object({
4377
+ requested: clarityHierarchyPeopleBatchCountSchema.min(1),
4378
+ assigned: clarityHierarchyPeopleBatchCountSchema,
4379
+ alreadyPresent: clarityHierarchyPeopleBatchCountSchema,
4380
+ failed: clarityHierarchyPeopleBatchCountSchema,
4381
+ invitationsSent: clarityHierarchyPeopleBatchCountSchema,
4382
+ invitationFailures: clarityHierarchyPeopleBatchCountSchema
4383
+ }).strict()
4384
+ }).strict().superRefine(({ outcomes, counts }, ctx) => {
4385
+ const assigned = outcomes.filter(
4386
+ (item) => item.outcome === "assigned"
4387
+ ).length;
4388
+ const alreadyPresent = outcomes.filter(
4389
+ (item) => item.outcome === "already_present"
4390
+ ).length;
4391
+ const failed = outcomes.filter((item) => item.outcome === "failed").length;
4392
+ const invitationsSent = outcomes.filter(
4393
+ (item) => item.outcome === "assigned" && item.invitationDeliveryStatus === "sent"
4394
+ ).length;
4395
+ const invitationFailures = outcomes.filter(
4396
+ (item) => item.outcome === "assigned" && item.invitationDeliveryStatus === "failed"
4397
+ ).length;
4398
+ const expectedCounts = {
4399
+ requested: outcomes.length,
4400
+ assigned,
4401
+ alreadyPresent,
4402
+ failed,
4403
+ invitationsSent,
4404
+ invitationFailures
4405
+ };
4406
+ for (const field of [
4407
+ "requested",
4408
+ "assigned",
4409
+ "alreadyPresent",
4410
+ "failed",
4411
+ "invitationsSent",
4412
+ "invitationFailures"
4413
+ ]) {
4414
+ if (counts[field] === expectedCounts[field]) {
4415
+ continue;
4416
+ }
4417
+ ctx.addIssue({
4418
+ code: "custom",
4419
+ path: ["counts", field],
4420
+ message: `${field} must equal ${expectedCounts[field]}`
4421
+ });
4422
+ }
4423
+ });
4123
4424
  var clarityHierarchyPersonSchema = clarityProcessPersonSchema.extend({
4124
4425
  nodeId: z18.guid(),
4125
4426
  processId: z18.guid()
@@ -4139,7 +4440,12 @@ var clarityLandscapePeopleResponseSchema = clarityHierarchyPeopleResponseSchema.
4139
4440
  var createClarityProcessPersonRequestSchema = z18.object({
4140
4441
  name: z18.string().max(200).nullable().optional(),
4141
4442
  email: z18.email().nullable().optional(),
4142
- role: z18.string().max(200).nullable().optional()
4443
+ role: z18.string().max(200).nullable().optional(),
4444
+ /**
4445
+ * Team role granted when the email needs a new team invitation. Ignored
4446
+ * for existing team members. Defaults to Clarity Member when absent.
4447
+ */
4448
+ teamRole: z18.enum(TEAM_ROLES.ALL).nullable().optional()
4143
4449
  }).refine(
4144
4450
  (body) => Boolean(body.name?.trim()) || Boolean(body.email?.trim()),
4145
4451
  "Name or email is required"
@@ -6113,6 +6419,12 @@ var clarityV2ProcessReadModelSchema = z25.object({
6113
6419
  generation_progress: generationProgressSchema.nullable().describe(
6114
6420
  "Live progress checklist while a generation is in flight; null otherwise. Field names inside the payload are camelCase, matching the legacy v1 generation-progress shape."
6115
6421
  ),
6422
+ generation_started_at: z25.iso.datetime().nullable().default(null).describe(
6423
+ "ISO 8601 timestamp for the most recent generation kickoff; useful for generation-duration reporting"
6424
+ ),
6425
+ generation_last_activity_at: z25.iso.datetime().nullable().default(null).describe(
6426
+ "ISO 8601 timestamp of the latest process or message activity while generation is in flight; use it for stale-generation detection"
6427
+ ),
6116
6428
  custom_prompt: z25.string().nullable().describe("User-supplied custom prompt that steers generation"),
6117
6429
  created_at: z25.string().describe("ISO 8601 creation timestamp"),
6118
6430
  updated_at: z25.string().describe("ISO 8601 last-update timestamp")
@@ -7236,6 +7548,12 @@ var NOTIFICATION_SEVERITIES = [
7236
7548
  "success"
7237
7549
  ];
7238
7550
  var notificationSeveritySchema = z31.enum(NOTIFICATION_SEVERITIES);
7551
+ var NOTIFICATION_SEVERITY_URGENCY_ORDER = [
7552
+ "success",
7553
+ "info",
7554
+ "warning",
7555
+ "critical"
7556
+ ];
7239
7557
  var NOTIFICATION_TYPE_META = {
7240
7558
  connection_broken: {
7241
7559
  label: "Reconnect",
@@ -7342,7 +7660,25 @@ var notificationBaseShape = {
7342
7660
  seenAt: z31.string().nullable(),
7343
7661
  readAt: z31.string().nullable(),
7344
7662
  resolvedAt: z31.string().nullable(),
7345
- dismissedAt: z31.string().nullable().default(null)
7663
+ dismissedAt: z31.string().nullable().default(null),
7664
+ /**
7665
+ * How many occurrences this row stands for. 1 for an ordinary notification;
7666
+ * higher on a collapsed row (a repeated eval flag, a flapping connection).
7667
+ *
7668
+ * On the wire because a collapsed row that renders as "1" is worse than no
7669
+ * collapsing at all — the reader sees one card and has no way to know the
7670
+ * other N happened. Defaulted so older stored rows and clients that never
7671
+ * sent it read as a single occurrence.
7672
+ *
7673
+ * `.min(1)` rather than `.positive()`: on an integer the two are the same
7674
+ * constraint, but `.positive()` lowers to a *numeric* `exclusiveMinimum`,
7675
+ * which is JSON Schema 2020-12. The published spec is OpenAPI 3.0.3, where
7676
+ * `exclusiveMinimum` is a boolean modifier on `minimum`, so the numeric form
7677
+ * is invalid there.
7678
+ */
7679
+ occurrenceCount: z31.number().int().min(1).default(1),
7680
+ /** When the most recent occurrence arrived; null when never collapsed. */
7681
+ lastSeenAt: z31.string().nullable().default(null)
7346
7682
  };
7347
7683
  var JOB_ISSUE_SOURCES = ["run_failed", "run_stuck"];
7348
7684
  var LEGACY_JOB_ISSUE_SOURCES = [
@@ -7466,6 +7802,9 @@ var notificationListQuerySchema = z31.object({
7466
7802
  severity: notificationSeveritySchema.optional().describe(
7467
7803
  `Only return notifications with this severity. One of: ${NOTIFICATION_SEVERITIES.join(", ")}.`
7468
7804
  ),
7805
+ minSeverity: notificationSeveritySchema.optional().describe(
7806
+ `Only return notifications at or above this urgency. Least to most urgent: ${NOTIFICATION_SEVERITY_URGENCY_ORDER.join(" < ")}. Mutually exclusive with severity.`
7807
+ ),
7469
7808
  important: z31.enum(["true", "false"]).optional().transform((v) => v === "true").describe(
7470
7809
  "If true, only return important notifications: unresolved connection_broken rows pinned until reconnected, removed, or dismissed."
7471
7810
  ),
@@ -7484,6 +7823,9 @@ var notificationListQuerySchema = z31.object({
7484
7823
  }).refine((data) => data.sort !== "importance" || Boolean(data.batchId), {
7485
7824
  message: "sort=importance is only valid together with batchId",
7486
7825
  path: ["sort"]
7826
+ }).refine((data) => !(data.severity && data.minSeverity), {
7827
+ message: "severity and minSeverity are mutually exclusive; use severity for an exact match or minSeverity for a threshold",
7828
+ path: ["minSeverity"]
7487
7829
  });
7488
7830
  var notificationListResponseSchema = z31.object({
7489
7831
  notifications: z31.array(notificationWireSchema),
@@ -7518,7 +7860,13 @@ var typePreferenceListResponseSchema = z31.array(typePreferenceSchema);
7518
7860
  var EVAL_ISSUE_SCOPE_STATUSES = ["custom"];
7519
7861
  var evalIssueScopeSchema = z31.object({
7520
7862
  status: z31.enum(EVAL_ISSUE_SCOPE_STATUSES).nullable(),
7521
- customSet: z31.array(z31.string()).nullable()
7863
+ customSet: z31.array(z31.string()).nullable(),
7864
+ /**
7865
+ * Minimum urgency an eval_issue must reach for this subscription to receive
7866
+ * it. Optional rather than required so adding it does not break a client
7867
+ * built against the previous shape; the backend always sends it.
7868
+ */
7869
+ minSeverity: notificationSeveritySchema.nullable().optional()
7522
7870
  });
7523
7871
  var agentNotificationSettingsResponseSchema = z31.object({
7524
7872
  muted: z31.boolean(),
@@ -7533,6 +7881,11 @@ var notificationBatchTypeCountSchema = z32.object({
7533
7881
  total: z32.number().int().nonnegative(),
7534
7882
  unread: z32.number().int().nonnegative()
7535
7883
  });
7884
+ var notificationBatchSeverityCountSchema = z32.object({
7885
+ severity: notificationSeveritySchema,
7886
+ total: z32.number().int().nonnegative(),
7887
+ unread: z32.number().int().nonnegative()
7888
+ });
7536
7889
  var notificationBatchWireSchema = z32.object({
7537
7890
  id: z32.guid(),
7538
7891
  agentId: z32.guid().nullable(),
@@ -7543,6 +7896,20 @@ var notificationBatchWireSchema = z32.object({
7543
7896
  closedAt: z32.string().nullable(),
7544
7897
  /** Live-member counts, one entry per type with total > 0, ordered by type sortOrder. Narrowed to matching members under a type filter (Resolved #11/#17). */
7545
7898
  typeCounts: z32.array(notificationBatchTypeCountSchema),
7899
+ /**
7900
+ * Live-member counts broken down by severity, one entry per severity with
7901
+ * total > 0. Exists because `worstSeverity` cannot answer an *exact*
7902
+ * severity filter: a batch whose worst member is critical may still hold
7903
+ * warning members, so "does this batch contain severity X" needs the
7904
+ * breakdown. Narrowed alongside typeCounts under an active filter.
7905
+ *
7906
+ * Defaulted rather than required because this schema also parses *responses*
7907
+ * in duvo-cli, which ships to npm on its own cadence: a CLI carrying this
7908
+ * field against a backend that predates it would otherwise reject every feed
7909
+ * page containing a batch. Same reasoning as occurrenceCount/lastSeenAt on
7910
+ * the notification wire.
7911
+ */
7912
+ severityCounts: z32.array(notificationBatchSeverityCountSchema).default([]),
7546
7913
  /** Sum of typeCounts[].unread — the "N new" chip. */
7547
7914
  unreadCount: z32.number().int().nonnegative(),
7548
7915
  /** Worst severity among live members (severity accent, Resolved #15). */
@@ -7562,13 +7929,36 @@ var notificationFeedQuerySchema = z32.object({
7562
7929
  unread: z32.enum(["true", "false"]).optional().transform((v) => v === "true").describe(
7563
7930
  "If true, only return unread individual notifications and batches with at least one unread live member."
7564
7931
  ),
7932
+ severity: notificationSeveritySchema.optional().describe(
7933
+ `Only return individual notifications with exactly this severity, and batches with at least one live member of it. A batch's counts then describe only those members. Mutually exclusive with minSeverity. One of: ${NOTIFICATION_SEVERITIES.join(", ")}.`
7934
+ ),
7935
+ minSeverity: notificationSeveritySchema.optional().describe(
7936
+ `Only return individual notifications at or above this urgency, and batches with at least one live member at or above it. A batch's counts and worst severity then describe only its members at or above the threshold. Least to most urgent: ${NOTIFICATION_SEVERITY_URGENCY_ORDER.join(" < ")}. Mutually exclusive with severity.`
7937
+ ),
7565
7938
  limit: z32.coerce.number().int().min(1).max(NOTIFICATION_LIST_MAX_LIMIT).prefault(NOTIFICATION_LIST_DEFAULT_LIMIT),
7566
7939
  cursor: z32.string().optional()
7940
+ }).refine((data) => !(data.severity && data.minSeverity), {
7941
+ message: "severity and minSeverity are mutually exclusive; use severity for an exact match or minSeverity for a threshold",
7942
+ path: ["severity"]
7567
7943
  });
7568
7944
  var notificationFeedResponseSchema = z32.object({
7569
7945
  items: z32.array(notificationFeedItemSchema),
7570
7946
  nextCursor: z32.string().nullable()
7571
7947
  });
7948
+ var notificationBatchByIdQuerySchema = z32.object({
7949
+ type: notificationTypeSchema.optional().describe(
7950
+ "Count only live members of this type. Omit to count every live member."
7951
+ ),
7952
+ severity: notificationSeveritySchema.optional().describe(
7953
+ `Count only live members with exactly this severity. Mutually exclusive with minSeverity. One of: ${NOTIFICATION_SEVERITIES.join(", ")}.`
7954
+ ),
7955
+ minSeverity: notificationSeveritySchema.optional().describe(
7956
+ `Count only live members at or above this urgency. Least to most urgent: ${NOTIFICATION_SEVERITY_URGENCY_ORDER.join(" < ")}. Mutually exclusive with severity.`
7957
+ )
7958
+ }).refine((data) => !(data.severity && data.minSeverity), {
7959
+ message: "severity and minSeverity are mutually exclusive; use severity for an exact match or minSeverity for a threshold",
7960
+ path: ["severity"]
7961
+ });
7572
7962
  var markBatchReadBodySchema = z32.object({
7573
7963
  /**
7574
7964
  * Narrow the mark-read to these member types (the page's active type
@@ -7582,7 +7972,30 @@ var markBatchReadBodySchema = z32.object({
7582
7972
  */
7583
7973
  types: z32.array(notificationTypeSchema).nonempty().max(NOTIFICATION_TYPES.length).refine((types) => new Set(types).size === types.length, {
7584
7974
  message: "types must not contain duplicates"
7585
- }).optional()
7975
+ }).optional(),
7976
+ /**
7977
+ * Narrow the mark-read to members of exactly this severity (the page's active
7978
+ * `severity` chip). Omit to mark every live member. Same reason `types`
7979
+ * exists: a batch card surfaced under a severity filter counts only its
7980
+ * matching members, so marking the whole batch read would silently consume
7981
+ * members the reader never saw.
7982
+ *
7983
+ * Distinct from `minSeverity`, not a rename of it: the feed's chips are
7984
+ * exact matches, so a batch opened under "Warning" shows warning members
7985
+ * only and must consume only those. Marking it with a `minSeverity` of
7986
+ * warning would also swallow its critical members — the unread rows the
7987
+ * reader most needs.
7988
+ */
7989
+ severity: notificationSeveritySchema.optional(),
7990
+ /**
7991
+ * Narrow the mark-read to members at or above this urgency, for a caller
7992
+ * paging the feed with `minSeverity` rather than `severity`. Mutually
7993
+ * exclusive with `severity`.
7994
+ */
7995
+ minSeverity: notificationSeveritySchema.optional()
7996
+ }).refine((data) => !(data.severity && data.minSeverity), {
7997
+ message: "severity and minSeverity are mutually exclusive; use severity for an exact match or minSeverity for a threshold",
7998
+ path: ["severity"]
7586
7999
  });
7587
8000
  var markBatchReadResponseSchema = z32.object({
7588
8001
  count: z32.number().int().nonnegative()
@@ -8188,138 +8601,6 @@ function buildPulseThemeStyle() {
8188
8601
  }
8189
8602
  __name(buildPulseThemeStyle, "buildPulseThemeStyle");
8190
8603
  __name2(buildPulseThemeStyle, "buildPulseThemeStyle");
8191
- var TEAM_ROLE = {
8192
- OWNER: "team:owner",
8193
- SUPERADMIN: "team:superadmin",
8194
- ADMIN: "team:admin",
8195
- MANAGER: "team:manager",
8196
- BUILDER: "team:builder",
8197
- MEMBER: "team:member",
8198
- CLARITY_MEMBER: "team:clarity-member"
8199
- };
8200
- var TEAM_ROLE_CONFIG = {
8201
- [TEAM_ROLE.OWNER]: {
8202
- displayName: "Owner",
8203
- parentRole: null
8204
- },
8205
- [TEAM_ROLE.SUPERADMIN]: {
8206
- displayName: "Administrator",
8207
- parentRole: TEAM_ROLE.OWNER
8208
- },
8209
- [TEAM_ROLE.ADMIN]: {
8210
- displayName: "Manager",
8211
- parentRole: TEAM_ROLE.SUPERADMIN
8212
- },
8213
- [TEAM_ROLE.MANAGER]: {
8214
- displayName: "Manager",
8215
- parentRole: TEAM_ROLE.ADMIN
8216
- },
8217
- [TEAM_ROLE.BUILDER]: {
8218
- displayName: "Builder",
8219
- parentRole: TEAM_ROLE.MANAGER
8220
- },
8221
- [TEAM_ROLE.MEMBER]: {
8222
- displayName: "Member",
8223
- parentRole: TEAM_ROLE.BUILDER
8224
- },
8225
- [TEAM_ROLE.CLARITY_MEMBER]: {
8226
- displayName: "Clarity Member",
8227
- parentRole: TEAM_ROLE.MEMBER
8228
- }
8229
- };
8230
- var TEAM_ROLES = {
8231
- OWNER_ONLY: [TEAM_ROLE.OWNER],
8232
- SUPERADMIN_AND_ABOVE: [TEAM_ROLE.OWNER, TEAM_ROLE.SUPERADMIN],
8233
- ADMIN_AND_ABOVE: [
8234
- TEAM_ROLE.OWNER,
8235
- TEAM_ROLE.SUPERADMIN,
8236
- TEAM_ROLE.ADMIN
8237
- ],
8238
- MANAGER_AND_ABOVE: [
8239
- TEAM_ROLE.OWNER,
8240
- TEAM_ROLE.SUPERADMIN,
8241
- TEAM_ROLE.ADMIN,
8242
- TEAM_ROLE.MANAGER
8243
- ],
8244
- BUILDER_AND_ABOVE: [
8245
- TEAM_ROLE.OWNER,
8246
- TEAM_ROLE.SUPERADMIN,
8247
- TEAM_ROLE.ADMIN,
8248
- TEAM_ROLE.MANAGER,
8249
- TEAM_ROLE.BUILDER
8250
- ],
8251
- MEMBER_AND_ABOVE: [
8252
- TEAM_ROLE.OWNER,
8253
- TEAM_ROLE.SUPERADMIN,
8254
- TEAM_ROLE.ADMIN,
8255
- TEAM_ROLE.MANAGER,
8256
- TEAM_ROLE.BUILDER,
8257
- TEAM_ROLE.MEMBER
8258
- ],
8259
- ALL: [
8260
- TEAM_ROLE.OWNER,
8261
- TEAM_ROLE.SUPERADMIN,
8262
- TEAM_ROLE.ADMIN,
8263
- TEAM_ROLE.MANAGER,
8264
- TEAM_ROLE.BUILDER,
8265
- TEAM_ROLE.MEMBER,
8266
- TEAM_ROLE.CLARITY_MEMBER
8267
- ],
8268
- /**
8269
- * Team roles an SSO role mapping — or a connection's default team role — may
8270
- * newly grant. Excludes `team:admin`: it is deprecated and shares the display
8271
- * name "Manager" with `team:manager`, so offering both leaves an
8272
- * administrator picking between two indistinguishable options.
8273
- *
8274
- * This governs what is *newly assignable*, not what is accepted: rows already
8275
- * holding `team:admin` stay valid and the write schema still takes `ALL`.
8276
- */
8277
- SSO_ASSIGNABLE: [
8278
- TEAM_ROLE.OWNER,
8279
- TEAM_ROLE.SUPERADMIN,
8280
- TEAM_ROLE.MANAGER,
8281
- TEAM_ROLE.BUILDER,
8282
- TEAM_ROLE.MEMBER,
8283
- TEAM_ROLE.CLARITY_MEMBER
8284
- ]
8285
- };
8286
- function hasMinimumRole(userRole, minimumRole) {
8287
- if (!isValidTeamRole(userRole)) {
8288
- return false;
8289
- }
8290
- let current = minimumRole;
8291
- while (current) {
8292
- if (current === userRole) {
8293
- return true;
8294
- }
8295
- current = TEAM_ROLE_CONFIG[current].parentRole;
8296
- }
8297
- return false;
8298
- }
8299
- __name(hasMinimumRole, "hasMinimumRole");
8300
- __name2(hasMinimumRole, "hasMinimumRole");
8301
- function isValidTeamRole(role) {
8302
- return Object.values(TEAM_ROLE).includes(role);
8303
- }
8304
- __name(isValidTeamRole, "isValidTeamRole");
8305
- __name2(isValidTeamRole, "isValidTeamRole");
8306
- function getTeamRoleLabel(role) {
8307
- if (!isValidTeamRole(role)) {
8308
- return role;
8309
- }
8310
- if (role === TEAM_ROLE.ADMIN) {
8311
- return `${TEAM_ROLE_CONFIG[role].displayName} (dep. admin)`;
8312
- }
8313
- return TEAM_ROLE_CONFIG[role].displayName;
8314
- }
8315
- __name(getTeamRoleLabel, "getTeamRoleLabel");
8316
- __name2(getTeamRoleLabel, "getTeamRoleLabel");
8317
- var SSO_ASSIGNABLE_TEAM_ROLES = TEAM_ROLES.SSO_ASSIGNABLE;
8318
- function getSsoAssignableTeamRoleOptions(current) {
8319
- return isValidTeamRole(current) && !SSO_ASSIGNABLE_TEAM_ROLES.includes(current) ? [...TEAM_ROLES.SSO_ASSIGNABLE, current] : TEAM_ROLES.SSO_ASSIGNABLE;
8320
- }
8321
- __name(getSsoAssignableTeamRoleOptions, "getSsoAssignableTeamRoleOptions");
8322
- __name2(getSsoAssignableTeamRoleOptions, "getSsoAssignableTeamRoleOptions");
8323
8604
  var TransportTypeSchema = z36.enum(["stdio", "sse", "http"]);
8324
8605
  var INTEGRATION_SLUGS = [
8325
8606
  "googlecalendar",
@@ -8428,6 +8709,13 @@ function isIntegrationSlug(value) {
8428
8709
  }
8429
8710
  __name(isIntegrationSlug, "isIntegrationSlug");
8430
8711
  __name2(isIntegrationSlug, "isIntegrationSlug");
8712
+ var COMPUTER_USE_INTEGRATION_SLUGS = /* @__PURE__ */ new Set(["duvo-computer-use", "duvo-computer-use-rdp"]);
8713
+ var BROWSING_INTEGRATION_SLUGS = /* @__PURE__ */ new Set(["browser-agent", "browser-agent-devtools"]);
8714
+ function isSupervisedModeIncompatibleIntegration(slug) {
8715
+ return BROWSING_INTEGRATION_SLUGS.has(slug) || COMPUTER_USE_INTEGRATION_SLUGS.has(slug);
8716
+ }
8717
+ __name(isSupervisedModeIncompatibleIntegration, "isSupervisedModeIncompatibleIntegration");
8718
+ __name2(isSupervisedModeIncompatibleIntegration, "isSupervisedModeIncompatibleIntegration");
8431
8719
  var SERVER_RESOLVED_MCP_URL_SLUGS = /* @__PURE__ */ new Set([
8432
8720
  "sap-ecc",
8433
8721
  "tableau",
@@ -10022,7 +10310,12 @@ var inviteOrgMemberRequestSchema = z51.object({
10022
10310
  "organization:admin",
10023
10311
  "organization:member"
10024
10312
  ]),
10025
- frontendUrl: z51.url().optional(),
10313
+ frontendUrl: z51.url().optional().describe(
10314
+ "Deprecated. Use `sendEmail` instead. Kept because its presence is the legacy opt-in for sending the invitation email; the value never sets the link host, which is always the server's configured frontend URL."
10315
+ ),
10316
+ sendEmail: z51.boolean().optional().describe(
10317
+ "Email the invitation to the recipient. `false` always suppresses the email. When omitted, the legacy opt-in applies instead: the email is sent only if the deprecated `frontendUrl` is present. Omit both to create the invitation without notifying anyone."
10318
+ ),
10026
10319
  teamId: z51.guid().optional()
10027
10320
  });
10028
10321
  var inviteOrgMemberResponseSchema = z51.object({
@@ -10114,10 +10407,14 @@ var acceptOrgInvitationResponseSchema = z51.object({
10114
10407
  orgId: z51.guid()
10115
10408
  });
10116
10409
  var createOrganizationInviteLinkRequestSchema = z51.object({
10117
- frontendUrl: z51.url()
10410
+ frontendUrl: z51.url().optional().describe(
10411
+ "Deprecated and ignored. The link is built from the server's configured frontend URL so a caller can't choose the host in a Duvo-branded email."
10412
+ )
10118
10413
  });
10119
10414
  var getOrganizationInviteLinkQuerySchema = z51.object({
10120
- frontendUrl: z51.url()
10415
+ frontendUrl: z51.url().optional().describe(
10416
+ "Deprecated and ignored. The link is built from the server's configured frontend URL so a caller can't choose the host in a Duvo-branded email."
10417
+ )
10121
10418
  });
10122
10419
  var organizationInviteLinkCreatorSchema = z51.object({
10123
10420
  id: z51.guid(),
@@ -10282,7 +10579,9 @@ var adminOrgAddMemberResponseSchema = z52.object({
10282
10579
  var adminOrgInviteMemberRequestSchema = z52.object({
10283
10580
  email: z52.email(),
10284
10581
  role: z52.enum(ORG_ROLES.ALL),
10285
- frontendUrl: z52.url().optional()
10582
+ frontendUrl: z52.url().optional().describe(
10583
+ "Set any URL to opt into sending the invitation email; omit it to create the invitation silently. The value no longer sets the link host \u2014 that is always the server's configured frontend URL."
10584
+ )
10286
10585
  });
10287
10586
  var adminOrgInviteMemberResponseSchema = z52.object({
10288
10587
  success: z52.literal(true),
@@ -10591,7 +10890,10 @@ var RuntimeOptionsSchema = z56.looseObject({
10591
10890
  "Browser infrastructure provider"
10592
10891
  ),
10593
10892
  evaluationSchemaId: z56.string().optional().describe("ID of the evaluation schema to apply to runs of this agent"),
10594
- benchmarkExpectedOutcomes: z56.array(BenchmarkExpectedOutcomeSchema).optional().describe("Expected outcomes used when running benchmark scenarios")
10893
+ benchmarkExpectedOutcomes: z56.array(BenchmarkExpectedOutcomeSchema).optional().describe("Expected outcomes used when running benchmark scenarios"),
10894
+ supervisedMode: z56.boolean().optional().describe(
10895
+ "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections."
10896
+ )
10595
10897
  });
10596
10898
  var AgentConfigSchemaV2 = z56.object({
10597
10899
  models: z56.object({
@@ -11156,7 +11458,10 @@ var automationDetailResponseApiSchema = z64.object({
11156
11458
  automation: automationDetailApiSchema
11157
11459
  });
11158
11460
  var createAutomationResponseApiSchema = z64.object({
11159
- automation: automationSummaryApiSchema
11461
+ automation: automationSummaryApiSchema,
11462
+ draft_revision_id: z64.guid().describe(
11463
+ "The draft revision the new automation was created with. A manually created automation has no live revision until it is first activated, so this is where its first agent build belongs."
11464
+ )
11160
11465
  });
11161
11466
  var updateAutomationResponseApiSchema = z64.object({
11162
11467
  automation: automationSummaryApiSchema
@@ -12263,10 +12568,14 @@ var publicClarityProcessSchema = z78.object({
12263
12568
  createdAt: z78.coerce.date()
12264
12569
  });
12265
12570
  var createTeamInviteLinkRequestSchema = z79.object({
12266
- frontendUrl: z79.url()
12571
+ frontendUrl: z79.url().optional().describe(
12572
+ "Deprecated and ignored. The link is built from the server's configured frontend URL so a caller can't choose the host in a Duvo-branded email."
12573
+ )
12267
12574
  });
12268
12575
  var getTeamInviteLinkQuerySchema = z79.object({
12269
- frontendUrl: z79.url()
12576
+ frontendUrl: z79.url().optional().describe(
12577
+ "Deprecated and ignored. The link is built from the server's configured frontend URL so a caller can't choose the host in a Duvo-branded email."
12578
+ )
12270
12579
  });
12271
12580
  var teamInviteLinkCreatorSchema = z79.object({
12272
12581
  id: z79.guid(),
@@ -12294,7 +12603,9 @@ var acceptJoinLinkResponseSchema = z79.object({
12294
12603
  teamId: z79.guid()
12295
12604
  });
12296
12605
  var createClarityProcessInviteLinkRequestSchema = z80.object({
12297
- frontendUrl: z80.url()
12606
+ frontendUrl: z80.url().optional().describe(
12607
+ "Deprecated and ignored. The link is built from the server's configured frontend URL so a caller can't choose the host in a Duvo-branded email."
12608
+ )
12298
12609
  });
12299
12610
  var clarityProcessInviteLinkSchema = teamInviteLinkSchema;
12300
12611
  var getClarityProcessInviteLinkResponseSchema = z80.object({
@@ -12451,6 +12762,11 @@ var FEATURE_FLAG_CATALOGUE = {
12451
12762
  defaultValue: false,
12452
12763
  description: "Enables the L1-L4 Clarity process hierarchy surfaces, including the process landscape tree and related organize/auto-sort workflows."
12453
12764
  },
12765
+ UNIFIED_CLARITY: {
12766
+ key: "unified_clarity",
12767
+ defaultValue: false,
12768
+ description: "Enables the shared Clarity Tree and Map home, canonical navigation, compatibility redirects, and eligible team-only organization landscape reads. Off by default for internal and FDE prototype validation."
12769
+ },
12454
12770
  LANDSCAPE_ONBOARDING: {
12455
12771
  key: "landscape_onboarding",
12456
12772
  defaultValue: false,
@@ -12616,6 +12932,11 @@ var FEATURE_FLAG_CATALOGUE = {
12616
12932
  defaultValue: false,
12617
12933
  description: "Grants connection sharing to teams that are NOT part of an organization (org-less teams have no org-level `connections_sharing_enabled` kill-switch). Resolved with team > global precedence; a global override turns it on for every org-less team. Teams inside an organization are governed solely by their org's setting and are unaffected by this flag."
12618
12934
  },
12935
+ SUPERVISED_MODE: {
12936
+ key: "supervised_mode",
12937
+ defaultValue: false,
12938
+ description: "Per-team opt-in for Supervised mode \u2014 running an agent under a custom `PreToolUse` classifier hook that rules on every tool call before it executes (`permissionMode` stays `bypassPermissions`; the SDK's own auto mode is not used). When on, the builder shows the Supervised mode toggle and build configs may persist `options.supervisedMode: true` (classifier asks route to the Requests center; per-tool-call verdicts render on run tool-call cards). When off (default), the toggle is hidden and saving a config with supervisedMode enabled is rejected at the build-config routes. Execution honors the frozen RunConfig regardless, so flipping the flag off does not break in-flight runs."
12939
+ },
12619
12940
  SUPPORT_ESCALATION: {
12620
12941
  key: "support_escalation",
12621
12942
  defaultValue: false,
@@ -12753,6 +13074,9 @@ var jobListItemSchema = z84.object({
12753
13074
  agent_id: z84.guid(),
12754
13075
  agent_name: z84.string(),
12755
13076
  build_id: z84.guid(),
13077
+ // Automation info (null for runs whose agent doesn't belong to an automation)
13078
+ automation_id: z84.guid().nullable(),
13079
+ automation_name: z84.string().nullable(),
12756
13080
  // User info
12757
13081
  user_id: z84.guid().nullable(),
12758
13082
  // Case info
@@ -12790,7 +13114,8 @@ var jobFilterOptionsSchema = z84.object({
12790
13114
  email: z84.string()
12791
13115
  })
12792
13116
  ),
12793
- caseQueues: z84.array(z84.object({ id: z84.string(), name: z84.string() }))
13117
+ caseQueues: z84.array(z84.object({ id: z84.string(), name: z84.string() })),
13118
+ automations: z84.array(z84.object({ id: z84.string(), name: z84.string() }))
12794
13119
  });
12795
13120
  var stepModeSchema = z85.enum(["deterministic", "parameterized", "agent"]).describe("How replay executes this step");
12796
13121
  var workflowParameterSchema = z85.object({
@@ -13498,9 +13823,13 @@ var teamInvitationDetailApiSchema = z93.object({
13498
13823
  }).optional()
13499
13824
  });
13500
13825
  var createTeamInvitationRequestSchema = z93.object({
13501
- email: z93.email(),
13502
- role: z93.string(),
13503
- processId: z93.guid().optional()
13826
+ email: z93.email().describe("Email address of the person to invite."),
13827
+ role: z93.string().describe(
13828
+ "Team role to grant. One of: team:owner, team:superadmin, team:admin (deprecated), team:manager, team:builder, team:member, team:clarity-member. You cannot grant a role above your own. Process invitations must use team:clarity-member."
13829
+ ),
13830
+ processId: z93.guid().optional().describe(
13831
+ "Invite the person to this Clarity process rather than the whole team. Requires the team:clarity-member role."
13832
+ )
13504
13833
  });
13505
13834
  var acceptTeamInvitationRequestSchema = z93.object({
13506
13835
  name: z93.string().optional()
@@ -16838,7 +17167,10 @@ var readinessDropSchema = z104.object({
16838
17167
  credentials_dropped: z104.number(),
16839
17168
  event_triggers_dropped: z104.number(),
16840
17169
  schedules_dropped: z104.number(),
16841
- case_triggers_dropped: z104.number()
17170
+ case_triggers_dropped: z104.number(),
17171
+ runs_interrupted: z104.number(),
17172
+ blocks_approvals: z104.boolean(),
17173
+ runs_at_risk: z104.number()
16842
17174
  });
16843
17175
  var inFlightRunSchema = z104.object({
16844
17176
  agent_id: z104.string(),
@@ -16866,7 +17198,9 @@ var moveAgentResponseSchema = z104.object({
16866
17198
  readiness: z104.object({
16867
17199
  users_missing_on_target: z104.array(readinessDropSchema)
16868
17200
  }),
16869
- in_flight_runs: z104.array(inFlightRunSchema)
17201
+ in_flight_runs: z104.array(inFlightRunSchema),
17202
+ runs_pinned: z104.number(),
17203
+ runs_interrupted: z104.number()
16870
17204
  }),
16871
17205
  dropped_folders: z104.array(namedRefSchema),
16872
17206
  dropped_memory_count: z104.number(),
@@ -18014,14 +18348,39 @@ Files copied to target: ${paths}`);
18014
18348
  "\nOwners not on the target team \u2014 add them there first, or their connections, triggers, and schedules are dropped:"
18015
18349
  );
18016
18350
  for (const u of outcome.readiness.users_missing_on_target) {
18017
- console.log(` - ${u.user_name} (${u.user_id}) \u2014 role ${u.source_role}`);
18351
+ const consequences = [];
18352
+ if (u.runs_interrupted > 0) {
18353
+ consequences.push(`${u.runs_interrupted} run(s) will be stopped`);
18354
+ }
18355
+ if (u.blocks_approvals) {
18356
+ consequences.push("the AOP names them as an approver");
18357
+ }
18358
+ if (u.runs_at_risk > 0) {
18359
+ consequences.push(
18360
+ `${u.runs_at_risk} run(s) they own keep going, but nobody could answer their next question`
18361
+ );
18362
+ }
18363
+ const suffix = consequences.length > 0 ? ` \u2014 ${consequences.join("; ")}` : "";
18364
+ console.log(
18365
+ ` - ${u.user_name} (${u.user_id}) \u2014 role ${u.source_role}${suffix}`
18366
+ );
18018
18367
  }
18019
18368
  }
18020
18369
  if (outcome.in_flight_runs.length > 0) {
18021
- console.log("\nAgents with runs in progress (will continue on target):");
18370
+ console.log("\nAgents with runs in progress:");
18022
18371
  for (const r of outcome.in_flight_runs) {
18023
18372
  console.log(` - ${r.agent_name} \u2014 ${r.count} run(s)`);
18024
18373
  }
18374
+ if (outcome.runs_pinned > 0) {
18375
+ console.log(
18376
+ ` ${outcome.runs_pinned} run(s) keep the source team's connections until their next step, then switch to the target team.`
18377
+ );
18378
+ }
18379
+ if (outcome.runs_interrupted > 0) {
18380
+ console.log(
18381
+ ` ${outcome.runs_interrupted} run(s) will be stopped \u2014 nobody on the target team can answer them, or a connection they use isn't coming along. Pending requests stay open, so adding the missing user picks those runs back up; a dropped connection has to be reconnected on the target team first.`
18382
+ );
18383
+ }
18025
18384
  }
18026
18385
  const dropped = [];
18027
18386
  if (outcome.event_triggers_dropped > 0) {
@@ -21984,6 +22343,14 @@ function renderOverview(overview) {
21984
22343
  { label: "Name", value: process2.name },
21985
22344
  { label: "Version", value: String(process2.version) },
21986
22345
  { label: "Status", value: process2.status },
22346
+ {
22347
+ label: "Generation started",
22348
+ value: process2.generation_started_at ?? "none"
22349
+ },
22350
+ {
22351
+ label: "Generation activity",
22352
+ value: process2.generation_last_activity_at ?? "none"
22353
+ },
21987
22354
  { label: "Captures", value: String(overview.process.captures.length) },
21988
22355
  {
21989
22356
  label: "Current",
@@ -33286,7 +33653,7 @@ function registerRunsList(runs) {
33286
33653
  runs.command("list").description("List agent runs for your team").option("--limit <n>", `page size (${MIN_LIMIT16}-${MAX_LIMIT14})`).option("--offset <n>", "number of runs to skip").option("--sort-order <order>", `sort direction (${SORT_ORDERS2.join("|")})`).option(
33287
33654
  "--status <status>",
33288
33655
  "filter by status (e.g. running, completed, failed, waiting, interrupted, stopped, needs_attention)"
33289
- ).option("--agent <id>", "filter by agent ID").option("--user <id>", "filter by user ID").option("--case-queue <id>", "filter by queue ID").option("--source <source>", "filter by source").option("--search <query>", "free-text search across runs").option(
33656
+ ).option("--agent <id>", "filter by agent ID").option("--automation <id>", "filter by automation ID").option("--user <id>", "filter by user ID").option("--case-queue <id>", "filter by queue ID").option("--source <source>", "filter by source").option("--search <query>", "free-text search across runs").option(
33290
33657
  "--has-issues <true|false>",
33291
33658
  `show only runs with (or without) issues (${HAS_ISSUES_VALUES.join("|")})`
33292
33659
  ).option(
@@ -33333,6 +33700,9 @@ function registerRunsList(runs) {
33333
33700
  if (options.agent !== void 0) {
33334
33701
  searchParams.append("agent_id", options.agent);
33335
33702
  }
33703
+ if (options.automation !== void 0) {
33704
+ searchParams.append("automation_id", options.automation);
33705
+ }
33336
33706
  if (options.user !== void 0) {
33337
33707
  searchParams.append("user_id", options.user);
33338
33708
  }
@@ -36771,7 +37141,7 @@ __name(isStandaloneBinary, "isStandaloneBinary");
36771
37141
  import { createRequire } from "node:module";
36772
37142
  function getPackageMeta() {
36773
37143
  if (true) {
36774
- return { name: "@duvoai/cli", version: "1.45.2" };
37144
+ return { name: "@duvoai/cli", version: "1.45.3" };
36775
37145
  }
36776
37146
  const require2 = createRequire(import.meta.url);
36777
37147
  const raw = require2("../../package.json");