@duvoai/cli 1.45.2 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/duvo.js CHANGED
@@ -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",
@@ -9508,15 +9796,7 @@ var adminCaseQueueConsumerSchema = z49.object({
9508
9796
  agentName: z49.string(),
9509
9797
  caseTriggerEnabled: z49.boolean(),
9510
9798
  isHandoverTarget: z49.boolean(),
9511
- problems: z49.array(adminCaseQueueAgentProblemSchema),
9512
- /** Raw concurrency set on the trigger row, null if unset or no trigger exists. */
9513
- triggerConcurrency: z49.number().nullable(),
9514
- /**
9515
- * Effective concurrency for the consumer trigger:
9516
- * `min(triggerConcurrency ?? defaultConcurrency, maxConcurrency)`.
9517
- * Null when this consumer has no trigger.
9518
- */
9519
- effectiveConcurrency: z49.number().nullable()
9799
+ problems: z49.array(adminCaseQueueAgentProblemSchema)
9520
9800
  });
9521
9801
  var adminCaseQueueItemSummarySchema = z49.object({
9522
9802
  id: z49.string(),
@@ -9570,6 +9850,13 @@ var adminCaseQueueDetailResponseSchema = z49.object({
9570
9850
  name: z49.string(),
9571
9851
  description: z49.string().nullable(),
9572
9852
  folderId: z49.string().nullable(),
9853
+ /** The configured per-queue concurrency cap (case_queue.concurrency); null uses the default. */
9854
+ configuredConcurrency: z49.number().nullable(),
9855
+ /**
9856
+ * Effective per-queue concurrency after the default fallback and the
9857
+ * `MAX_CASE_TRIGGER_CONCURRENCY` ceiling. Always a number.
9858
+ */
9859
+ effectiveConcurrency: z49.number(),
9573
9860
  createdAt: z49.string(),
9574
9861
  updatedAt: z49.string()
9575
9862
  }),
@@ -9577,13 +9864,13 @@ var adminCaseQueueDetailResponseSchema = z49.object({
9577
9864
  consumers: z49.array(adminCaseQueueConsumerSchema),
9578
9865
  /**
9579
9866
  * `env.DEFAULT_CASE_TRIGGER_CONCURRENCY` — the per-queue concurrency applied
9580
- * to a trigger that has no concurrency set.
9867
+ * to a queue that has no explicit cap set.
9581
9868
  */
9582
9869
  defaultConcurrency: z49.number(),
9583
9870
  /**
9584
9871
  * `env.MAX_CASE_TRIGGER_CONCURRENCY` — the hard per-queue ceiling for
9585
- * effective trigger concurrency, clamping both a trigger's own concurrency
9586
- * and the fallback default when either exceeds this value.
9872
+ * effective concurrency, clamping both a queue's own cap and the fallback
9873
+ * default when either exceeds this value.
9587
9874
  */
9588
9875
  maxConcurrency: z49.number(),
9589
9876
  items: z49.object({
@@ -9594,20 +9881,19 @@ var adminCaseQueueDetailResponseSchema = z49.object({
9594
9881
  })
9595
9882
  })
9596
9883
  });
9597
- var adminUpdateCaseTriggerConcurrencyRequestSchema = z49.object({
9884
+ var adminUpdateQueueConcurrencyRequestSchema = z49.object({
9598
9885
  concurrency: z49.int().positive().nullable().describe(
9599
- "New per-trigger concurrency cap. A positive integer (up to the platform max) sets an explicit cap; null clears it so the trigger uses the platform default."
9886
+ "New per-queue concurrency cap. A positive integer (up to the platform max) sets an explicit cap; null clears it so the queue uses the platform default."
9600
9887
  )
9601
9888
  });
9602
- var adminUpdateCaseTriggerConcurrencyResponseSchema = z49.object({
9889
+ var adminUpdateQueueConcurrencyResponseSchema = z49.object({
9603
9890
  data: z49.object({
9604
- agentId: z49.string(),
9605
- /** Raw concurrency stored on the trigger row, null when using the default. */
9606
- triggerConcurrency: z49.number().nullable(),
9891
+ queueId: z49.string(),
9892
+ /** The configured concurrency stored on the queue row, null when using the default. */
9893
+ configuredConcurrency: z49.number().nullable(),
9607
9894
  /**
9608
9895
  * Effective concurrency after applying the default fallback and the
9609
- * `MAX_CASE_TRIGGER_CONCURRENCY` ceiling. Always a number because a trigger
9610
- * row exists.
9896
+ * `MAX_CASE_TRIGGER_CONCURRENCY` ceiling.
9611
9897
  */
9612
9898
  effectiveConcurrency: z49.number()
9613
9899
  })
@@ -10022,7 +10308,12 @@ var inviteOrgMemberRequestSchema = z51.object({
10022
10308
  "organization:admin",
10023
10309
  "organization:member"
10024
10310
  ]),
10025
- frontendUrl: z51.url().optional(),
10311
+ frontendUrl: z51.url().optional().describe(
10312
+ "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."
10313
+ ),
10314
+ sendEmail: z51.boolean().optional().describe(
10315
+ "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."
10316
+ ),
10026
10317
  teamId: z51.guid().optional()
10027
10318
  });
10028
10319
  var inviteOrgMemberResponseSchema = z51.object({
@@ -10114,10 +10405,14 @@ var acceptOrgInvitationResponseSchema = z51.object({
10114
10405
  orgId: z51.guid()
10115
10406
  });
10116
10407
  var createOrganizationInviteLinkRequestSchema = z51.object({
10117
- frontendUrl: z51.url()
10408
+ frontendUrl: z51.url().optional().describe(
10409
+ "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."
10410
+ )
10118
10411
  });
10119
10412
  var getOrganizationInviteLinkQuerySchema = z51.object({
10120
- frontendUrl: z51.url()
10413
+ frontendUrl: z51.url().optional().describe(
10414
+ "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."
10415
+ )
10121
10416
  });
10122
10417
  var organizationInviteLinkCreatorSchema = z51.object({
10123
10418
  id: z51.guid(),
@@ -10282,7 +10577,9 @@ var adminOrgAddMemberResponseSchema = z52.object({
10282
10577
  var adminOrgInviteMemberRequestSchema = z52.object({
10283
10578
  email: z52.email(),
10284
10579
  role: z52.enum(ORG_ROLES.ALL),
10285
- frontendUrl: z52.url().optional()
10580
+ frontendUrl: z52.url().optional().describe(
10581
+ "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."
10582
+ )
10286
10583
  });
10287
10584
  var adminOrgInviteMemberResponseSchema = z52.object({
10288
10585
  success: z52.literal(true),
@@ -10591,7 +10888,10 @@ var RuntimeOptionsSchema = z56.looseObject({
10591
10888
  "Browser infrastructure provider"
10592
10889
  ),
10593
10890
  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")
10891
+ benchmarkExpectedOutcomes: z56.array(BenchmarkExpectedOutcomeSchema).optional().describe("Expected outcomes used when running benchmark scenarios"),
10892
+ supervisedMode: z56.boolean().optional().describe(
10893
+ "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."
10894
+ )
10595
10895
  });
10596
10896
  var AgentConfigSchemaV2 = z56.object({
10597
10897
  models: z56.object({
@@ -11156,7 +11456,10 @@ var automationDetailResponseApiSchema = z64.object({
11156
11456
  automation: automationDetailApiSchema
11157
11457
  });
11158
11458
  var createAutomationResponseApiSchema = z64.object({
11159
- automation: automationSummaryApiSchema
11459
+ automation: automationSummaryApiSchema,
11460
+ draft_revision_id: z64.guid().describe(
11461
+ "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."
11462
+ )
11160
11463
  });
11161
11464
  var updateAutomationResponseApiSchema = z64.object({
11162
11465
  automation: automationSummaryApiSchema
@@ -11237,7 +11540,6 @@ var automationRevisionQueueBindingApiSchema = z64.object({
11237
11540
  "Agent the queue routes to in this revision (null when unrouted)"
11238
11541
  ),
11239
11542
  enabled: z64.boolean().describe("Whether the queue's routing is enabled"),
11240
- concurrency: z64.int().nullable().describe("Per-revision concurrency limit (null for the queue default)"),
11241
11543
  name: z64.string().nullable().describe(
11242
11544
  "Per-revision queue name override (null to keep the queue's own name)"
11243
11545
  ),
@@ -11281,6 +11583,111 @@ var automationRevisionScheduleBindingApiSchema = z64.object({
11281
11583
  day_of_month: z64.int().min(1).max(31).nullable().describe("Day of month for a monthly schedule"),
11282
11584
  task: z64.string().nullable().describe("Prompt passed as the run's initial user message")
11283
11585
  });
11586
+ var automationTriggerSubscriptionApiSchema = z64.object({
11587
+ id: z64.guid().describe("Subscription identifier"),
11588
+ automation_trigger_id: z64.guid().describe("Declaration this subscription fulfills"),
11589
+ user_id: z64.guid().nullable().describe(
11590
+ "Scope owner. Always populated today: a null-scope (team) subscription needs the shared-run runtime, so nothing creates one yet"
11591
+ ),
11592
+ created_by: z64.guid().nullable().describe("Who authored the subscription"),
11593
+ enabled: z64.boolean().describe("Whether this scope participates"),
11594
+ integration_instance_id: z64.guid().nullable().describe("The connection this subscription currently fires with"),
11595
+ pending_integration_instance_id: z64.guid().nullable().describe(
11596
+ "A connection change staged with a draft, applied atomically on that draft's promotion"
11597
+ ),
11598
+ pending_from_revision_id: z64.guid().nullable().describe("Draft revision the staged connection change belongs to")
11599
+ });
11600
+ var automationScheduleSubscriptionApiSchema = z64.object({
11601
+ id: z64.guid().describe("Subscription identifier"),
11602
+ automation_schedule_id: z64.guid().describe("Declaration this subscription fulfills"),
11603
+ user_id: z64.guid().nullable().describe(
11604
+ "Scope owner. Always populated today: a null-scope (team) subscription needs the shared-run runtime, so nothing creates one yet"
11605
+ ),
11606
+ created_by: z64.guid().nullable().describe("Who authored the subscription"),
11607
+ enabled: z64.boolean().describe("Whether this scope participates")
11608
+ });
11609
+ var automationRevisionTriggersResponseApiSchema = z64.object({
11610
+ revision_id: z64.guid().describe("Revision these declarations were read from"),
11611
+ revision_status: automationRevisionStatusApiSchema.describe(
11612
+ "`draft`, `live`, or `historic` \u2014 drives read-only presentation"
11613
+ ),
11614
+ revision_updated_at: z64.string().describe(
11615
+ "ISO 8601 change stamp, and the concurrency token for the paired PUT. Send it back as `If-Match` and a write from stale state is refused with 409. Without it there is no check, and because the PUT replaces the complete set, a stale client silently drops declarations another editor added"
11616
+ ),
11617
+ triggers: z64.array(automationRevisionTriggerBindingApiSchema).describe(
11618
+ "Credential-free trigger declarations and this revision's config"
11619
+ ),
11620
+ subscriptions: z64.array(automationTriggerSubscriptionApiSchema).describe(
11621
+ "How each declaration is fulfilled **right now** \u2014 every scope's, not just the caller's. Returned at any revision status, and always current state: this is not a record of what fulfilled the declaration while a historic revision was live (that is not stored). On a historic revision it answers what a rollback would resume \u2014 note that activation disables the subscriptions of a declaration a newer revision omits and never re-enables them, so a bound-but-disabled row means rolling back will not resume it until each member opts back in"
11622
+ )
11623
+ });
11624
+ var automationRevisionSchedulesResponseApiSchema = z64.object({
11625
+ revision_id: z64.guid().describe("Revision these declarations were read from"),
11626
+ revision_status: automationRevisionStatusApiSchema.describe(
11627
+ "`draft`, `live`, or `historic` \u2014 drives read-only presentation"
11628
+ ),
11629
+ revision_updated_at: z64.string().describe(
11630
+ "ISO 8601 change stamp, and the concurrency token for the paired PUT. Send it back as `If-Match` and a write from stale state is refused with 409. Without it there is no check, and because the PUT replaces the complete set, a stale client silently drops declarations another editor added"
11631
+ ),
11632
+ schedules: z64.array(automationRevisionScheduleBindingApiSchema).describe(
11633
+ "Credential-free schedule declarations and this revision's config"
11634
+ ),
11635
+ subscriptions: z64.array(automationScheduleSubscriptionApiSchema).describe(
11636
+ "Who the schedule runs as **right now** \u2014 every scope's, not just the caller's. Returned at any revision status, and always current state rather than a record of who it ran as while a historic revision was live. Unlike the trigger lane, activation never disables a schedule opt-in when a revision omits the declaration, so these survive a rollback intact"
11637
+ )
11638
+ });
11639
+ var setAutomationRevisionTriggerApiSchema = z64.object({
11640
+ automation_trigger_id: z64.guid().optional().describe("Existing declaration to update; omit to mint a new one"),
11641
+ agent_id: z64.guid().describe("Agent this trigger routes to"),
11642
+ integration_slug: z64.string().min(1).describe("Integration to watch"),
11643
+ trigger_type: z64.string().min(1).describe("Trigger type within the integration"),
11644
+ enabled: z64.boolean().default(true).describe("Whether the trigger is enabled in this revision"),
11645
+ filter_config: z64.record(z64.string(), z64.unknown()).default({}).describe("Per-revision filter configuration"),
11646
+ integration_instance_id: z64.guid().nullable().optional().describe(
11647
+ "Connection to fulfill this declaration with. Applied on promotion for an already-live declaration; set directly for one that is not live. Omit to leave it as it is; pass null to discard a choice staged against this draft"
11648
+ )
11649
+ });
11650
+ var setAutomationRevisionTriggersRequestApiSchema = z64.object({
11651
+ triggers: z64.array(setAutomationRevisionTriggerApiSchema).describe(
11652
+ "The draft's complete desired trigger set; declarations absent here are removed from the draft"
11653
+ )
11654
+ });
11655
+ var setAutomationRevisionScheduleApiSchema = z64.object({
11656
+ automation_schedule_id: z64.guid().optional().describe("Existing declaration to update; omit to mint a new one"),
11657
+ agent_id: z64.guid().describe("Agent this schedule fires"),
11658
+ enabled: z64.boolean().default(true).describe("Whether the schedule is enabled"),
11659
+ cron: z64.string().min(1).nullable().optional().describe("5-field cron expression; mutually exclusive with `frequency`"),
11660
+ frequency: z64.enum(AUTOMATION_SCHEDULE_FREQUENCIES).nullable().optional().describe("Frequency form; mutually exclusive with `cron`"),
11661
+ time: z64.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/).nullable().optional().describe("Local time of day as HH:MM"),
11662
+ timezone: z64.string().default("UTC").describe("IANA timezone the schedule is evaluated in"),
11663
+ day: z64.enum(AUTOMATION_SCHEDULE_DAYS).nullable().optional().describe("Day of week for a weekly schedule"),
11664
+ day_of_month: z64.int().min(1).max(31).nullable().optional().describe("Day of month for a monthly schedule"),
11665
+ task: z64.string().nullable().optional().describe("Prompt passed as the run's initial user message")
11666
+ });
11667
+ var setAutomationRevisionSchedulesRequestApiSchema = z64.object({
11668
+ schedules: z64.array(setAutomationRevisionScheduleApiSchema).describe(
11669
+ "The draft's complete desired schedule set; declarations absent here are removed from the draft"
11670
+ )
11671
+ });
11672
+ var setAutomationTriggerSubscriptionRequestApiSchema = z64.object({
11673
+ enabled: z64.boolean().describe("Whether this scope participates"),
11674
+ integration_instance_id: z64.guid().nullable().optional().describe(
11675
+ "Connection this scope fires with. Required to enable a subscription that has none"
11676
+ )
11677
+ });
11678
+ var setAutomationScheduleSubscriptionRequestApiSchema = z64.object({
11679
+ enabled: z64.boolean().describe("Whether this scope participates")
11680
+ });
11681
+ var automationTriggerSubscriptionResponseApiSchema = z64.object({
11682
+ subscription: automationTriggerSubscriptionApiSchema.describe(
11683
+ "The subscription after the change"
11684
+ )
11685
+ });
11686
+ var automationScheduleSubscriptionResponseApiSchema = z64.object({
11687
+ subscription: automationScheduleSubscriptionApiSchema.describe(
11688
+ "The subscription after the change"
11689
+ )
11690
+ });
11284
11691
  var automationRevisionDetailApiSchema = automationRevisionSummaryApiSchema.extend({
11285
11692
  ai_description: z64.string().nullable().describe(
11286
11693
  "AI-generated short description of what this revision does (null until generated)"
@@ -11360,9 +11767,6 @@ var setAutomationRevisionQueueBodyApiSchema = z64.object({
11360
11767
  enabled: z64.boolean().optional().describe(
11361
11768
  "Whether routing is enabled (omit to keep current; default true when new)"
11362
11769
  ),
11363
- concurrency: z64.int().nonnegative().nullable().optional().describe(
11364
- "Per-revision concurrency limit (null for queue default; omit to keep current)"
11365
- ),
11366
11770
  name: revisionNameFieldSchema.nullable().optional().describe("Per-revision name override (null clears; omit to keep current)"),
11367
11771
  description: revisionDescriptionFieldSchema.nullable().optional().describe(
11368
11772
  "Per-revision description override (null clears; omit to keep current)"
@@ -12263,10 +12667,14 @@ var publicClarityProcessSchema = z78.object({
12263
12667
  createdAt: z78.coerce.date()
12264
12668
  });
12265
12669
  var createTeamInviteLinkRequestSchema = z79.object({
12266
- frontendUrl: z79.url()
12670
+ frontendUrl: z79.url().optional().describe(
12671
+ "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."
12672
+ )
12267
12673
  });
12268
12674
  var getTeamInviteLinkQuerySchema = z79.object({
12269
- frontendUrl: z79.url()
12675
+ frontendUrl: z79.url().optional().describe(
12676
+ "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."
12677
+ )
12270
12678
  });
12271
12679
  var teamInviteLinkCreatorSchema = z79.object({
12272
12680
  id: z79.guid(),
@@ -12283,6 +12691,7 @@ var getTeamInviteLinkResponseSchema = z79.object({
12283
12691
  hasLink: z79.boolean(),
12284
12692
  link: teamInviteLinkSchema.optional()
12285
12693
  });
12694
+ var createTeamInviteLinkResponseSchema = teamInviteLinkSchema;
12286
12695
  var joinLinkInfoResponseSchema = z79.object({
12287
12696
  valid: z79.boolean(),
12288
12697
  teamName: z79.string().optional(),
@@ -12294,7 +12703,9 @@ var acceptJoinLinkResponseSchema = z79.object({
12294
12703
  teamId: z79.guid()
12295
12704
  });
12296
12705
  var createClarityProcessInviteLinkRequestSchema = z80.object({
12297
- frontendUrl: z80.url()
12706
+ frontendUrl: z80.url().optional().describe(
12707
+ "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."
12708
+ )
12298
12709
  });
12299
12710
  var clarityProcessInviteLinkSchema = teamInviteLinkSchema;
12300
12711
  var getClarityProcessInviteLinkResponseSchema = z80.object({
@@ -12451,6 +12862,11 @@ var FEATURE_FLAG_CATALOGUE = {
12451
12862
  defaultValue: false,
12452
12863
  description: "Enables the L1-L4 Clarity process hierarchy surfaces, including the process landscape tree and related organize/auto-sort workflows."
12453
12864
  },
12865
+ UNIFIED_CLARITY: {
12866
+ key: "unified_clarity",
12867
+ defaultValue: false,
12868
+ 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."
12869
+ },
12454
12870
  LANDSCAPE_ONBOARDING: {
12455
12871
  key: "landscape_onboarding",
12456
12872
  defaultValue: false,
@@ -12616,6 +13032,11 @@ var FEATURE_FLAG_CATALOGUE = {
12616
13032
  defaultValue: false,
12617
13033
  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
13034
  },
13035
+ SUPERVISED_MODE: {
13036
+ key: "supervised_mode",
13037
+ defaultValue: false,
13038
+ 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."
13039
+ },
12619
13040
  SUPPORT_ESCALATION: {
12620
13041
  key: "support_escalation",
12621
13042
  defaultValue: false,
@@ -12753,6 +13174,9 @@ var jobListItemSchema = z84.object({
12753
13174
  agent_id: z84.guid(),
12754
13175
  agent_name: z84.string(),
12755
13176
  build_id: z84.guid(),
13177
+ // Automation info (null for runs whose agent doesn't belong to an automation)
13178
+ automation_id: z84.guid().nullable(),
13179
+ automation_name: z84.string().nullable(),
12756
13180
  // User info
12757
13181
  user_id: z84.guid().nullable(),
12758
13182
  // Case info
@@ -12790,7 +13214,8 @@ var jobFilterOptionsSchema = z84.object({
12790
13214
  email: z84.string()
12791
13215
  })
12792
13216
  ),
12793
- caseQueues: z84.array(z84.object({ id: z84.string(), name: z84.string() }))
13217
+ caseQueues: z84.array(z84.object({ id: z84.string(), name: z84.string() })),
13218
+ automations: z84.array(z84.object({ id: z84.string(), name: z84.string() }))
12794
13219
  });
12795
13220
  var stepModeSchema = z85.enum(["deterministic", "parameterized", "agent"]).describe("How replay executes this step");
12796
13221
  var workflowParameterSchema = z85.object({
@@ -13498,9 +13923,13 @@ var teamInvitationDetailApiSchema = z93.object({
13498
13923
  }).optional()
13499
13924
  });
13500
13925
  var createTeamInvitationRequestSchema = z93.object({
13501
- email: z93.email(),
13502
- role: z93.string(),
13503
- processId: z93.guid().optional()
13926
+ email: z93.email().describe("Email address of the person to invite."),
13927
+ role: z93.string().describe(
13928
+ "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."
13929
+ ),
13930
+ processId: z93.guid().optional().describe(
13931
+ "Invite the person to this Clarity process rather than the whole team. Requires the team:clarity-member role."
13932
+ )
13504
13933
  });
13505
13934
  var acceptTeamInvitationRequestSchema = z93.object({
13506
13935
  name: z93.string().optional()
@@ -13515,6 +13944,7 @@ var bulkInviteResponseSchema = z93.object({
13515
13944
  skipped: z93.number(),
13516
13945
  failed: z93.number()
13517
13946
  });
13947
+ var createTeamInvitationResponseSchema = teamInvitationDetailApiSchema;
13518
13948
  var TEAM_DISCOVERY_MODES = ["request", "auto"];
13519
13949
  var teamDiscoveryModeSchema = z94.enum(TEAM_DISCOVERY_MODES);
13520
13950
  var BrowserRegionSchema = z94.enum([
@@ -15681,7 +16111,8 @@ function normalizeProfile(value) {
15681
16111
  return {
15682
16112
  type: "api-key",
15683
16113
  apiKey: profile.apiKey,
15684
- apiBaseUrl
16114
+ apiBaseUrl,
16115
+ defaultTeamId: typeof profile.defaultTeamId === "string" ? profile.defaultTeamId : void 0
15685
16116
  };
15686
16117
  }
15687
16118
  return null;
@@ -15859,7 +16290,10 @@ async function resolveConfig(options = {}) {
15859
16290
  apiBaseUrl: env.DUVO_API_BASE_URL ?? profile.apiBaseUrl,
15860
16291
  profileName,
15861
16292
  authType: "api-key",
15862
- defaultTeamId: null
16293
+ // Honored for user-scoped keys (team_id NULL server-side), which can
16294
+ // act on every team the owner can reach; a team-scoped key ignores it
16295
+ // because the server pins the key's team.
16296
+ defaultTeamId: profile.defaultTeamId ?? null
15863
16297
  };
15864
16298
  }
15865
16299
  const fresh = await ensureFreshOAuthProfile(config, profileName, profile);
@@ -16004,6 +16438,11 @@ async function resolveTeamIdFromApiKey(config) {
16004
16438
  "API key is not associated with a team. Pass --team <id> or check your key."
16005
16439
  );
16006
16440
  }
16441
+ if (parsed.data.teams.length > 1) {
16442
+ throw new CliError(
16443
+ "This key can act on multiple teams. Pass --team <id>, set DUVO_TEAM_ID, or choose a default with `duvo team use <id>`. Run `duvo teams list` to see them."
16444
+ );
16445
+ }
16007
16446
  return team.id;
16008
16447
  }
16009
16448
  __name(resolveTeamIdFromApiKey, "resolveTeamIdFromApiKey");
@@ -16838,7 +17277,10 @@ var readinessDropSchema = z104.object({
16838
17277
  credentials_dropped: z104.number(),
16839
17278
  event_triggers_dropped: z104.number(),
16840
17279
  schedules_dropped: z104.number(),
16841
- case_triggers_dropped: z104.number()
17280
+ case_triggers_dropped: z104.number(),
17281
+ runs_interrupted: z104.number(),
17282
+ blocks_approvals: z104.boolean(),
17283
+ runs_at_risk: z104.number()
16842
17284
  });
16843
17285
  var inFlightRunSchema = z104.object({
16844
17286
  agent_id: z104.string(),
@@ -16866,7 +17308,9 @@ var moveAgentResponseSchema = z104.object({
16866
17308
  readiness: z104.object({
16867
17309
  users_missing_on_target: z104.array(readinessDropSchema)
16868
17310
  }),
16869
- in_flight_runs: z104.array(inFlightRunSchema)
17311
+ in_flight_runs: z104.array(inFlightRunSchema),
17312
+ runs_pinned: z104.number(),
17313
+ runs_interrupted: z104.number()
16870
17314
  }),
16871
17315
  dropped_folders: z104.array(namedRefSchema),
16872
17316
  dropped_memory_count: z104.number(),
@@ -18014,14 +18458,39 @@ Files copied to target: ${paths}`);
18014
18458
  "\nOwners not on the target team \u2014 add them there first, or their connections, triggers, and schedules are dropped:"
18015
18459
  );
18016
18460
  for (const u of outcome.readiness.users_missing_on_target) {
18017
- console.log(` - ${u.user_name} (${u.user_id}) \u2014 role ${u.source_role}`);
18461
+ const consequences = [];
18462
+ if (u.runs_interrupted > 0) {
18463
+ consequences.push(`${u.runs_interrupted} run(s) will be stopped`);
18464
+ }
18465
+ if (u.blocks_approvals) {
18466
+ consequences.push("the AOP names them as an approver");
18467
+ }
18468
+ if (u.runs_at_risk > 0) {
18469
+ consequences.push(
18470
+ `${u.runs_at_risk} run(s) they own keep going, but nobody could answer their next question`
18471
+ );
18472
+ }
18473
+ const suffix = consequences.length > 0 ? ` \u2014 ${consequences.join("; ")}` : "";
18474
+ console.log(
18475
+ ` - ${u.user_name} (${u.user_id}) \u2014 role ${u.source_role}${suffix}`
18476
+ );
18018
18477
  }
18019
18478
  }
18020
18479
  if (outcome.in_flight_runs.length > 0) {
18021
- console.log("\nAgents with runs in progress (will continue on target):");
18480
+ console.log("\nAgents with runs in progress:");
18022
18481
  for (const r of outcome.in_flight_runs) {
18023
18482
  console.log(` - ${r.agent_name} \u2014 ${r.count} run(s)`);
18024
18483
  }
18484
+ if (outcome.runs_pinned > 0) {
18485
+ console.log(
18486
+ ` ${outcome.runs_pinned} run(s) keep the source team's connections until their next step, then switch to the target team.`
18487
+ );
18488
+ }
18489
+ if (outcome.runs_interrupted > 0) {
18490
+ console.log(
18491
+ ` ${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.`
18492
+ );
18493
+ }
18025
18494
  }
18026
18495
  const dropped = [];
18027
18496
  if (outcome.event_triggers_dropped > 0) {
@@ -21984,6 +22453,14 @@ function renderOverview(overview) {
21984
22453
  { label: "Name", value: process2.name },
21985
22454
  { label: "Version", value: String(process2.version) },
21986
22455
  { label: "Status", value: process2.status },
22456
+ {
22457
+ label: "Generation started",
22458
+ value: process2.generation_started_at ?? "none"
22459
+ },
22460
+ {
22461
+ label: "Generation activity",
22462
+ value: process2.generation_last_activity_at ?? "none"
22463
+ },
21987
22464
  { label: "Captures", value: String(overview.process.captures.length) },
21988
22465
  {
21989
22466
  label: "Current",
@@ -28729,6 +29206,684 @@ function registerIntegrations(program) {
28729
29206
  }
28730
29207
  __name(registerIntegrations, "registerIntegrations");
28731
29208
 
29209
+ // src/commands/invite/team-roles.ts
29210
+ var TEAM_ROLES2 = Object.values(TEAM_ROLE);
29211
+ var DEFAULT_TEAM_ROLE = TEAM_ROLE.MEMBER;
29212
+ function assertTeamRole(role, flag = "--role") {
29213
+ if (!TEAM_ROLES2.includes(role)) {
29214
+ throw new CliError(
29215
+ `Invalid ${flag} "${role}"; expected one of: ${TEAM_ROLES2.join(", ")}`
29216
+ );
29217
+ }
29218
+ return role;
29219
+ }
29220
+ __name(assertTeamRole, "assertTeamRole");
29221
+
29222
+ // src/commands/invite/bulk.ts
29223
+ var MAX_MEMBERS = 50;
29224
+ function collect3(value, previous = []) {
29225
+ return [...previous, value];
29226
+ }
29227
+ __name(collect3, "collect");
29228
+ function parseMember(value, defaultRole) {
29229
+ const raw = trimRequired(value, "--member");
29230
+ const separator = raw.indexOf("=");
29231
+ if (separator === -1) {
29232
+ return { email: raw, role: defaultRole };
29233
+ }
29234
+ const email = raw.slice(0, separator).trim();
29235
+ const role = raw.slice(separator + 1).trim();
29236
+ if (email.length === 0) {
29237
+ throw new CliError(
29238
+ `Invalid --member "${raw}"; expected <email> or <email>=<role>.`
29239
+ );
29240
+ }
29241
+ return { email, role: assertTeamRole(role, `--member ${email} role`) };
29242
+ }
29243
+ __name(parseMember, "parseMember");
29244
+ function registerInviteBulk(invite) {
29245
+ invite.command("bulk").description("Invite several people to a team and email each invitation").requiredOption(
29246
+ "--member <email[=role]>",
29247
+ "person to invite; repeat for multiple. Append =<role> to override the --role default",
29248
+ collect3,
29249
+ []
29250
+ ).option(
29251
+ "--role <role>",
29252
+ `role for members that don't specify their own (default ${DEFAULT_TEAM_ROLE})`,
29253
+ DEFAULT_TEAM_ROLE
29254
+ ).option(
29255
+ "--team <id>",
29256
+ "team ID (defaults to the team scoped to your credentials)"
29257
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function bulkAction(options) {
29258
+ if (options.member.length === 0) {
29259
+ throw new CliError("Provide at least one --member <email[=role]>.");
29260
+ }
29261
+ const defaultRole = assertTeamRole(options.role ?? DEFAULT_TEAM_ROLE);
29262
+ const members = options.member.map(
29263
+ (value) => parseMember(value, defaultRole)
29264
+ );
29265
+ if (members.length > MAX_MEMBERS) {
29266
+ throw new CliError(
29267
+ `Provide at most ${MAX_MEMBERS} --member values (got ${members.length}).`
29268
+ );
29269
+ }
29270
+ const emails = members.map((member) => member.email.toLowerCase());
29271
+ if (new Set(emails).size !== emails.length) {
29272
+ throw new CliError("--member emails must be unique.");
29273
+ }
29274
+ const config = await requireAuthenticatedConfig(this);
29275
+ const { apiKey, apiBaseUrl } = config;
29276
+ const teamId = await resolveRequiredTeamId(config, {
29277
+ override: options.team ?? getTeamFlag(this)
29278
+ });
29279
+ const raw = await httpRequest({
29280
+ method: "POST",
29281
+ path: buildTeamPath(teamId, "/invites/bulk"),
29282
+ apiKey,
29283
+ apiBaseUrl,
29284
+ body: { members }
29285
+ });
29286
+ const parsed = bulkInviteResponseSchema.safeParse(raw);
29287
+ if (options.json) {
29288
+ printJson(raw);
29289
+ if (parsed.success && parsed.data.failed > 0) {
29290
+ throw new CliError(
29291
+ `${parsed.data.failed} of ${members.length} invitations could not be emailed and were rolled back.`
29292
+ );
29293
+ }
29294
+ return;
29295
+ }
29296
+ if (!parsed.success) {
29297
+ throw new CliError(
29298
+ `Unexpected response from the API: ${parsed.error.message}`
29299
+ );
29300
+ }
29301
+ const { succeeded, skipped, failed } = parsed.data;
29302
+ console.log(green(`Invited ${succeeded} of ${members.length} people.`));
29303
+ console.log();
29304
+ console.log(
29305
+ renderKeyValue([
29306
+ { label: "Invited", value: String(succeeded) },
29307
+ { label: "Skipped", value: String(skipped) },
29308
+ { label: "Failed", value: String(failed) }
29309
+ ])
29310
+ );
29311
+ if (skipped > 0) {
29312
+ console.log();
29313
+ console.log(
29314
+ "Skipped people are already on the team or already hold a pending invitation."
29315
+ );
29316
+ }
29317
+ if (failed > 0) {
29318
+ console.log();
29319
+ console.log(
29320
+ "Failed invitations could not be emailed and were rolled back \u2014 re-run for those addresses."
29321
+ );
29322
+ throw new CliError(
29323
+ `${failed} of ${members.length} invitations could not be emailed and were rolled back.`
29324
+ );
29325
+ }
29326
+ }, "bulkAction"));
29327
+ }
29328
+ __name(registerInviteBulk, "registerInviteBulk");
29329
+
29330
+ // src/api/invite-schemas.ts
29331
+ import { z as z127 } from "zod";
29332
+ var updateTeamInviteResponseSchema = z127.object({
29333
+ id: z127.string(),
29334
+ role: z127.string()
29335
+ });
29336
+ var inviteSuccessResponseSchema = z127.object({
29337
+ success: z127.literal(true)
29338
+ });
29339
+
29340
+ // src/commands/invite/send-invitation-email.ts
29341
+ function classifyFailure(error) {
29342
+ if (error instanceof CliHttpError && error.status < 500) {
29343
+ return "failed";
29344
+ }
29345
+ return "unconfirmed";
29346
+ }
29347
+ __name(classifyFailure, "classifyFailure");
29348
+ async function trySendInvitationEmail(args) {
29349
+ try {
29350
+ const raw = await httpRequest({
29351
+ method: "POST",
29352
+ path: buildTeamPath(
29353
+ args.teamId,
29354
+ `/invites/${encodeURIComponent(args.inviteId)}/send-email`
29355
+ ),
29356
+ apiKey: args.apiKey,
29357
+ apiBaseUrl: args.apiBaseUrl,
29358
+ body: {}
29359
+ });
29360
+ const parsed = inviteSuccessResponseSchema.safeParse(raw);
29361
+ if (parsed.success) {
29362
+ return { status: "sent", error: null };
29363
+ }
29364
+ return { status: "unconfirmed", error: parsed.error.message };
29365
+ } catch (error) {
29366
+ return {
29367
+ status: classifyFailure(error),
29368
+ error: error instanceof Error ? error.message : String(error)
29369
+ };
29370
+ }
29371
+ }
29372
+ __name(trySendInvitationEmail, "trySendInvitationEmail");
29373
+
29374
+ // src/commands/invite/create.ts
29375
+ var EMAIL_SENT_LABEL = {
29376
+ sent: "yes",
29377
+ failed: "no",
29378
+ unconfirmed: "unconfirmed"
29379
+ };
29380
+ function assertEmailDelivered(emailRequested, outcome) {
29381
+ if (!emailRequested || outcome.status === "sent") {
29382
+ return;
29383
+ }
29384
+ throw new CliError(
29385
+ outcome.status === "failed" ? `The invitation was created but --send-email failed: ${outcome.error}` : `The invitation was created but --send-email could not be confirmed: ${outcome.error}`
29386
+ );
29387
+ }
29388
+ __name(assertEmailDelivered, "assertEmailDelivered");
29389
+ function registerInviteCreate(invite) {
29390
+ invite.command("create").description("Invite one person to a team").requiredOption("--email <email>", "email address of the person to invite").option(
29391
+ "--role <role>",
29392
+ `team role to grant (default ${DEFAULT_TEAM_ROLE}, or ${TEAM_ROLE.CLARITY_MEMBER} with --process)`
29393
+ ).option(
29394
+ "--process <id>",
29395
+ `invite them to this Clarity process instead of the whole team (defaults --role to ${TEAM_ROLE.CLARITY_MEMBER}, the only role a process invitation accepts)`
29396
+ ).option(
29397
+ "--send-email",
29398
+ "also email the invitation to the recipient. Without it the invitation is created but nobody is notified"
29399
+ ).option(
29400
+ "--team <id>",
29401
+ "team ID (defaults to the team scoped to your credentials)"
29402
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function createAction(options) {
29403
+ const email = trimRequired(options.email ?? "", "--email");
29404
+ const processId = options.process === void 0 ? void 0 : trimRequired(options.process, "--process");
29405
+ const defaultRole = processId === void 0 ? DEFAULT_TEAM_ROLE : TEAM_ROLE.CLARITY_MEMBER;
29406
+ const role = assertTeamRole(options.role ?? defaultRole);
29407
+ const config = await requireAuthenticatedConfig(this);
29408
+ const { apiKey, apiBaseUrl } = config;
29409
+ const teamId = await resolveRequiredTeamId(config, {
29410
+ override: options.team ?? getTeamFlag(this)
29411
+ });
29412
+ const body = { email, role };
29413
+ if (processId !== void 0) {
29414
+ body.processId = processId;
29415
+ }
29416
+ const raw = await httpRequest({
29417
+ method: "POST",
29418
+ path: buildTeamPath(teamId, "/invites"),
29419
+ apiKey,
29420
+ apiBaseUrl,
29421
+ body
29422
+ });
29423
+ const parsed = createTeamInvitationResponseSchema.safeParse(raw);
29424
+ if (!parsed.success) {
29425
+ if (options.json) {
29426
+ printJson(raw);
29427
+ return;
29428
+ }
29429
+ throw new CliError(
29430
+ `Unexpected response from the API: ${parsed.error.message}`
29431
+ );
29432
+ }
29433
+ const emailRequested = options.sendEmail === true;
29434
+ const emailOutcome = emailRequested ? await trySendInvitationEmail({
29435
+ apiKey,
29436
+ apiBaseUrl,
29437
+ teamId,
29438
+ inviteId: parsed.data.id
29439
+ }) : { status: "failed", error: null };
29440
+ if (options.json) {
29441
+ printJson(raw);
29442
+ assertEmailDelivered(emailRequested, emailOutcome);
29443
+ return;
29444
+ }
29445
+ console.log(green("Invitation created!"));
29446
+ console.log();
29447
+ console.log(
29448
+ renderKeyValue([
29449
+ { label: "Invitation ID", value: parsed.data.id },
29450
+ { label: "Email", value: parsed.data.email },
29451
+ { label: "Role", value: parsed.data.role },
29452
+ { label: "Team", value: parsed.data.team.name },
29453
+ { label: "Process", value: parsed.data.process?.name ?? "\u2014" },
29454
+ { label: "Status", value: parsed.data.status },
29455
+ { label: "Email sent", value: EMAIL_SENT_LABEL[emailOutcome.status] }
29456
+ ])
29457
+ );
29458
+ if (!emailRequested) {
29459
+ console.log();
29460
+ console.log(
29461
+ `Nobody has been notified yet. Send the email with: duvo invite resend ${parsed.data.id}`
29462
+ );
29463
+ return;
29464
+ }
29465
+ if (emailOutcome.status === "failed") {
29466
+ console.log();
29467
+ console.log(
29468
+ `The invitation exists but the email was rejected, so nobody was notified: ${emailOutcome.error}`
29469
+ );
29470
+ console.log(`Send it with: duvo invite resend ${parsed.data.id}`);
29471
+ }
29472
+ if (emailOutcome.status === "unconfirmed") {
29473
+ console.log();
29474
+ console.log(
29475
+ `The invitation exists but the email could not be confirmed: ${emailOutcome.error}`
29476
+ );
29477
+ console.log(
29478
+ `It may or may not have been delivered. Check with the recipient before running: duvo invite resend ${parsed.data.id}`
29479
+ );
29480
+ }
29481
+ assertEmailDelivered(emailRequested, emailOutcome);
29482
+ }, "createAction"));
29483
+ }
29484
+ __name(registerInviteCreate, "registerInviteCreate");
29485
+
29486
+ // src/commands/invite/delete.ts
29487
+ function registerInviteDelete(invite) {
29488
+ invite.command("delete <id>").alias("revoke").description(
29489
+ "Revoke a pending invitation so its link and email stop working"
29490
+ ).option(
29491
+ "--team <id>",
29492
+ "team ID (defaults to the team scoped to your credentials)"
29493
+ ).option("-y, --yes", "skip the confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function deleteAction(id, options) {
29494
+ const inviteId = trimRequired(id, "<id>");
29495
+ const config = await requireAuthenticatedConfig(this);
29496
+ const { apiKey, apiBaseUrl } = config;
29497
+ const teamId = await resolveRequiredTeamId(config, {
29498
+ override: options.team ?? getTeamFlag(this)
29499
+ });
29500
+ await confirmDestructive({
29501
+ message: `Revoke invitation "${inviteId}"?`,
29502
+ skip: options.yes === true
29503
+ });
29504
+ const raw = await httpRequest({
29505
+ method: "DELETE",
29506
+ path: buildTeamPath(teamId, `/invites/${encodeURIComponent(inviteId)}`),
29507
+ apiKey,
29508
+ apiBaseUrl
29509
+ });
29510
+ if (options.json) {
29511
+ printJson(raw);
29512
+ return;
29513
+ }
29514
+ const parsed = inviteSuccessResponseSchema.safeParse(raw);
29515
+ if (!parsed.success) {
29516
+ throw new CliError(
29517
+ `Unexpected response from the API: ${parsed.error.message}`
29518
+ );
29519
+ }
29520
+ console.log(green(`Invitation ${inviteId} revoked.`));
29521
+ }, "deleteAction"));
29522
+ }
29523
+ __name(registerInviteDelete, "registerInviteDelete");
29524
+
29525
+ // src/commands/invite/link.ts
29526
+ var LINK_PATH = "/team-invite-link";
29527
+ function registerGet(link) {
29528
+ link.command("get").description("Show the team's shareable invite link").option(
29529
+ "--team <id>",
29530
+ "team ID (defaults to the team scoped to your credentials)"
29531
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function getAction(options) {
29532
+ const config = await requireAuthenticatedConfig(this);
29533
+ const { apiKey, apiBaseUrl } = config;
29534
+ const teamId = await resolveRequiredTeamId(config, {
29535
+ override: options.team ?? getTeamFlag(this)
29536
+ });
29537
+ const raw = await httpRequest({
29538
+ method: "GET",
29539
+ path: buildTeamPath(teamId, LINK_PATH),
29540
+ apiKey,
29541
+ apiBaseUrl
29542
+ });
29543
+ if (options.json) {
29544
+ printJson(raw);
29545
+ return;
29546
+ }
29547
+ const parsed = getTeamInviteLinkResponseSchema.safeParse(raw);
29548
+ if (!parsed.success) {
29549
+ throw new CliError(
29550
+ `Unexpected response from the API: ${parsed.error.message}`
29551
+ );
29552
+ }
29553
+ const { hasLink, link: inviteLink } = parsed.data;
29554
+ if (!hasLink || !inviteLink) {
29555
+ console.log(
29556
+ "No invite link yet. Create one with: duvo invite link create"
29557
+ );
29558
+ return;
29559
+ }
29560
+ console.log(
29561
+ renderKeyValue([
29562
+ { label: "Link ID", value: inviteLink.id },
29563
+ { label: "URL", value: inviteLink.url ?? "\u2014" },
29564
+ { label: "Created", value: inviteLink.createdAt },
29565
+ {
29566
+ label: "Created by",
29567
+ value: inviteLink.createdBy.name ?? inviteLink.createdBy.email
29568
+ }
29569
+ ])
29570
+ );
29571
+ }, "getAction"));
29572
+ }
29573
+ __name(registerGet, "registerGet");
29574
+ function registerCreate2(link) {
29575
+ link.command("create").description(
29576
+ "Create or regenerate the team's shareable invite link (regenerating invalidates the previous URL)"
29577
+ ).option(
29578
+ "--team <id>",
29579
+ "team ID (defaults to the team scoped to your credentials)"
29580
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function createAction(options) {
29581
+ const config = await requireAuthenticatedConfig(this);
29582
+ const { apiKey, apiBaseUrl } = config;
29583
+ const teamId = await resolveRequiredTeamId(config, {
29584
+ override: options.team ?? getTeamFlag(this)
29585
+ });
29586
+ const raw = await httpRequest({
29587
+ method: "POST",
29588
+ path: buildTeamPath(teamId, LINK_PATH),
29589
+ apiKey,
29590
+ apiBaseUrl,
29591
+ body: {}
29592
+ });
29593
+ if (options.json) {
29594
+ printJson(raw);
29595
+ return;
29596
+ }
29597
+ const parsed = createTeamInviteLinkResponseSchema.safeParse(raw);
29598
+ if (!parsed.success) {
29599
+ throw new CliError(
29600
+ `Unexpected response from the API: ${parsed.error.message}`
29601
+ );
29602
+ }
29603
+ console.log(green("Invite link ready!"));
29604
+ console.log();
29605
+ console.log(
29606
+ renderKeyValue([
29607
+ { label: "Link ID", value: parsed.data.id },
29608
+ { label: "URL", value: parsed.data.url ?? "\u2014" },
29609
+ { label: "Created", value: parsed.data.createdAt }
29610
+ ])
29611
+ );
29612
+ console.log();
29613
+ console.log(
29614
+ "Anyone with this URL can join the team. Any previous link no longer works."
29615
+ );
29616
+ }, "createAction"));
29617
+ }
29618
+ __name(registerCreate2, "registerCreate");
29619
+ function registerDelete2(link) {
29620
+ link.command("delete").description("Delete the team's shareable invite link").option(
29621
+ "--team <id>",
29622
+ "team ID (defaults to the team scoped to your credentials)"
29623
+ ).option("-y, --yes", "skip the confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function deleteAction(options) {
29624
+ const config = await requireAuthenticatedConfig(this);
29625
+ const { apiKey, apiBaseUrl } = config;
29626
+ const teamId = await resolveRequiredTeamId(config, {
29627
+ override: options.team ?? getTeamFlag(this)
29628
+ });
29629
+ await confirmDestructive({
29630
+ message: `Delete the invite link for team "${teamId}"?`,
29631
+ skip: options.yes === true
29632
+ });
29633
+ const raw = await httpRequest({
29634
+ method: "DELETE",
29635
+ path: buildTeamPath(teamId, LINK_PATH),
29636
+ apiKey,
29637
+ apiBaseUrl
29638
+ });
29639
+ if (options.json) {
29640
+ printJson(raw);
29641
+ return;
29642
+ }
29643
+ console.log(green("Invite link deleted."));
29644
+ }, "deleteAction"));
29645
+ }
29646
+ __name(registerDelete2, "registerDelete");
29647
+ function registerInviteLink(invite) {
29648
+ const link = invite.command("link").description("Manage the team's shareable invite link");
29649
+ registerGet(link);
29650
+ registerCreate2(link);
29651
+ registerDelete2(link);
29652
+ }
29653
+ __name(registerInviteLink, "registerInviteLink");
29654
+
29655
+ // src/commands/invite/list.ts
29656
+ var TABLE_COLUMNS27 = [
29657
+ { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
29658
+ { header: "EMAIL", cell: /* @__PURE__ */ __name((row) => row.email, "cell") },
29659
+ { header: "ROLE", cell: /* @__PURE__ */ __name((row) => row.role, "cell") },
29660
+ { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
29661
+ {
29662
+ header: "PROCESS",
29663
+ cell: /* @__PURE__ */ __name((row) => row.process_id ?? "", "cell")
29664
+ },
29665
+ { header: "CREATED", cell: /* @__PURE__ */ __name((row) => row.created_at, "cell") }
29666
+ ];
29667
+ function registerInviteList(invite) {
29668
+ invite.command("list").description("List a team's pending invitations").option(
29669
+ "--process <id>",
29670
+ "list the pending invitations for this Clarity process instead of the team's own"
29671
+ ).option(
29672
+ "--team <id>",
29673
+ "team ID (defaults to the team scoped to your credentials)"
29674
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function listAction(options) {
29675
+ const config = await requireAuthenticatedConfig(this);
29676
+ const { apiKey, apiBaseUrl } = config;
29677
+ const teamId = await resolveRequiredTeamId(config, {
29678
+ override: options.team ?? getTeamFlag(this)
29679
+ });
29680
+ const searchParams = new URLSearchParams();
29681
+ if (options.process !== void 0) {
29682
+ searchParams.append(
29683
+ "processId",
29684
+ trimRequired(options.process, "--process")
29685
+ );
29686
+ }
29687
+ const raw = await httpRequest({
29688
+ method: "GET",
29689
+ path: buildTeamPath(teamId, "/invites"),
29690
+ apiKey,
29691
+ apiBaseUrl,
29692
+ searchParams
29693
+ });
29694
+ if (options.json) {
29695
+ printJson(raw);
29696
+ return;
29697
+ }
29698
+ const parsed = listTeamInvitesResponseSchema.safeParse(raw);
29699
+ if (!parsed.success) {
29700
+ throw new CliError(
29701
+ `Unexpected response from the API: ${parsed.error.message}`
29702
+ );
29703
+ }
29704
+ const { invitations } = parsed.data;
29705
+ if (invitations.length === 0) {
29706
+ console.log("No pending invitations found.");
29707
+ return;
29708
+ }
29709
+ console.log(renderTable(TABLE_COLUMNS27, invitations));
29710
+ console.log(`Showing ${invitations.length}`);
29711
+ }, "listAction"));
29712
+ }
29713
+ __name(registerInviteList, "registerInviteList");
29714
+
29715
+ // src/commands/invite/org-member.ts
29716
+ var ORG_ROLES2 = Object.values(ORG_ROLE);
29717
+ var DEFAULT_ROLE = ORG_ROLE.MEMBER;
29718
+ function registerInviteOrgMember(invite) {
29719
+ invite.command("org-member <org-id>").description(
29720
+ "Invite a person to an organization, optionally onto one of its teams"
29721
+ ).requiredOption("--email <email>", "email address of the person to invite").option(
29722
+ "--role <role>",
29723
+ `organization role to grant: ${ORG_ROLES2.join(", ")} (default ${DEFAULT_ROLE})`,
29724
+ DEFAULT_ROLE
29725
+ ).option("--team-id <id>", "assign the invitee to this team in the org").option(
29726
+ "--send-email",
29727
+ "also email the invitation to the recipient. Without it the invitation is created but nobody is notified"
29728
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function inviteOrgMemberAction(orgId, options) {
29729
+ const email = options.email?.trim();
29730
+ if (email === void 0 || email.length === 0) {
29731
+ throw new CliError("--email must not be empty");
29732
+ }
29733
+ const role = options.role ?? DEFAULT_ROLE;
29734
+ if (!ORG_ROLES2.includes(role)) {
29735
+ throw new CliError(
29736
+ `Invalid --role "${role}"; expected one of: ${ORG_ROLES2.join(", ")}`
29737
+ );
29738
+ }
29739
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
29740
+ const body = { email, role };
29741
+ if (options.teamId !== void 0) {
29742
+ const teamId = options.teamId.trim();
29743
+ if (teamId.length === 0) {
29744
+ throw new CliError("--team-id must not be empty");
29745
+ }
29746
+ body.teamId = teamId;
29747
+ }
29748
+ if (options.sendEmail === true) {
29749
+ body.sendEmail = true;
29750
+ }
29751
+ const raw = await httpRequest({
29752
+ method: "POST",
29753
+ path: `/v2/organizations/${encodeURIComponent(orgId)}/members`,
29754
+ apiKey,
29755
+ apiBaseUrl,
29756
+ body
29757
+ });
29758
+ const parsed = inviteOrgMemberResponseSchema.safeParse(raw);
29759
+ if (options.json) {
29760
+ printJson(raw);
29761
+ if (options.sendEmail === true && parsed.success && !parsed.data.emailSent) {
29762
+ throw new CliError(
29763
+ `The invitation was created (${parsed.data.invitationId}) but --send-email did not deliver it.`
29764
+ );
29765
+ }
29766
+ return;
29767
+ }
29768
+ if (!parsed.success) {
29769
+ throw new CliError(
29770
+ `Unexpected response from POST /v2/organizations/:orgId/members: ${parsed.error.message}`
29771
+ );
29772
+ }
29773
+ console.log(green("Invitation created!"));
29774
+ console.log();
29775
+ console.log(
29776
+ renderKeyValue([
29777
+ { label: "Invitation ID", value: parsed.data.invitationId },
29778
+ { label: "Email", value: email },
29779
+ { label: "Role", value: role },
29780
+ { label: "Team", value: body.teamId ?? "\u2014" },
29781
+ { label: "Email sent", value: parsed.data.emailSent ? "yes" : "no" }
29782
+ ])
29783
+ );
29784
+ if (options.sendEmail === true && !parsed.data.emailSent) {
29785
+ console.log();
29786
+ throw new CliError(
29787
+ `The invitation was created (${parsed.data.invitationId}) but --send-email did not deliver it. Send it from the organization members page.`
29788
+ );
29789
+ }
29790
+ }, "inviteOrgMemberAction"));
29791
+ }
29792
+ __name(registerInviteOrgMember, "registerInviteOrgMember");
29793
+
29794
+ // src/commands/invite/resend.ts
29795
+ function registerInviteResend(invite) {
29796
+ invite.command("resend <id>").description("Email an invitation to its recipient").option(
29797
+ "--team <id>",
29798
+ "team ID (defaults to the team scoped to your credentials)"
29799
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function resendAction(id, options) {
29800
+ const inviteId = trimRequired(id, "<id>");
29801
+ const config = await requireAuthenticatedConfig(this);
29802
+ const { apiKey, apiBaseUrl } = config;
29803
+ const teamId = await resolveRequiredTeamId(config, {
29804
+ override: options.team ?? getTeamFlag(this)
29805
+ });
29806
+ const raw = await httpRequest({
29807
+ method: "POST",
29808
+ path: buildTeamPath(
29809
+ teamId,
29810
+ `/invites/${encodeURIComponent(inviteId)}/send-email`
29811
+ ),
29812
+ apiKey,
29813
+ apiBaseUrl,
29814
+ body: {}
29815
+ });
29816
+ if (options.json) {
29817
+ printJson(raw);
29818
+ return;
29819
+ }
29820
+ const parsed = inviteSuccessResponseSchema.safeParse(raw);
29821
+ if (!parsed.success) {
29822
+ throw new CliError(
29823
+ `Unexpected response from the API: ${parsed.error.message}`
29824
+ );
29825
+ }
29826
+ console.log(green(`Invitation ${inviteId} emailed.`));
29827
+ }, "resendAction"));
29828
+ }
29829
+ __name(registerInviteResend, "registerInviteResend");
29830
+
29831
+ // src/commands/invite/update.ts
29832
+ function registerInviteUpdate(invite) {
29833
+ invite.command("update <id>").description("Change the role on a pending invitation").requiredOption("--role <role>", "new team role for the invitation").option(
29834
+ "--team <id>",
29835
+ "team ID (defaults to the team scoped to your credentials)"
29836
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function updateAction(id, options) {
29837
+ const inviteId = trimRequired(id, "<id>");
29838
+ const role = assertTeamRole(trimRequired(options.role ?? "", "--role"));
29839
+ const config = await requireAuthenticatedConfig(this);
29840
+ const { apiKey, apiBaseUrl } = config;
29841
+ const teamId = await resolveRequiredTeamId(config, {
29842
+ override: options.team ?? getTeamFlag(this)
29843
+ });
29844
+ const raw = await httpRequest({
29845
+ method: "PATCH",
29846
+ path: buildTeamPath(teamId, `/invites/${encodeURIComponent(inviteId)}`),
29847
+ apiKey,
29848
+ apiBaseUrl,
29849
+ body: { role }
29850
+ });
29851
+ if (options.json) {
29852
+ printJson(raw);
29853
+ return;
29854
+ }
29855
+ const parsed = updateTeamInviteResponseSchema.safeParse(raw);
29856
+ if (!parsed.success) {
29857
+ throw new CliError(
29858
+ `Unexpected response from the API: ${parsed.error.message}`
29859
+ );
29860
+ }
29861
+ console.log(green("Invitation updated!"));
29862
+ console.log();
29863
+ console.log(
29864
+ renderKeyValue([
29865
+ { label: "Invitation ID", value: parsed.data.id },
29866
+ { label: "Role", value: parsed.data.role }
29867
+ ])
29868
+ );
29869
+ }, "updateAction"));
29870
+ }
29871
+ __name(registerInviteUpdate, "registerInviteUpdate");
29872
+
29873
+ // src/commands/invite/index.ts
29874
+ function registerInvite(program) {
29875
+ const invite = program.command("invite").description("Invite people to a team or organization");
29876
+ registerInviteList(invite);
29877
+ registerInviteCreate(invite);
29878
+ registerInviteBulk(invite);
29879
+ registerInviteUpdate(invite);
29880
+ registerInviteResend(invite);
29881
+ registerInviteDelete(invite);
29882
+ registerInviteOrgMember(invite);
29883
+ registerInviteLink(invite);
29884
+ }
29885
+ __name(registerInvite, "registerInvite");
29886
+
28732
29887
  // src/commands/login.ts
28733
29888
  import { isCancel as isCancel4, log, password, spinner, text as text2 } from "@clack/prompts";
28734
29889
 
@@ -29422,7 +30577,7 @@ __name(parseNotificationTypeOption, "parseNotificationTypeOption");
29422
30577
 
29423
30578
  // src/commands/notifications/feed.ts
29424
30579
  var MIN_LIMIT11 = 1;
29425
- var TABLE_COLUMNS27 = [
30580
+ var TABLE_COLUMNS28 = [
29426
30581
  { header: "KIND", cell: /* @__PURE__ */ __name((row) => row.kind, "cell") },
29427
30582
  {
29428
30583
  header: "ID",
@@ -29509,7 +30664,7 @@ function registerNotificationsFeed(notifications) {
29509
30664
  console.log("No feed items found.");
29510
30665
  return;
29511
30666
  }
29512
- console.log(renderTable(TABLE_COLUMNS27, items));
30667
+ console.log(renderTable(TABLE_COLUMNS28, items));
29513
30668
  console.log(`Showing ${items.length}`);
29514
30669
  if (nextCursor) {
29515
30670
  console.log(
@@ -29616,7 +30771,7 @@ __name(registerNotificationsGet, "registerNotificationsGet");
29616
30771
 
29617
30772
  // src/commands/notifications/list.ts
29618
30773
  var MIN_LIMIT12 = 1;
29619
- var TABLE_COLUMNS28 = [
30774
+ var TABLE_COLUMNS29 = [
29620
30775
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
29621
30776
  { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
29622
30777
  { header: "SEVERITY", cell: /* @__PURE__ */ __name((row) => row.severity, "cell") },
@@ -29750,7 +30905,7 @@ function registerNotificationsList(notifications) {
29750
30905
  console.log("No notifications found.");
29751
30906
  return;
29752
30907
  }
29753
- console.log(renderTable(TABLE_COLUMNS28, notifications2));
30908
+ console.log(renderTable(TABLE_COLUMNS29, notifications2));
29754
30909
  console.log(`Showing ${notifications2.length}`);
29755
30910
  if (nextCursor) {
29756
30911
  console.log(
@@ -30105,7 +31260,7 @@ function parseHeaders(raw) {
30105
31260
  return result;
30106
31261
  }
30107
31262
  __name(parseHeaders, "parseHeaders");
30108
- var TABLE_COLUMNS29 = [
31263
+ var TABLE_COLUMNS30 = [
30109
31264
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
30110
31265
  { header: "DESCRIPTION", cell: /* @__PURE__ */ __name((row) => row.description, "cell") }
30111
31266
  ];
@@ -30163,7 +31318,7 @@ function registerOauthMcpProbe(mcp) {
30163
31318
  console.log("No tools advertised by this MCP server.");
30164
31319
  return;
30165
31320
  }
30166
- console.log(renderTable(TABLE_COLUMNS29, rows));
31321
+ console.log(renderTable(TABLE_COLUMNS30, rows));
30167
31322
  console.log(`Showing ${rows.length}`);
30168
31323
  }, "probeMcpAction"));
30169
31324
  }
@@ -30254,7 +31409,7 @@ function registerOauth(program) {
30254
31409
  __name(registerOauth, "registerOauth");
30255
31410
 
30256
31411
  // src/commands/plugins/list.ts
30257
- var TABLE_COLUMNS30 = [
31412
+ var TABLE_COLUMNS31 = [
30258
31413
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
30259
31414
  { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
30260
31415
  {
@@ -30288,7 +31443,7 @@ function registerPluginsList(plugins) {
30288
31443
  console.log("No plugins found.");
30289
31444
  return;
30290
31445
  }
30291
- console.log(renderTable(TABLE_COLUMNS30, parsed.data.plugins));
31446
+ console.log(renderTable(TABLE_COLUMNS31, parsed.data.plugins));
30292
31447
  console.log(`Showing ${parsed.data.plugins.length}`);
30293
31448
  }, "listAction"));
30294
31449
  }
@@ -30748,7 +31903,7 @@ function registerPulseAttachmentUrl(pulse) {
30748
31903
  __name(registerPulseAttachmentUrl, "registerPulseAttachmentUrl");
30749
31904
 
30750
31905
  // src/commands/pulse/connections.ts
30751
- var TABLE_COLUMNS31 = [
31906
+ var TABLE_COLUMNS32 = [
30752
31907
  {
30753
31908
  header: "CONNECTION ID",
30754
31909
  cell: /* @__PURE__ */ __name((row) => row.connection_id, "cell")
@@ -30780,7 +31935,7 @@ function registerList4(connections) {
30780
31935
  console.log("No connections attached.");
30781
31936
  return;
30782
31937
  }
30783
- console.log(renderTable(TABLE_COLUMNS31, parsed.data.connections));
31938
+ console.log(renderTable(TABLE_COLUMNS32, parsed.data.connections));
30784
31939
  }, "listAction"));
30785
31940
  }
30786
31941
  __name(registerList4, "registerList");
@@ -31072,7 +32227,7 @@ __name(registerPulseHtml, "registerPulseHtml");
31072
32227
  var DEFAULT_LIMIT11 = 20;
31073
32228
  var MIN_LIMIT13 = 1;
31074
32229
  var MAX_LIMIT11 = 100;
31075
- var TABLE_COLUMNS32 = [
32230
+ var TABLE_COLUMNS33 = [
31076
32231
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
31077
32232
  {
31078
32233
  header: "TITLE",
@@ -31134,7 +32289,7 @@ function registerPulseList(pulse) {
31134
32289
  console.log("No Pulse dashboards found.");
31135
32290
  return;
31136
32291
  }
31137
- console.log(renderTable(TABLE_COLUMNS32, response.artifacts));
32292
+ console.log(renderTable(TABLE_COLUMNS33, response.artifacts));
31138
32293
  console.log(
31139
32294
  `Showing ${response.artifacts.length} of ${response.total} \xB7 offset ${response.offset}`
31140
32295
  );
@@ -31146,7 +32301,7 @@ __name(registerPulseList, "registerPulseList");
31146
32301
  var DEFAULT_LIMIT12 = 100;
31147
32302
  var MIN_LIMIT14 = 1;
31148
32303
  var MAX_LIMIT12 = 500;
31149
- var TABLE_COLUMNS33 = [
32304
+ var TABLE_COLUMNS34 = [
31150
32305
  { header: "ROLE", cell: /* @__PURE__ */ __name((row) => row.role, "cell") },
31151
32306
  {
31152
32307
  header: "CONTENT",
@@ -31194,7 +32349,7 @@ function registerPulseMessages(pulse) {
31194
32349
  console.log("No messages yet.");
31195
32350
  return;
31196
32351
  }
31197
- console.log(renderTable(TABLE_COLUMNS33, data));
32352
+ console.log(renderTable(TABLE_COLUMNS34, data));
31198
32353
  console.log(`Showing ${data.length} of ${total}`);
31199
32354
  if (hasMore) {
31200
32355
  console.log(
@@ -31747,7 +32902,7 @@ function registerPulse(program) {
31747
32902
  __name(registerPulse, "registerPulse");
31748
32903
 
31749
32904
  // src/commands/queue-labels/index.ts
31750
- var TABLE_COLUMNS34 = [
32905
+ var TABLE_COLUMNS35 = [
31751
32906
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
31752
32907
  { header: "KEY", cell: /* @__PURE__ */ __name((row) => row.key, "cell") },
31753
32908
  { header: "VALUE", cell: /* @__PURE__ */ __name((row) => row.value, "cell") },
@@ -31763,9 +32918,9 @@ var TABLE_COLUMNS34 = [
31763
32918
  function registerQueueLabels(program) {
31764
32919
  const labels = program.command("queue-labels").description("Manage label vocabularies on a queue");
31765
32920
  registerList5(labels);
31766
- registerCreate2(labels);
32921
+ registerCreate3(labels);
31767
32922
  registerUpdate2(labels);
31768
- registerDelete2(labels);
32923
+ registerDelete3(labels);
31769
32924
  }
31770
32925
  __name(registerQueueLabels, "registerQueueLabels");
31771
32926
  function registerList5(labels) {
@@ -31801,12 +32956,12 @@ function registerList5(labels) {
31801
32956
  console.log("No labels defined on this queue.");
31802
32957
  return;
31803
32958
  }
31804
- console.log(renderTable(TABLE_COLUMNS34, parsed.data.labels));
32959
+ console.log(renderTable(TABLE_COLUMNS35, parsed.data.labels));
31805
32960
  console.log(`Showing ${parsed.data.labels.length}`);
31806
32961
  }, "listAction"));
31807
32962
  }
31808
32963
  __name(registerList5, "registerList");
31809
- function registerCreate2(labels) {
32964
+ function registerCreate3(labels) {
31810
32965
  labels.command("create").description("Create a label on a queue without assigning it to a case").requiredOption("--queue <id>", "ID of the queue").option("--key <text>", "label key (omit for tag-only labels)").requiredOption("--value <text>", "label value (required, non-empty)").option("--color-hue <n>", "color hue 0-360 (auto-derived if omitted)").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function createAction(options) {
31811
32966
  if (options.value.trim().length === 0) {
31812
32967
  throw new CliError("--value must not be empty");
@@ -31850,7 +33005,7 @@ function registerCreate2(labels) {
31850
33005
  );
31851
33006
  }, "createAction"));
31852
33007
  }
31853
- __name(registerCreate2, "registerCreate");
33008
+ __name(registerCreate3, "registerCreate");
31854
33009
  function registerUpdate2(labels) {
31855
33010
  labels.command("update <label-id>").description(
31856
33011
  "Rename a label or change its color (affects every case it's assigned to)"
@@ -31913,7 +33068,7 @@ function registerUpdate2(labels) {
31913
33068
  }, "updateAction"));
31914
33069
  }
31915
33070
  __name(registerUpdate2, "registerUpdate");
31916
- function registerDelete2(labels) {
33071
+ function registerDelete3(labels) {
31917
33072
  labels.command("delete <label-id>").description(
31918
33073
  "Delete a label from a queue (cascade-removes from every case it was assigned to)"
31919
33074
  ).requiredOption("--queue <id>", "ID of the queue the label belongs to").option("-y, --yes", "skip confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function deleteAction(labelId, options) {
@@ -31944,7 +33099,7 @@ function registerDelete2(labels) {
31944
33099
  console.log(green("Label deleted!"));
31945
33100
  }, "deleteAction"));
31946
33101
  }
31947
- __name(registerDelete2, "registerDelete");
33102
+ __name(registerDelete3, "registerDelete");
31948
33103
  var LABEL_PAGE_SIZE = 1e3;
31949
33104
  async function fetchCurrentLabelValue(queueId, labelId, apiKey, apiBaseUrl) {
31950
33105
  for (let offset = 0; ; offset += LABEL_PAGE_SIZE) {
@@ -32555,7 +33710,7 @@ __name(registerQueuesLinkAgent, "registerQueuesLinkAgent");
32555
33710
  var DEFAULT_LIMIT13 = 20;
32556
33711
  var MIN_LIMIT15 = 1;
32557
33712
  var MAX_LIMIT13 = 100;
32558
- var TABLE_COLUMNS35 = [
33713
+ var TABLE_COLUMNS36 = [
32559
33714
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
32560
33715
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
32561
33716
  {
@@ -32603,7 +33758,7 @@ function registerQueuesList(queues) {
32603
33758
  console.log("No queues found.");
32604
33759
  return;
32605
33760
  }
32606
- console.log(renderTable(TABLE_COLUMNS35, response.queues));
33761
+ console.log(renderTable(TABLE_COLUMNS36, response.queues));
32607
33762
  const resolvedOffset = response.offset ?? offset;
32608
33763
  const total = response.total ?? null;
32609
33764
  const summary = total === null ? `Showing ${response.queues.length} \xB7 offset ${resolvedOffset}` : `Showing ${response.queues.length} of ${total} \xB7 offset ${resolvedOffset}`;
@@ -32861,7 +34016,7 @@ function registerRevisionLoginsDetach(revisionLogins) {
32861
34016
  __name(registerRevisionLoginsDetach, "registerRevisionLoginsDetach");
32862
34017
 
32863
34018
  // src/commands/revision-logins/list.ts
32864
- var TABLE_COLUMNS36 = [
34019
+ var TABLE_COLUMNS37 = [
32865
34020
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
32866
34021
  { header: "DOMAIN", cell: /* @__PURE__ */ __name((row) => row.domain, "cell") },
32867
34022
  {
@@ -32897,7 +34052,7 @@ function registerRevisionLoginsList(revisionLogins) {
32897
34052
  console.log("No logins attached to this revision.");
32898
34053
  return;
32899
34054
  }
32900
- console.log(renderTable(TABLE_COLUMNS36, rows));
34055
+ console.log(renderTable(TABLE_COLUMNS37, rows));
32901
34056
  console.log(`Showing ${rows.length}`);
32902
34057
  }, "listAction"));
32903
34058
  }
@@ -32970,7 +34125,7 @@ function registerRevisionSecretsDetach(revisionSecrets) {
32970
34125
  __name(registerRevisionSecretsDetach, "registerRevisionSecretsDetach");
32971
34126
 
32972
34127
  // src/commands/revision-secrets/list.ts
32973
- var TABLE_COLUMNS37 = [
34128
+ var TABLE_COLUMNS38 = [
32974
34129
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
32975
34130
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
32976
34131
  {
@@ -33008,7 +34163,7 @@ function registerRevisionSecretsList(revisionSecrets) {
33008
34163
  console.log("No secrets attached to this revision.");
33009
34164
  return;
33010
34165
  }
33011
- console.log(renderTable(TABLE_COLUMNS37, rows));
34166
+ console.log(renderTable(TABLE_COLUMNS38, rows));
33012
34167
  console.log(`Showing ${rows.length}`);
33013
34168
  }, "listAction"));
33014
34169
  }
@@ -33024,91 +34179,91 @@ function registerRevisionSecrets(program) {
33024
34179
  __name(registerRevisionSecrets, "registerRevisionSecrets");
33025
34180
 
33026
34181
  // src/api/run-schemas.ts
33027
- import { z as z127 } from "zod";
33028
- var publicRunSchema = z127.object({
33029
- id: z127.string(),
33030
- agent_id: z127.string(),
33031
- build_id: z127.string(),
33032
- status: z127.string(),
33033
- source: z127.string().nullish(),
33034
- sandbox_id: z127.string().nullish(),
33035
- started_at: z127.string().nullish(),
33036
- completed_at: z127.string().nullish(),
33037
- created_at: z127.string(),
33038
- updated_at: z127.string().nullish(),
33039
- human_in_the_loop_enabled: z127.boolean().nullish()
33040
- });
33041
- var startRunResponseSchema = z127.object({
34182
+ import { z as z128 } from "zod";
34183
+ var publicRunSchema = z128.object({
34184
+ id: z128.string(),
34185
+ agent_id: z128.string(),
34186
+ build_id: z128.string(),
34187
+ status: z128.string(),
34188
+ source: z128.string().nullish(),
34189
+ sandbox_id: z128.string().nullish(),
34190
+ started_at: z128.string().nullish(),
34191
+ completed_at: z128.string().nullish(),
34192
+ created_at: z128.string(),
34193
+ updated_at: z128.string().nullish(),
34194
+ human_in_the_loop_enabled: z128.boolean().nullish()
34195
+ });
34196
+ var startRunResponseSchema = z128.object({
33042
34197
  run: publicRunSchema
33043
34198
  });
33044
- var questionOptionSchema = z127.object({
33045
- label: z127.string(),
33046
- description: z127.string().nullish()
33047
- });
33048
- var questionSchema = z127.object({
33049
- question: z127.string(),
33050
- header: z127.string().nullish(),
33051
- options: z127.array(questionOptionSchema).nullish(),
33052
- multi_select: z127.boolean().nullish()
33053
- });
33054
- var pendingHumanRequestSchema = z127.object({
33055
- id: z127.string(),
33056
- title: z127.string(),
33057
- description: z127.string().nullish(),
33058
- created_at: z127.string(),
33059
- type: z127.string(),
33060
- questions: z127.array(questionSchema).nullish()
33061
- });
33062
- var getRunResponseSchema = z127.object({
34199
+ var questionOptionSchema = z128.object({
34200
+ label: z128.string(),
34201
+ description: z128.string().nullish()
34202
+ });
34203
+ var questionSchema = z128.object({
34204
+ question: z128.string(),
34205
+ header: z128.string().nullish(),
34206
+ options: z128.array(questionOptionSchema).nullish(),
34207
+ multi_select: z128.boolean().nullish()
34208
+ });
34209
+ var pendingHumanRequestSchema = z128.object({
34210
+ id: z128.string(),
34211
+ title: z128.string(),
34212
+ description: z128.string().nullish(),
34213
+ created_at: z128.string(),
34214
+ type: z128.string(),
34215
+ questions: z128.array(questionSchema).nullish()
34216
+ });
34217
+ var getRunResponseSchema = z128.object({
33063
34218
  run: publicRunSchema.nullable(),
33064
34219
  pending_human_request: pendingHumanRequestSchema.nullish()
33065
34220
  });
33066
- var stopRunResponseSchema = z127.object({
33067
- success: z127.boolean(),
33068
- message: z127.string().nullish()
33069
- });
33070
- var runMessageSchema = z127.object({
33071
- id: z127.string(),
33072
- type: z127.string(),
33073
- role: z127.string(),
33074
- timestamp: z127.string(),
33075
- text_content: z127.string().nullish(),
33076
- tool_call: z127.object({
33077
- id: z127.string(),
33078
- name: z127.string(),
33079
- arguments: z127.record(z127.string(), z127.unknown()).nullish()
34221
+ var stopRunResponseSchema = z128.object({
34222
+ success: z128.boolean(),
34223
+ message: z128.string().nullish()
34224
+ });
34225
+ var runMessageSchema = z128.object({
34226
+ id: z128.string(),
34227
+ type: z128.string(),
34228
+ role: z128.string(),
34229
+ timestamp: z128.string(),
34230
+ text_content: z128.string().nullish(),
34231
+ tool_call: z128.object({
34232
+ id: z128.string(),
34233
+ name: z128.string(),
34234
+ arguments: z128.record(z128.string(), z128.unknown()).nullish()
33080
34235
  }).nullish(),
33081
- tool_result: z127.object({
33082
- tool_call_id: z127.string(),
33083
- result: z127.unknown().nullish(),
33084
- error: z127.string().nullish()
34236
+ tool_result: z128.object({
34237
+ tool_call_id: z128.string(),
34238
+ result: z128.unknown().nullish(),
34239
+ error: z128.string().nullish()
33085
34240
  }).nullish()
33086
34241
  });
33087
- var listRunMessagesResponseSchema = z127.object({
33088
- messages: z127.array(runMessageSchema),
33089
- total: z127.number().nullish(),
33090
- limit: z127.number().nullish(),
33091
- offset: z127.number().nullish()
34242
+ var listRunMessagesResponseSchema = z128.object({
34243
+ messages: z128.array(runMessageSchema),
34244
+ total: z128.number().nullish(),
34245
+ limit: z128.number().nullish(),
34246
+ offset: z128.number().nullish()
33092
34247
  });
33093
- var postedMessageSchema = z127.object({
33094
- id: z127.string(),
33095
- type: z127.string(),
33096
- role: z127.string(),
33097
- timestamp: z127.string(),
33098
- text_content: z127.string()
34248
+ var postedMessageSchema = z128.object({
34249
+ id: z128.string(),
34250
+ type: z128.string(),
34251
+ role: z128.string(),
34252
+ timestamp: z128.string(),
34253
+ text_content: z128.string()
33099
34254
  });
33100
- var postRunMessageResponseSchema = z127.object({
34255
+ var postRunMessageResponseSchema = z128.object({
33101
34256
  message: postedMessageSchema
33102
34257
  });
33103
- var respondHumanRequestResponseSchema = z127.object({
33104
- human_request: z127.object({
33105
- id: z127.string(),
33106
- run_id: z127.string(),
33107
- title: z127.string(),
33108
- description: z127.string().nullish(),
33109
- response: z127.string().nullish(),
33110
- responded_at: z127.string().nullish(),
33111
- created_at: z127.string()
34258
+ var respondHumanRequestResponseSchema = z128.object({
34259
+ human_request: z128.object({
34260
+ id: z128.string(),
34261
+ run_id: z128.string(),
34262
+ title: z128.string(),
34263
+ description: z128.string().nullish(),
34264
+ response: z128.string().nullish(),
34265
+ responded_at: z128.string().nullish(),
34266
+ created_at: z128.string()
33112
34267
  })
33113
34268
  });
33114
34269
 
@@ -33259,7 +34414,7 @@ var MAX_LIMIT14 = 100;
33259
34414
  var SORT_ORDERS2 = ["asc", "desc"];
33260
34415
  var HAS_ISSUES_VALUES = ["true", "false"];
33261
34416
  var TITLE_PREVIEW_WIDTH = 50;
33262
- var TABLE_COLUMNS38 = [
34417
+ var TABLE_COLUMNS39 = [
33263
34418
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
33264
34419
  { header: "RUN#", cell: /* @__PURE__ */ __name((row) => String(row.run_number), "cell") },
33265
34420
  { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
@@ -33286,7 +34441,7 @@ function registerRunsList(runs) {
33286
34441
  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
34442
  "--status <status>",
33288
34443
  "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(
34444
+ ).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
34445
  "--has-issues <true|false>",
33291
34446
  `show only runs with (or without) issues (${HAS_ISSUES_VALUES.join("|")})`
33292
34447
  ).option(
@@ -33333,6 +34488,9 @@ function registerRunsList(runs) {
33333
34488
  if (options.agent !== void 0) {
33334
34489
  searchParams.append("agent_id", options.agent);
33335
34490
  }
34491
+ if (options.automation !== void 0) {
34492
+ searchParams.append("automation_id", options.automation);
34493
+ }
33336
34494
  if (options.user !== void 0) {
33337
34495
  searchParams.append("user_id", options.user);
33338
34496
  }
@@ -33380,7 +34538,7 @@ function registerRunsList(runs) {
33380
34538
  console.log("No runs found.");
33381
34539
  return;
33382
34540
  }
33383
- console.log(renderTable(TABLE_COLUMNS38, response.data));
34541
+ console.log(renderTable(TABLE_COLUMNS39, response.data));
33384
34542
  console.log(
33385
34543
  `Showing ${response.data.length} of ${response.total} \xB7 offset ${offset}`
33386
34544
  );
@@ -33490,7 +34648,7 @@ var DEFAULT_LIMIT15 = 20;
33490
34648
  var MIN_LIMIT17 = 1;
33491
34649
  var MAX_LIMIT15 = 50;
33492
34650
  var TEXT_PREVIEW_WIDTH2 = 60;
33493
- var TABLE_COLUMNS39 = [
34651
+ var TABLE_COLUMNS40 = [
33494
34652
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
33495
34653
  { header: "ROLE", cell: /* @__PURE__ */ __name((row) => row.role, "cell") },
33496
34654
  { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
@@ -33555,7 +34713,7 @@ function registerRunsMessages(runs) {
33555
34713
  console.log("No messages found.");
33556
34714
  return;
33557
34715
  }
33558
- console.log(renderTable(TABLE_COLUMNS39, response.messages));
34716
+ console.log(renderTable(TABLE_COLUMNS40, response.messages));
33559
34717
  const resolvedOffset = response.offset ?? offset;
33560
34718
  const summary = response.total === null || response.total === void 0 ? `Showing ${response.messages.length} \xB7 offset ${resolvedOffset}` : `Showing ${response.messages.length} of ${response.total} \xB7 offset ${resolvedOffset}`;
33561
34719
  console.log(summary);
@@ -33823,28 +34981,28 @@ function registerRuns(program) {
33823
34981
  __name(registerRuns, "registerRuns");
33824
34982
 
33825
34983
  // src/api/sandbox-schemas.ts
33826
- import { z as z128 } from "zod";
33827
- var createSandboxResponseSchema = z128.object({
33828
- sandbox_id: z128.string(),
33829
- expires_at: z128.string()
34984
+ import { z as z129 } from "zod";
34985
+ var createSandboxResponseSchema = z129.object({
34986
+ sandbox_id: z129.string(),
34987
+ expires_at: z129.string()
33830
34988
  });
33831
- var createSandboxUploadUrlResponseSchema = z128.object({
33832
- upload_url: z128.string(),
33833
- path: z128.string(),
33834
- expires_in_seconds: z128.number()
34989
+ var createSandboxUploadUrlResponseSchema = z129.object({
34990
+ upload_url: z129.string(),
34991
+ path: z129.string(),
34992
+ expires_in_seconds: z129.number()
33835
34993
  });
33836
- var sandboxFileSchema = z128.object({
33837
- name: z128.string(),
33838
- path: z128.string(),
33839
- type: z128.enum(["file", "dir"]),
33840
- size_bytes: z128.number()
34994
+ var sandboxFileSchema = z129.object({
34995
+ name: z129.string(),
34996
+ path: z129.string(),
34997
+ type: z129.enum(["file", "dir"]),
34998
+ size_bytes: z129.number()
33841
34999
  });
33842
- var listSandboxFilesResponseSchema = z128.object({
33843
- files: z128.array(sandboxFileSchema)
35000
+ var listSandboxFilesResponseSchema = z129.object({
35001
+ files: z129.array(sandboxFileSchema)
33844
35002
  });
33845
- var uploadSandboxFileResponseSchema = z128.object({
33846
- path: z128.string(),
33847
- size_bytes: z128.number()
35003
+ var uploadSandboxFileResponseSchema = z129.object({
35004
+ path: z129.string(),
35005
+ size_bytes: z129.number()
33848
35006
  });
33849
35007
  var DEFAULT_SANDBOX_FILES_PATH = "/workspace";
33850
35008
 
@@ -33881,7 +35039,7 @@ function registerSandboxesCreate(sandboxes) {
33881
35039
  __name(registerSandboxesCreate, "registerSandboxesCreate");
33882
35040
 
33883
35041
  // src/commands/sandboxes/files.ts
33884
- var TABLE_COLUMNS40 = [
35042
+ var TABLE_COLUMNS41 = [
33885
35043
  { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
33886
35044
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
33887
35045
  { header: "PATH", cell: /* @__PURE__ */ __name((row) => row.path, "cell") },
@@ -33919,7 +35077,7 @@ function registerSandboxesFiles(sandboxes) {
33919
35077
  console.log("No files found.");
33920
35078
  return;
33921
35079
  }
33922
- console.log(renderTable(TABLE_COLUMNS40, files));
35080
+ console.log(renderTable(TABLE_COLUMNS41, files));
33923
35081
  console.log(`Showing ${files.length}`);
33924
35082
  }, "filesAction"));
33925
35083
  }
@@ -34264,7 +35422,7 @@ function registerSecretsGet(secrets) {
34264
35422
  __name(registerSecretsGet, "registerSecretsGet");
34265
35423
 
34266
35424
  // src/commands/secrets/list.ts
34267
- var TABLE_COLUMNS41 = [
35425
+ var TABLE_COLUMNS42 = [
34268
35426
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
34269
35427
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
34270
35428
  {
@@ -34308,7 +35466,7 @@ function registerSecretsList(secrets) {
34308
35466
  console.log("No secrets found.");
34309
35467
  return;
34310
35468
  }
34311
- console.log(renderTable(TABLE_COLUMNS41, rows));
35469
+ console.log(renderTable(TABLE_COLUMNS42, rows));
34312
35470
  console.log(`Showing ${rows.length}`);
34313
35471
  }, "listAction"));
34314
35472
  }
@@ -34419,7 +35577,7 @@ function registerSecrets(program) {
34419
35577
  __name(registerSecrets, "registerSecrets");
34420
35578
 
34421
35579
  // src/commands/skills/assignments.ts
34422
- var TABLE_COLUMNS42 = [
35580
+ var TABLE_COLUMNS43 = [
34423
35581
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
34424
35582
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") }
34425
35583
  ];
@@ -34447,7 +35605,7 @@ function registerSkillsAssignments(skills) {
34447
35605
  console.log("No agents use this skill.");
34448
35606
  return;
34449
35607
  }
34450
- console.log(renderTable(TABLE_COLUMNS42, assignments));
35608
+ console.log(renderTable(TABLE_COLUMNS43, assignments));
34451
35609
  console.log(`Showing ${assignments.length} of ${total}`);
34452
35610
  }, "assignmentsAction"));
34453
35611
  }
@@ -34455,13 +35613,13 @@ __name(registerSkillsAssignments, "registerSkillsAssignments");
34455
35613
 
34456
35614
  // src/commands/skills/create.ts
34457
35615
  import { readFileSync as readFileSync5 } from "node:fs";
34458
- import { z as z129 } from "zod";
34459
- var createSkillResponseSchema = z129.object({
34460
- skill: z129.object({
34461
- id: z129.string(),
34462
- name: z129.string(),
34463
- description: z129.string(),
34464
- team_id: z129.string()
35616
+ import { z as z130 } from "zod";
35617
+ var createSkillResponseSchema = z130.object({
35618
+ skill: z130.object({
35619
+ id: z130.string(),
35620
+ name: z130.string(),
35621
+ description: z130.string(),
35622
+ team_id: z130.string()
34465
35623
  })
34466
35624
  });
34467
35625
  function registerSkillsCreate(skills) {
@@ -34740,7 +35898,7 @@ function registerSkillsFileUpdate(skills) {
34740
35898
  __name(registerSkillsFileUpdate, "registerSkillsFileUpdate");
34741
35899
 
34742
35900
  // src/commands/skills/files.ts
34743
- var TABLE_COLUMNS43 = [
35901
+ var TABLE_COLUMNS44 = [
34744
35902
  { header: "PATH", cell: /* @__PURE__ */ __name((row) => row.path, "cell") },
34745
35903
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
34746
35904
  {
@@ -34779,7 +35937,7 @@ function registerSkillsFiles(skills) {
34779
35937
  console.log("No files found.");
34780
35938
  return;
34781
35939
  }
34782
- console.log(renderTable(TABLE_COLUMNS43, parsed.data.files));
35940
+ console.log(renderTable(TABLE_COLUMNS44, parsed.data.files));
34783
35941
  console.log(`Showing ${parsed.data.files.length}`);
34784
35942
  }, "filesAction"));
34785
35943
  }
@@ -34836,13 +35994,13 @@ function readExistingContent(source) {
34836
35994
  __name(readExistingContent, "readExistingContent");
34837
35995
 
34838
35996
  // src/commands/skills/install.ts
34839
- import { z as z130 } from "zod";
34840
- var installSkillResponseSchema = z130.object({
34841
- skill: z130.object({
34842
- id: z130.string(),
34843
- name: z130.string(),
34844
- description: z130.string(),
34845
- team_id: z130.string()
35997
+ import { z as z131 } from "zod";
35998
+ var installSkillResponseSchema = z131.object({
35999
+ skill: z131.object({
36000
+ id: z131.string(),
36001
+ name: z131.string(),
36002
+ description: z131.string(),
36003
+ team_id: z131.string()
34846
36004
  })
34847
36005
  });
34848
36006
  function registerSkillsInstall(skills) {
@@ -34991,48 +36149,48 @@ function registerSkillsList(skills) {
34991
36149
  __name(registerSkillsList, "registerSkillsList");
34992
36150
 
34993
36151
  // src/api/skill-revision-schemas.ts
34994
- import { z as z131 } from "zod";
34995
- var skillRevisionSchema = z131.object({
34996
- id: z131.string(),
34997
- skill_id: z131.string(),
34998
- revision_number: z131.number().nullable(),
34999
- status: z131.enum(["draft", "live", "historic"]),
35000
- revision_name: z131.string().nullable(),
35001
- revision_description: z131.string().nullable(),
35002
- created_by: z131.string().nullable(),
35003
- created_by_name: z131.string().nullable(),
35004
- created_at: z131.string(),
35005
- updated_at: z131.string()
35006
- });
35007
- var listSkillRevisionsResponseSchema = z131.object({
35008
- revisions: z131.array(skillRevisionSchema),
35009
- total: z131.number().nullish(),
35010
- limit: z131.number().nullish(),
35011
- offset: z131.number().nullish()
35012
- });
35013
- var createSkillRevisionResponseSchema = z131.object({
36152
+ import { z as z132 } from "zod";
36153
+ var skillRevisionSchema = z132.object({
36154
+ id: z132.string(),
36155
+ skill_id: z132.string(),
36156
+ revision_number: z132.number().nullable(),
36157
+ status: z132.enum(["draft", "live", "historic"]),
36158
+ revision_name: z132.string().nullable(),
36159
+ revision_description: z132.string().nullable(),
36160
+ created_by: z132.string().nullable(),
36161
+ created_by_name: z132.string().nullable(),
36162
+ created_at: z132.string(),
36163
+ updated_at: z132.string()
36164
+ });
36165
+ var listSkillRevisionsResponseSchema = z132.object({
36166
+ revisions: z132.array(skillRevisionSchema),
36167
+ total: z132.number().nullish(),
36168
+ limit: z132.number().nullish(),
36169
+ offset: z132.number().nullish()
36170
+ });
36171
+ var createSkillRevisionResponseSchema = z132.object({
35014
36172
  revision: skillRevisionSchema,
35015
- created: z131.boolean()
36173
+ created: z132.boolean()
35016
36174
  });
35017
- var skillRevisionResponseSchema = z131.object({
36175
+ var skillRevisionResponseSchema = z132.object({
35018
36176
  revision: skillRevisionSchema
35019
36177
  });
35020
- var deleteSkillRevisionResponseSchema = z131.object({
35021
- success: z131.boolean(),
35022
- message: z131.string()
36178
+ var deleteSkillRevisionResponseSchema = z132.object({
36179
+ success: z132.boolean(),
36180
+ message: z132.string()
35023
36181
  });
35024
- var skillRevisionFileSchema = z131.object({
35025
- name: z131.string(),
35026
- path: z131.string(),
35027
- size: z131.number().optional(),
35028
- contentType: z131.string().optional(),
35029
- updatedAt: z131.string().optional()
36182
+ var skillRevisionFileSchema = z132.object({
36183
+ name: z132.string(),
36184
+ path: z132.string(),
36185
+ size: z132.number().optional(),
36186
+ contentType: z132.string().optional(),
36187
+ updatedAt: z132.string().optional()
35030
36188
  });
35031
- var listSkillRevisionFilesResponseSchema = z131.object({
35032
- files: z131.array(skillRevisionFileSchema),
35033
- limit: z131.number().nullish(),
35034
- has_more: z131.boolean().nullish(),
35035
- next_cursor: z131.string().nullish()
36189
+ var listSkillRevisionFilesResponseSchema = z132.object({
36190
+ files: z132.array(skillRevisionFileSchema),
36191
+ limit: z132.number().nullish(),
36192
+ has_more: z132.boolean().nullish(),
36193
+ next_cursor: z132.string().nullish()
35036
36194
  });
35037
36195
 
35038
36196
  // src/commands/skills/revisions/create.ts
@@ -35195,7 +36353,7 @@ __name(registerSkillsRevisionsFileUpdate, "registerSkillsRevisionsFileUpdate");
35195
36353
  var DEFAULT_LIMIT16 = 100;
35196
36354
  var MIN_LIMIT18 = 1;
35197
36355
  var MAX_LIMIT16 = 1e3;
35198
- var TABLE_COLUMNS44 = [
36356
+ var TABLE_COLUMNS45 = [
35199
36357
  { header: "PATH", cell: /* @__PURE__ */ __name((row) => row.path, "cell") },
35200
36358
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
35201
36359
  {
@@ -35257,7 +36415,7 @@ function registerSkillsRevisionsFiles(revisions) {
35257
36415
  );
35258
36416
  return;
35259
36417
  }
35260
- console.log(renderTable(TABLE_COLUMNS44, parsed.data.files));
36418
+ console.log(renderTable(TABLE_COLUMNS45, parsed.data.files));
35261
36419
  console.log(
35262
36420
  nextCursor === null ? `Showing ${parsed.data.files.length}` : `Showing ${parsed.data.files.length} \xB7 more files remain \u2014 next page: --cursor ${nextCursor}`
35263
36421
  );
@@ -35269,7 +36427,7 @@ __name(registerSkillsRevisionsFiles, "registerSkillsRevisionsFiles");
35269
36427
  var DEFAULT_LIMIT17 = 20;
35270
36428
  var MIN_LIMIT19 = 1;
35271
36429
  var MAX_LIMIT17 = 100;
35272
- var TABLE_COLUMNS45 = [
36430
+ var TABLE_COLUMNS46 = [
35273
36431
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
35274
36432
  {
35275
36433
  header: "VERSION",
@@ -35318,7 +36476,7 @@ function registerSkillsRevisionsList(revisions) {
35318
36476
  console.log("No revisions found.");
35319
36477
  return;
35320
36478
  }
35321
- console.log(renderTable(TABLE_COLUMNS45, response.revisions));
36479
+ console.log(renderTable(TABLE_COLUMNS46, response.revisions));
35322
36480
  const resolvedOffset = response.offset ?? offset;
35323
36481
  const total = response.total ?? null;
35324
36482
  const summary = total === null ? `Showing ${response.revisions.length} \xB7 offset ${resolvedOffset}` : `Showing ${response.revisions.length} of ${total} \xB7 offset ${resolvedOffset}`;
@@ -35508,13 +36666,13 @@ __name(registerSkillsSystem, "registerSkillsSystem");
35508
36666
  // src/commands/skills/upload.ts
35509
36667
  import { readFile as readFile10, stat as stat3 } from "node:fs/promises";
35510
36668
  import { basename as basename4 } from "node:path";
35511
- import { z as z132 } from "zod";
35512
- var uploadSkillResponseSchema = z132.object({
35513
- skill: z132.object({
35514
- id: z132.string(),
35515
- name: z132.string(),
35516
- description: z132.string(),
35517
- team_id: z132.string()
36669
+ import { z as z133 } from "zod";
36670
+ var uploadSkillResponseSchema = z133.object({
36671
+ skill: z133.object({
36672
+ id: z133.string(),
36673
+ name: z133.string(),
36674
+ description: z133.string(),
36675
+ team_id: z133.string()
35518
36676
  })
35519
36677
  });
35520
36678
  function registerSkillsUpload(skills) {
@@ -35750,17 +36908,17 @@ function registerSuggestionsGet(suggestions) {
35750
36908
  __name(registerSuggestionsGet, "registerSuggestionsGet");
35751
36909
 
35752
36910
  // src/commands/suggestions/list.ts
35753
- import { z as z133 } from "zod";
36911
+ import { z as z134 } from "zod";
35754
36912
  var DEFAULT_LIMIT18 = 100;
35755
36913
  var MIN_LIMIT20 = 1;
35756
36914
  var MAX_LIMIT18 = 250;
35757
- var listEnvelopeSchema = z133.object({
35758
- data: z133.array(z133.unknown()),
35759
- pending_count: z133.number().int().nonnegative()
36915
+ var listEnvelopeSchema = z134.object({
36916
+ data: z134.array(z134.unknown()),
36917
+ pending_count: z134.number().int().nonnegative()
35760
36918
  });
35761
36919
  var STATUS_FILTERS = ["pending", "history"];
35762
36920
  var TITLE_PREVIEW_WIDTH2 = 50;
35763
- var TABLE_COLUMNS46 = [
36921
+ var TABLE_COLUMNS47 = [
35764
36922
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
35765
36923
  { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
35766
36924
  { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
@@ -35838,7 +36996,7 @@ function registerSuggestionsList(suggestions) {
35838
36996
  console.log(`Pending total: ${pendingCount}`);
35839
36997
  return;
35840
36998
  }
35841
- console.log(renderTable(TABLE_COLUMNS46, data));
36999
+ console.log(renderTable(TABLE_COLUMNS47, data));
35842
37000
  console.log(
35843
37001
  `Showing ${data.length} \xB7 offset ${offset} \xB7 pending total ${pendingCount}`
35844
37002
  );
@@ -35965,7 +37123,7 @@ __name(registerTeamGet, "registerTeamGet");
35965
37123
  var DEFAULT_LIMIT19 = 50;
35966
37124
  var MIN_LIMIT21 = 1;
35967
37125
  var MAX_LIMIT19 = 100;
35968
- var TABLE_COLUMNS47 = [
37126
+ var TABLE_COLUMNS48 = [
35969
37127
  { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
35970
37128
  { header: "NAME", cell: /* @__PURE__ */ __name((row) => row.name ?? "", "cell") },
35971
37129
  { header: "EMAIL", cell: /* @__PURE__ */ __name((row) => row.email, "cell") },
@@ -36016,7 +37174,7 @@ function registerTeamMembers(team) {
36016
37174
  console.log("No members found.");
36017
37175
  return;
36018
37176
  }
36019
- console.log(renderTable(TABLE_COLUMNS47, response.members));
37177
+ console.log(renderTable(TABLE_COLUMNS48, response.members));
36020
37178
  console.log(
36021
37179
  `Showing ${response.members.length} of ${response.total} \xB7 offset ${response.offset}`
36022
37180
  );
@@ -36025,19 +37183,14 @@ function registerTeamMembers(team) {
36025
37183
  __name(registerTeamMembers, "registerTeamMembers");
36026
37184
 
36027
37185
  // src/commands/team/use.ts
36028
- import { z as z134 } from "zod";
37186
+ import { z as z135 } from "zod";
36029
37187
  var TEAM_ID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
36030
- var teamIdSchema = z134.string().regex(TEAM_ID_SHAPE);
37188
+ var teamIdSchema = z135.string().regex(TEAM_ID_SHAPE);
36031
37189
  function registerTeamUse(team) {
36032
37190
  team.command("use <team-id>").description(
36033
- "Set the default team for the active OAuth profile (overridable per-command via --team or DUVO_TEAM_ID)"
37191
+ "Set the default team for the active profile (overridable per-command via --team or DUVO_TEAM_ID)"
36034
37192
  ).action(/* @__PURE__ */ __name(async function useAction(teamId) {
36035
37193
  const auth = await requireAuthenticatedConfig(this);
36036
- if (auth.authType === "api-key") {
36037
- throw new CliError(
36038
- `This is an API-key profile \u2014 the team is baked into the key itself. Create or switch to an OAuth profile to use \`team use\`.`
36039
- );
36040
- }
36041
37194
  const parsedTeamId = teamIdSchema.safeParse(teamId);
36042
37195
  if (!parsedTeamId.success) {
36043
37196
  throw new CliError(
@@ -36050,16 +37203,17 @@ function registerTeamUse(team) {
36050
37203
  auth.apiBaseUrl
36051
37204
  );
36052
37205
  const config = await readConfig();
36053
- const profileFlag = getProfileFlag(this);
36054
- const profileName = profileFlag ?? config.defaultProfile;
37206
+ const profileName = auth.profileName;
36055
37207
  if (!profileName) {
36056
37208
  throw new CliError(
36057
- "No active profile. Run `duvo login` first or pass --profile."
37209
+ "Can't set a default team for an env-supplied credential (DUVO_API_KEY) \u2014 there's no stored profile to persist it to. Set DUVO_TEAM_ID instead, or store the key first with `duvo login --api-key`."
36058
37210
  );
36059
37211
  }
36060
37212
  const profile = config.profiles[profileName];
36061
- if (!profile || profile.type !== "oauth") {
36062
- throw new CliError(`Profile "${profileName}" is not an OAuth profile.`);
37213
+ if (!profile) {
37214
+ throw new CliError(
37215
+ `Profile "${profileName}" does not exist. Run \`duvo profiles list\` to see available profiles.`
37216
+ );
36063
37217
  }
36064
37218
  const updated = {
36065
37219
  ...config,
@@ -36113,10 +37267,10 @@ function registerTeam(program) {
36113
37267
  __name(registerTeam, "registerTeam");
36114
37268
 
36115
37269
  // src/commands/teams/create-org-team.ts
36116
- import { z as z135 } from "zod";
36117
- var createOrgTeamResponseSchema = z135.object({
36118
- id: z135.guid(),
36119
- name: z135.string()
37270
+ import { z as z136 } from "zod";
37271
+ var createOrgTeamResponseSchema = z136.object({
37272
+ id: z136.guid(),
37273
+ name: z136.string()
36120
37274
  });
36121
37275
  function registerTeamsCreateOrgTeam(teams) {
36122
37276
  teams.command("create-org-team <org-id>").description("Create a new team inside an organization you administer").requiredOption("--name <name>", "team name").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function createOrgTeamAction(orgId, options) {
@@ -36153,87 +37307,15 @@ function registerTeamsCreateOrgTeam(teams) {
36153
37307
  }
36154
37308
  __name(registerTeamsCreateOrgTeam, "registerTeamsCreateOrgTeam");
36155
37309
 
36156
- // src/commands/teams/invite-org-member.ts
36157
- var ORG_ROLES2 = Object.values(ORG_ROLE);
36158
- var DEFAULT_ROLE = ORG_ROLE.MEMBER;
36159
- function registerTeamsInviteOrgMember(teams) {
36160
- teams.command("invite-org-member <org-id>").description(
36161
- "Invite a person to an organization, optionally onto one of its teams"
36162
- ).requiredOption("--email <email>", "email address of the person to invite").option(
36163
- "--role <role>",
36164
- `organization role to grant: ${ORG_ROLES2.join(", ")} (default ${DEFAULT_ROLE})`,
36165
- DEFAULT_ROLE
36166
- ).option("--team-id <id>", "assign the invitee to this team in the org").option(
36167
- "--frontend-url <url>",
36168
- "base URL used to build the invitation email link (email is skipped if omitted)"
36169
- ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function inviteOrgMemberAction(orgId, options) {
36170
- const email = options.email?.trim();
36171
- if (email === void 0 || email.length === 0) {
36172
- throw new CliError("--email must not be empty");
36173
- }
36174
- const role = options.role ?? DEFAULT_ROLE;
36175
- if (!ORG_ROLES2.includes(role)) {
36176
- throw new CliError(
36177
- `Invalid --role "${role}"; expected one of: ${ORG_ROLES2.join(", ")}`
36178
- );
36179
- }
36180
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
36181
- const body = { email, role };
36182
- if (options.teamId !== void 0) {
36183
- const teamId = options.teamId.trim();
36184
- if (teamId.length === 0) {
36185
- throw new CliError("--team-id must not be empty");
36186
- }
36187
- body.teamId = teamId;
36188
- }
36189
- if (options.frontendUrl !== void 0) {
36190
- const frontendUrl = options.frontendUrl.trim();
36191
- if (frontendUrl.length === 0) {
36192
- throw new CliError("--frontend-url must not be empty");
36193
- }
36194
- body.frontendUrl = frontendUrl;
36195
- }
36196
- const raw = await httpRequest({
36197
- method: "POST",
36198
- path: `/v2/organizations/${encodeURIComponent(orgId)}/members`,
36199
- apiKey,
36200
- apiBaseUrl,
36201
- body
36202
- });
36203
- if (options.json) {
36204
- printJson(raw);
36205
- return;
36206
- }
36207
- const parsed = inviteOrgMemberResponseSchema.safeParse(raw);
36208
- if (!parsed.success) {
36209
- throw new CliError(
36210
- `Unexpected response from POST /v2/organizations/:orgId/members: ${parsed.error.message}`
36211
- );
36212
- }
36213
- console.log(green("Invitation created!"));
36214
- console.log();
36215
- console.log(
36216
- renderKeyValue([
36217
- { label: "Invitation ID", value: parsed.data.invitationId },
36218
- { label: "Email", value: email },
36219
- { label: "Role", value: role },
36220
- { label: "Team", value: body.teamId ?? "\u2014" },
36221
- { label: "Email sent", value: parsed.data.emailSent ? "yes" : "no" }
36222
- ])
36223
- );
36224
- }, "inviteOrgMemberAction"));
36225
- }
36226
- __name(registerTeamsInviteOrgMember, "registerTeamsInviteOrgMember");
36227
-
36228
37310
  // src/commands/teams/list.ts
36229
- import { z as z136 } from "zod";
36230
- var teamApiSchema2 = z136.object({
36231
- id: z136.string(),
36232
- name: z136.string(),
36233
- organization_id: z136.string().nullable()
37311
+ import { z as z137 } from "zod";
37312
+ var teamApiSchema2 = z137.object({
37313
+ id: z137.string(),
37314
+ name: z137.string(),
37315
+ organization_id: z137.string().nullable()
36234
37316
  });
36235
- var listMyTeamsResponseSchema3 = z136.object({
36236
- teams: z136.array(teamApiSchema2)
37317
+ var listMyTeamsResponseSchema3 = z137.object({
37318
+ teams: z137.array(teamApiSchema2)
36237
37319
  });
36238
37320
  function registerTeamsList(teams) {
36239
37321
  teams.command("list", { isDefault: true }).description("List every team you can act on").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function listAction(options) {
@@ -36276,21 +37358,21 @@ function registerTeamsList(teams) {
36276
37358
  __name(registerTeamsList, "registerTeamsList");
36277
37359
 
36278
37360
  // src/commands/teams/org-insights.ts
36279
- import { z as z137 } from "zod";
36280
- var headlineSchema = z137.object({
36281
- total_runs: z137.number(),
36282
- completed_runs: z137.number(),
36283
- failed_runs: z137.number(),
36284
- success_rate: z137.number().nullable(),
36285
- active_agents: z137.number(),
36286
- active_users: z137.number(),
36287
- start_date: z137.string(),
36288
- end_date: z137.string(),
36289
- truncated: z137.boolean(),
36290
- aggregated_teams: z137.number(),
36291
- total_teams: z137.number()
36292
- });
36293
- var orgInsightsHeadlineResponseSchema = z137.object({
37361
+ import { z as z138 } from "zod";
37362
+ var headlineSchema = z138.object({
37363
+ total_runs: z138.number(),
37364
+ completed_runs: z138.number(),
37365
+ failed_runs: z138.number(),
37366
+ success_rate: z138.number().nullable(),
37367
+ active_agents: z138.number(),
37368
+ active_users: z138.number(),
37369
+ start_date: z138.string(),
37370
+ end_date: z138.string(),
37371
+ truncated: z138.boolean(),
37372
+ aggregated_teams: z138.number(),
37373
+ total_teams: z138.number()
37374
+ });
37375
+ var orgInsightsHeadlineResponseSchema = z138.object({
36294
37376
  headline: headlineSchema
36295
37377
  });
36296
37378
  function formatRate(rate) {
@@ -36358,26 +37440,26 @@ function registerTeamsOrgInsights(teams) {
36358
37440
  __name(registerTeamsOrgInsights, "registerTeamsOrgInsights");
36359
37441
 
36360
37442
  // src/commands/teams/org-metrics.ts
36361
- import { z as z138 } from "zod";
36362
- var teamMetricSchema = z138.object({
36363
- team_id: z138.string(),
36364
- team_name: z138.string(),
36365
- is_deleted: z138.boolean(),
36366
- member_count: z138.number(),
36367
- assignment_count: z138.number(),
36368
- scheduled_job_count: z138.number(),
36369
- total_jobs: z138.number(),
36370
- completed_jobs: z138.number(),
36371
- failed_jobs: z138.number(),
36372
- total_runs: z138.number()
36373
- });
36374
- var orgInsightsMetricsResponseSchema = z138.object({
36375
- teams: z138.array(teamMetricSchema),
36376
- start_date: z138.string(),
36377
- end_date: z138.string(),
36378
- truncated: z138.boolean(),
36379
- total_teams: z138.number(),
36380
- org_member_count: z138.number()
37443
+ import { z as z139 } from "zod";
37444
+ var teamMetricSchema = z139.object({
37445
+ team_id: z139.string(),
37446
+ team_name: z139.string(),
37447
+ is_deleted: z139.boolean(),
37448
+ member_count: z139.number(),
37449
+ assignment_count: z139.number(),
37450
+ scheduled_job_count: z139.number(),
37451
+ total_jobs: z139.number(),
37452
+ completed_jobs: z139.number(),
37453
+ failed_jobs: z139.number(),
37454
+ total_runs: z139.number()
37455
+ });
37456
+ var orgInsightsMetricsResponseSchema = z139.object({
37457
+ teams: z139.array(teamMetricSchema),
37458
+ start_date: z139.string(),
37459
+ end_date: z139.string(),
37460
+ truncated: z139.boolean(),
37461
+ total_teams: z139.number(),
37462
+ org_member_count: z139.number()
36381
37463
  });
36382
37464
  function registerTeamsOrgMetrics(teams) {
36383
37465
  teams.command("org-metrics <org-id>").description("Show per-team run metrics across an organization").option("--start-date <date>", "window start (ISO 8601, default 7d ago)").option("--end-date <date>", "window end (ISO 8601, default now)").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function orgMetricsAction(orgId, options) {
@@ -36440,20 +37522,20 @@ ${total_teams} teams${suffix} \xB7 ${org_member_count} org members`
36440
37522
  __name(registerTeamsOrgMetrics, "registerTeamsOrgMetrics");
36441
37523
 
36442
37524
  // src/commands/teams/org-usage.ts
36443
- import { z as z139 } from "zod";
37525
+ import { z as z140 } from "zod";
36444
37526
  var GRANULARITIES = ["day", "week", "month"];
36445
37527
  var DEFAULT_LOOKBACK_MS = 30 * 24 * 60 * 60 * 1e3;
36446
- var bucketSchema = z139.object({
36447
- period: z139.string(),
36448
- total_runs: z139.number(),
36449
- scheduled_runs: z139.number(),
36450
- on_demand_runs: z139.number()
36451
- });
36452
- var usageChartResponseSchema = z139.object({
36453
- buckets: z139.array(bucketSchema),
36454
- granularity: z139.enum(GRANULARITIES),
36455
- truncated: z139.boolean(),
36456
- total_teams: z139.number()
37528
+ var bucketSchema = z140.object({
37529
+ period: z140.string(),
37530
+ total_runs: z140.number(),
37531
+ scheduled_runs: z140.number(),
37532
+ on_demand_runs: z140.number()
37533
+ });
37534
+ var usageChartResponseSchema = z140.object({
37535
+ buckets: z140.array(bucketSchema),
37536
+ granularity: z140.enum(GRANULARITIES),
37537
+ truncated: z140.boolean(),
37538
+ total_teams: z140.number()
36457
37539
  });
36458
37540
  function registerTeamsOrgUsage(teams) {
36459
37541
  teams.command("org-usage <org-id>").description("Show org-wide run volume over time (scheduled vs on-demand)").option("--start-date <date>", "window start (ISO 8601, default 30d ago)").option("--end-date <date>", "window end (ISO 8601, default now)").option(
@@ -36512,17 +37594,17 @@ function registerTeamsOrgUsage(teams) {
36512
37594
  __name(registerTeamsOrgUsage, "registerTeamsOrgUsage");
36513
37595
 
36514
37596
  // src/commands/teams/org.ts
36515
- import { z as z140 } from "zod";
36516
- var orgTeamSchema = z140.object({
36517
- id: z140.string(),
36518
- name: z140.string(),
36519
- userIsMember: z140.boolean(),
36520
- userRole: z140.string().nullable(),
36521
- memberCount: z140.number()
37597
+ import { z as z141 } from "zod";
37598
+ var orgTeamSchema = z141.object({
37599
+ id: z141.string(),
37600
+ name: z141.string(),
37601
+ userIsMember: z141.boolean(),
37602
+ userRole: z141.string().nullable(),
37603
+ memberCount: z141.number()
36522
37604
  });
36523
- var listOrgTeamsResponseSchema = z140.object({
36524
- teams: z140.array(orgTeamSchema),
36525
- total: z140.number()
37605
+ var listOrgTeamsResponseSchema = z141.object({
37606
+ teams: z141.array(orgTeamSchema),
37607
+ total: z141.number()
36526
37608
  });
36527
37609
  var SORT_BY_VALUES = ["createdAt", "name"];
36528
37610
  function registerTeamsOrg(teams) {
@@ -36583,17 +37665,17 @@ function registerTeamsOrg(teams) {
36583
37665
  __name(registerTeamsOrg, "registerTeamsOrg");
36584
37666
 
36585
37667
  // src/commands/teams/orgs.ts
36586
- import { z as z141 } from "zod";
36587
- var orgMembershipSchema = z141.object({
36588
- organization: z141.object({
36589
- id: z141.string(),
36590
- name: z141.string()
37668
+ import { z as z142 } from "zod";
37669
+ var orgMembershipSchema = z142.object({
37670
+ organization: z142.object({
37671
+ id: z142.string(),
37672
+ name: z142.string()
36591
37673
  }),
36592
- role: z141.string(),
36593
- memberCount: z141.number()
37674
+ role: z142.string(),
37675
+ memberCount: z142.number()
36594
37676
  });
36595
- var listMyOrganizationsResponseSchema = z141.object({
36596
- memberships: z141.array(orgMembershipSchema)
37677
+ var listMyOrganizationsResponseSchema = z142.object({
37678
+ memberships: z142.array(orgMembershipSchema)
36597
37679
  });
36598
37680
  function registerTeamsOrgs(teams) {
36599
37681
  teams.command("orgs").description("List the organizations you belong to and your role in each").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function orgsAction(options) {
@@ -36640,7 +37722,6 @@ function registerTeams(program) {
36640
37722
  registerTeamsOrg(teams);
36641
37723
  registerTeamsOrgs(teams);
36642
37724
  registerTeamsCreateOrgTeam(teams);
36643
- registerTeamsInviteOrgMember(teams);
36644
37725
  registerTeamsOrgInsights(teams);
36645
37726
  registerTeamsOrgMetrics(teams);
36646
37727
  registerTeamsOrgUsage(teams);
@@ -36771,7 +37852,7 @@ __name(isStandaloneBinary, "isStandaloneBinary");
36771
37852
  import { createRequire } from "node:module";
36772
37853
  function getPackageMeta() {
36773
37854
  if (true) {
36774
- return { name: "@duvoai/cli", version: "1.45.2" };
37855
+ return { name: "@duvoai/cli", version: "1.46.0" };
36775
37856
  }
36776
37857
  const require2 = createRequire(import.meta.url);
36777
37858
  const raw = require2("../../package.json");
@@ -37002,15 +38083,25 @@ __name(updateNpmInstall, "updateNpmInstall");
37002
38083
  function registerWhoami(program) {
37003
38084
  program.command("whoami").description(
37004
38085
  "Print the active profile, the authenticated user's name and email, the team ID that subsequent commands will act on, and the auth type"
37005
- ).action(/* @__PURE__ */ __name(async function whoamiAction() {
38086
+ ).option("--json", "output machine-readable JSON").action(/* @__PURE__ */ __name(async function whoamiAction(options) {
37006
38087
  const resolved = await requireAuthenticatedConfig(this);
38088
+ const user = await fetchUser(resolved);
38089
+ const teamId = await resolveActiveTeamId(resolved, getTeamFlag(this));
38090
+ if (options.json) {
38091
+ printJson({
38092
+ profile: resolved.profileName,
38093
+ user,
38094
+ team: teamId,
38095
+ authType: resolved.authType
38096
+ });
38097
+ return;
38098
+ }
37007
38099
  const profileLabel = resolved.profileName ?? "(env-only, no stored profile)";
37008
38100
  console.log(`Profile ${profileLabel}`);
37009
- const userLine = await fetchUserLine(resolved);
37010
- if (userLine !== null) {
38101
+ if (user !== null) {
38102
+ const userLine = user.name ? `${user.name} <${user.email}>` : user.email;
37011
38103
  console.log(`User ${userLine}`);
37012
38104
  }
37013
- const teamId = await resolveActiveTeamId(resolved, getTeamFlag(this));
37014
38105
  if (teamId !== null) {
37015
38106
  console.log(`Team ${teamId}`);
37016
38107
  }
@@ -37019,7 +38110,7 @@ function registerWhoami(program) {
37019
38110
  }, "whoamiAction"));
37020
38111
  }
37021
38112
  __name(registerWhoami, "registerWhoami");
37022
- async function fetchUserLine(config) {
38113
+ async function fetchUser(config) {
37023
38114
  try {
37024
38115
  const raw = await httpRequest({
37025
38116
  method: "GET",
@@ -37031,13 +38122,13 @@ async function fetchUserLine(config) {
37031
38122
  if (!parsed.success) {
37032
38123
  return null;
37033
38124
  }
37034
- const { name, email } = parsed.data.profile;
37035
- return name ? `${name} <${email}>` : email;
38125
+ const { id, name, email } = parsed.data.profile;
38126
+ return { id, name, email };
37036
38127
  } catch {
37037
38128
  return null;
37038
38129
  }
37039
38130
  }
37040
- __name(fetchUserLine, "fetchUserLine");
38131
+ __name(fetchUser, "fetchUser");
37041
38132
  async function resolveActiveTeamId(config, override) {
37042
38133
  try {
37043
38134
  return await resolveRequiredTeamId(config, { override });
@@ -37185,7 +38276,7 @@ function createProgram() {
37185
38276
  "use a specific profile for this invocation (overrides default profile)"
37186
38277
  ).option(
37187
38278
  "--team <id>",
37188
- "use a specific team for this invocation (overrides DUVO_TEAM_ID and profile default; API-key profiles are pinned to the key's team, so a different value is rejected by the server)"
38279
+ "use a specific team for this invocation (overrides DUVO_TEAM_ID and profile default; team-scoped API keys stay pinned to the key's team)"
37189
38280
  ).addOption(
37190
38281
  new Option2(
37191
38282
  "--no-update-notifier",
@@ -37234,6 +38325,7 @@ ${notice}` : "";
37234
38325
  registerSuggestions(program);
37235
38326
  registerTeam(program);
37236
38327
  registerTeams(program);
38328
+ registerInvite(program);
37237
38329
  registerSecrets(program);
37238
38330
  registerCredentials(program);
37239
38331
  registerRevisionSecrets(program);