@duvoai/cli 1.3.0 → 1.5.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
@@ -99,6 +99,7 @@ import { z as z61 } from "zod";
99
99
  import { z as z62 } from "zod";
100
100
  import { z as z63 } from "zod";
101
101
  import { z as z64 } from "zod";
102
+ import { z as z65 } from "zod";
102
103
 
103
104
  // ../node_modules/.pnpm/jsonrepair@3.13.2/node_modules/jsonrepair/lib/esm/utils/JSONRepairError.js
104
105
  var JSONRepairError = class extends Error {
@@ -1659,13 +1660,34 @@ var evalSummarySchema = z8.object({
1659
1660
  });
1660
1661
  var evalFlagCountSchema = z8.object({
1661
1662
  flag: z8.string(),
1662
- count: z8.int()
1663
+ count: z8.int(),
1664
+ label: z8.string().nullable().optional()
1663
1665
  });
1664
1666
  var evalScoresResponseSchema = z8.object({
1665
1667
  total_evaluated: z8.int(),
1666
1668
  with_issues: z8.int(),
1667
1669
  flag_distribution: z8.array(evalFlagCountSchema)
1668
1670
  });
1671
+ var evalRubricSchema = z8.object({
1672
+ id: z8.guid(),
1673
+ slug: z8.string(),
1674
+ title: z8.string(),
1675
+ description: z8.string(),
1676
+ sort_order: z8.number(),
1677
+ deleted_at: z8.string().nullable()
1678
+ });
1679
+ var platformEvalRubricSchema = z8.object({
1680
+ key: z8.string(),
1681
+ label: z8.string(),
1682
+ description: z8.string(),
1683
+ cause: z8.string()
1684
+ });
1685
+ var evalRubricsResponseSchema = z8.object({
1686
+ /** Assignment-specific rubrics persisted in `agent_eval_rubric`. */
1687
+ rubrics: z8.array(evalRubricSchema),
1688
+ /** Platform default rubrics sourced from `EVALUATION_RUBRIC_CATALOG`. */
1689
+ platform_rubrics: z8.array(platformEvalRubricSchema)
1690
+ });
1669
1691
  var evalCountsSchema = z8.object({
1670
1692
  total_evaluated: z8.int(),
1671
1693
  with_issues: z8.int()
@@ -1674,7 +1696,9 @@ var evalCountsByAgentResponseSchema = z8.object({
1674
1696
  by_agent: z8.record(z8.string(), evalCountsSchema)
1675
1697
  });
1676
1698
  var summarizeEvalScoresBodySchema = z8.object({
1677
- since: z8.iso.datetime()
1699
+ since: z8.iso.datetime(),
1700
+ /** `"custom"` restricts to live-build runs + `custom__*` flags only. */
1701
+ scope: z8.enum(["all", "custom"]).optional()
1678
1702
  });
1679
1703
  var summarizeEvalScoresResponseSchema = z8.object({
1680
1704
  data: z8.object({
@@ -1714,6 +1738,7 @@ var AGENT_RUN_SOURCES = [
1714
1738
  "handover",
1715
1739
  "postpone",
1716
1740
  "delegate",
1741
+ "reprocess",
1717
1742
  "trigger"
1718
1743
  ];
1719
1744
  var agentRunSourceSchema = z9.enum(AGENT_RUN_SOURCES);
@@ -1746,6 +1771,7 @@ var SOURCE_TO_INITIATOR = {
1746
1771
  handover: "handover",
1747
1772
  postpone: "case-queue",
1748
1773
  delegate: "case-queue",
1774
+ reprocess: "case-queue",
1749
1775
  trigger: "trigger"
1750
1776
  };
1751
1777
  function mapSourceToInitiator(source) {
@@ -2012,6 +2038,28 @@ function isLegacyModelId(model) {
2012
2038
  }
2013
2039
  __name(isLegacyModelId, "isLegacyModelId");
2014
2040
  __name2(isLegacyModelId, "isLegacyModelId");
2041
+ var CONTEXT_1M_MARKER = "[1m]";
2042
+ var RUNTIME_AUXILIARY_MODEL_IDS = [
2043
+ "claude-haiku-4-5-20251001"
2044
+ ];
2045
+ function buildModelAliasesForProvider(provider) {
2046
+ if (provider === "bedrock") {
2047
+ const aliasableModelIds = [
2048
+ ...CLAUDE_MODEL_IDS,
2049
+ ...RUNTIME_AUXILIARY_MODEL_IDS
2050
+ ];
2051
+ return Object.fromEntries(
2052
+ aliasableModelIds.map((id) => {
2053
+ const bareId = id.endsWith(CONTEXT_1M_MARKER) ? id.slice(0, -CONTEXT_1M_MARKER.length) : id;
2054
+ const marker = id.slice(bareId.length);
2055
+ return [id, `${bareId}-bedrock${marker}`];
2056
+ })
2057
+ );
2058
+ }
2059
+ return {};
2060
+ }
2061
+ __name(buildModelAliasesForProvider, "buildModelAliasesForProvider");
2062
+ __name2(buildModelAliasesForProvider, "buildModelAliasesForProvider");
2015
2063
  var AGENT_CONFIG_VERSION = "v2";
2016
2064
  var DEFAULT_BROWSER_PROVIDER = "browserbase";
2017
2065
  var LEGACY_DEFAULT_BROWSER_PROVIDER = "browserbase";
@@ -2044,24 +2092,6 @@ var BUILD_STATUS = {
2044
2092
  LIVE: "live",
2045
2093
  HISTORIC: "historic"
2046
2094
  };
2047
- var CASE_QUEUE_ITEM_STATUS = {
2048
- PENDING: "pending",
2049
- CLAIMED: "claimed",
2050
- COMPLETED: "completed",
2051
- FAILED: "failed"
2052
- };
2053
- var RETRYABLE_CASE_STATUSES = [
2054
- CASE_QUEUE_ITEM_STATUS.COMPLETED,
2055
- CASE_QUEUE_ITEM_STATUS.FAILED,
2056
- CASE_QUEUE_ITEM_STATUS.CLAIMED
2057
- ];
2058
- function isRetryableCaseStatus(status) {
2059
- return RETRYABLE_CASE_STATUSES.includes(
2060
- status
2061
- );
2062
- }
2063
- __name(isRetryableCaseStatus, "isRetryableCaseStatus");
2064
- __name2(isRetryableCaseStatus, "isRetryableCaseStatus");
2065
2095
  var ALL_EVALUATION_RUBRIC_SEVERITIES = [
2066
2096
  "critical",
2067
2097
  "medium",
@@ -2339,6 +2369,7 @@ var ALL_EVALUATION_RUBRIC_KEYS = Object.keys(
2339
2369
  var PLATFORM_DEFAULT_EVAL_RUBRIC_KEYS = ALL_EVALUATION_RUBRIC_KEYS.filter(
2340
2370
  (k) => EVALUATION_RUBRIC_CATALOG[k].is_default
2341
2371
  );
2372
+ var EVALUATION_FINAL_COMMENT_KEY = "final_comment";
2342
2373
  var EVALUATION_SEVERITY_KEY_SUFFIX = "_severity";
2343
2374
  var EVALUATION_REASON_KEY_SUFFIX = "_reason";
2344
2375
  function getRubricSeverityKey(key) {
@@ -2361,6 +2392,23 @@ function isEvaluationRubricKey(value) {
2361
2392
  }
2362
2393
  __name(isEvaluationRubricKey, "isEvaluationRubricKey");
2363
2394
  __name2(isEvaluationRubricKey, "isEvaluationRubricKey");
2395
+ var CUSTOM_RUBRIC_KEY_PREFIX = "custom__";
2396
+ function isCustomRubricKey(key) {
2397
+ return key.startsWith(CUSTOM_RUBRIC_KEY_PREFIX);
2398
+ }
2399
+ __name(isCustomRubricKey, "isCustomRubricKey");
2400
+ __name2(isCustomRubricKey, "isCustomRubricKey");
2401
+ function isFailingFlag(key, value) {
2402
+ if (key === EVALUATION_FINAL_COMMENT_KEY) {
2403
+ return false;
2404
+ }
2405
+ if (typeof value !== "boolean") {
2406
+ return false;
2407
+ }
2408
+ return isCustomRubricKey(key) ? !value : value;
2409
+ }
2410
+ __name(isFailingFlag, "isFailingFlag");
2411
+ __name2(isFailingFlag, "isFailingFlag");
2364
2412
  var EVALUATION_RUBRIC_KEYS_BY_CAUSE = (() => {
2365
2413
  const mutable = {
2366
2414
  sop_gap: [],
@@ -2664,12 +2712,17 @@ var clarityProcessVersionSchema = z12.union([
2664
2712
  z12.literal(1),
2665
2713
  z12.literal(2)
2666
2714
  ]);
2715
+ var CLARITY_PROCESS_VISIBILITIES = ["team", "restricted"];
2716
+ var clarityProcessVisibilitySchema = z12.enum(
2717
+ CLARITY_PROCESS_VISIBILITIES
2718
+ );
2667
2719
  var clarityProcessSchema = z12.object({
2668
2720
  id: z12.guid(),
2669
2721
  teamId: z12.guid(),
2670
2722
  userId: z12.guid(),
2671
2723
  name: z12.string(),
2672
2724
  status: clarityProcessStatusSchema,
2725
+ visibility: clarityProcessVisibilitySchema,
2673
2726
  /** 1 = legacy, 2 = v2. */
2674
2727
  version: z12.number().int(),
2675
2728
  analysis: clarityAnalysisResponseSchema.nullable(),
@@ -2684,6 +2737,7 @@ var clarityProcessListItemSchema = z12.object({
2684
2737
  teamName: z12.string().optional(),
2685
2738
  name: z12.string(),
2686
2739
  status: clarityProcessStatusSchema,
2740
+ visibility: clarityProcessVisibilitySchema,
2687
2741
  version: z12.number().int(),
2688
2742
  captureCount: z12.number(),
2689
2743
  captureCounts: z12.object({
@@ -2757,7 +2811,8 @@ var createClarityProcessResponseSchema = z12.object({
2757
2811
  });
2758
2812
  var updateClarityProcessSchema = z12.object({
2759
2813
  name: z12.string().min(1).max(255).optional(),
2760
- customPrompt: z12.string().max(5e3).nullable().optional()
2814
+ customPrompt: z12.string().max(5e3).nullable().optional(),
2815
+ visibility: clarityProcessVisibilitySchema.optional()
2761
2816
  });
2762
2817
  var INTERVIEW_LANGUAGES = [
2763
2818
  "en",
@@ -3280,41 +3335,22 @@ var stepEdgeSchema = z14.object({
3280
3335
  "True on exactly one outgoing edge of an exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges."
3281
3336
  )
3282
3337
  });
3283
- var clarityStepBaseSchema = z14.object({
3338
+ var baseStepFields = {
3284
3339
  id: z14.string().min(1).describe(
3285
3340
  'Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: "step-review-invoice"'
3286
3341
  ),
3287
- nodeType: z14.enum(PROCESS_FLOW_NODE_TYPES).describe(
3288
- 'BPMN top-level category. "event" for things that happen (start/end/timer/message/escalation), "task" for work performed, "gateway" for branching decisions.'
3289
- ),
3290
- nodeSubtype: z14.enum([
3291
- ...PROCESS_FLOW_EVENT_SUBTYPES,
3292
- ...PROCESS_FLOW_TASK_SUBTYPES,
3293
- ...PROCESS_FLOW_GATEWAY_SUBTYPES
3294
- ]).describe(
3295
- 'Specific BPMN element. Events: "start", "end", "timer", "message", "escalation". Tasks: "user", "service", "send", "receive", "manual", "businessRule", "script". Gateways: "exclusive", "parallel", "inclusive".'
3296
- ),
3297
3342
  targetSteps: z14.array(stepEdgeSchema).describe(
3298
3343
  "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways must have \u22652 entries with exactly one isDefault: true."
3299
3344
  ),
3300
3345
  title: z14.string().min(1).describe(
3301
- `Short action-oriented heading, 2-5 words. Used as the step's name in lists and BPMN node labels. Example: "Review invoice"`
3302
- ),
3303
- description: z14.string().min(1).describe(
3304
- 'Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: "Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval."'
3346
+ 'Required node label used in lists and BPMN node labels. Structural markers use defaults such as "Start" and "End".'
3305
3347
  ),
3306
3348
  action: z14.string().min(1).nullable().describe(
3307
3349
  'Verb-led one-liner summarizing the concrete action performed. Example: "Reviews invoice line items in NetSuite against the purchase order."'
3308
3350
  ),
3309
- rationale: z14.string().min(1).describe(
3310
- 'Why this step exists in the process \u2014 its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: "Catches mispriced line items before they reach the customer and prevents downstream credit notes."'
3311
- ),
3312
3351
  role: z14.string().min(1).nullable().describe(
3313
3352
  'Performer of this step \u2014 the specific job title, team, or system. Use "Duvo" for automated actions and "System" for system-triggered steps. Examples: "Finance Analyst", "Sales Operations", "Duvo", "System"'
3314
3353
  ),
3315
- sources: z14.array(stepSourceSchema).min(1).describe(
3316
- "Evidence supporting this step's existence and details. At least one source is required \u2014 every step must trace back to something in the captures."
3317
- ),
3318
3354
  system: z14.string().nullable().describe(
3319
3355
  'System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: "NetSuite", "Gmail", "Excel", null'
3320
3356
  ),
@@ -3324,9 +3360,6 @@ var clarityStepBaseSchema = z14.object({
3324
3360
  output: z14.string().nullable().describe(
3325
3361
  'What this step produces or updates. Null on pure waits or events that emit nothing. Example: "Approved invoice record in NetSuite with reviewer signature"'
3326
3362
  ),
3327
- condition: z14.string().nullable().describe(
3328
- 'Decision criteria or precondition that gates this step. Null when the step is unconditional. For gateway nodes, this is the question being evaluated. Example: "Only when invoice total exceeds $10,000"'
3329
- ),
3330
3363
  exception: z14.string().nullable().describe(
3331
3364
  'Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: "Customer disputes line items or PO number does not match"'
3332
3365
  ),
@@ -3342,7 +3375,66 @@ var clarityStepBaseSchema = z14.object({
3342
3375
  confidence: z14.enum(["low", "medium", "high"]).describe(
3343
3376
  'Confidence in the accuracy of this step given evidence quality and completeness. "high" = directly stated by multiple sources, "medium" = stated by one source or inferred from strong signals, "low" = inferred with significant assumptions.'
3344
3377
  )
3378
+ };
3379
+ var eventStepSchema = z14.object({
3380
+ ...baseStepFields,
3381
+ nodeType: z14.literal("event"),
3382
+ nodeSubtype: z14.enum(PROCESS_FLOW_EVENT_SUBTYPES).describe(
3383
+ 'BPMN event subtype. "start" (entry trigger), "end" (terminal state), "timer" (time-based wait), "message" (external communication), "escalation" (route to higher authority).'
3384
+ ),
3385
+ description: z14.string().min(1).nullable().describe(
3386
+ "Optional prose describing what happens at this event. May be null for structural markers."
3387
+ ),
3388
+ rationale: z14.string().min(1).nullable().describe(
3389
+ "Optional reason for the event's existence. May be null for structural markers."
3390
+ ),
3391
+ sources: z14.array(stepSourceSchema).describe(
3392
+ "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema."
3393
+ ),
3394
+ condition: z14.string().nullable().describe(
3395
+ "Always null on events; included for shape compatibility across variants."
3396
+ )
3397
+ });
3398
+ var taskStepSchema = z14.object({
3399
+ ...baseStepFields,
3400
+ nodeType: z14.literal("task"),
3401
+ nodeSubtype: z14.enum(PROCESS_FLOW_TASK_SUBTYPES).describe(
3402
+ 'BPMN task subtype. "user" (human work), "service" (automated/API call), "send"/"receive" (messaging), "manual" (offline physical work), "businessRule" (rule engine), "script" (code execution).'
3403
+ ),
3404
+ description: z14.string().min(1).describe(
3405
+ 'Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: "Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval."'
3406
+ ),
3407
+ rationale: z14.string().min(1).describe(
3408
+ 'Why this step exists in the process \u2014 its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: "Catches mispriced line items before they reach the customer and prevents downstream credit notes."'
3409
+ ),
3410
+ sources: z14.array(stepSourceSchema).min(1).describe(
3411
+ "Evidence supporting this step's existence and details. At least one source is required \u2014 every step must trace back to something in the captures."
3412
+ ),
3413
+ condition: z14.string().nullable().describe(
3414
+ 'Optional precondition that gates this task. Null when the task is unconditional. Example: "Only when invoice total exceeds $10,000"'
3415
+ )
3416
+ });
3417
+ var gatewayStepSchema = z14.object({
3418
+ ...baseStepFields,
3419
+ nodeType: z14.literal("gateway"),
3420
+ nodeSubtype: z14.enum(PROCESS_FLOW_GATEWAY_SUBTYPES).describe(
3421
+ 'BPMN gateway subtype. "exclusive" (XOR \u2014 exactly one branch taken), "parallel" (AND \u2014 all branches taken), "inclusive" (OR \u2014 one or more branches taken).'
3422
+ ),
3423
+ description: z14.string().min(1).describe("Full prose describing the decision logic at this gateway."),
3424
+ rationale: z14.string().min(1).describe("Why this branching decision exists in the process."),
3425
+ sources: z14.array(stepSourceSchema).min(1).describe("Evidence supporting the decision criteria."),
3426
+ condition: z14.preprocess(
3427
+ (value) => value == null || value === "" ? "unknown" : value,
3428
+ z14.string().min(1)
3429
+ ).describe(
3430
+ 'Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as "unknown" via a read-side preprocess; producers should write a real condition string going forward.'
3431
+ )
3345
3432
  });
3433
+ var clarityStepBaseSchema = z14.discriminatedUnion("nodeType", [
3434
+ eventStepSchema,
3435
+ taskStepSchema,
3436
+ gatewayStepSchema
3437
+ ]);
3346
3438
  var extraCaptureNeededValueSchema = z14.object({
3347
3439
  id: z14.guid().describe(
3348
3440
  "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value."
@@ -3366,7 +3458,27 @@ var bpmnStepReadinessAgentStepSchema = z14.object({
3366
3458
  'One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: "Requires human judgement on edge cases that are not documented in the captures."'
3367
3459
  )
3368
3460
  });
3369
- var postprocessClarityStepBaseSchema = clarityStepBaseSchema.extend(extraCaptureNeededAgentStepSchema.shape).extend(bpmnStepReadinessAgentStepSchema.shape).extend({});
3461
+ var postprocessAgentSliceShape = {
3462
+ ...extraCaptureNeededAgentStepSchema.shape,
3463
+ ...bpmnStepReadinessAgentStepSchema.shape
3464
+ };
3465
+ var postprocessEventStepSchema = eventStepSchema.extend(
3466
+ postprocessAgentSliceShape
3467
+ );
3468
+ var postprocessTaskStepSchema = taskStepSchema.extend(
3469
+ postprocessAgentSliceShape
3470
+ );
3471
+ var postprocessGatewayStepSchema = gatewayStepSchema.extend(
3472
+ postprocessAgentSliceShape
3473
+ );
3474
+ var postprocessClarityStepBaseSchema = z14.discriminatedUnion(
3475
+ "nodeType",
3476
+ [
3477
+ postprocessEventStepSchema,
3478
+ postprocessTaskStepSchema,
3479
+ postprocessGatewayStepSchema
3480
+ ]
3481
+ );
3370
3482
  var clarityCurrentProcessDataObjectSchema = z14.object({
3371
3483
  version: z14.number().int().describe(
3372
3484
  "Schema version for the current process data payload. Increment on breaking changes to the data shape so consumers can branch on the version field."
@@ -3510,6 +3622,9 @@ var clarityV2ProcessReadModelSchema = z15.object({
3510
3622
  user_id: z15.guid().describe("Creator user id"),
3511
3623
  name: z15.string().describe("Process name"),
3512
3624
  status: clarityProcessStatusSchema.describe("Lifecycle status"),
3625
+ visibility: clarityProcessVisibilitySchema.describe(
3626
+ "Process visibility. 'team' is workspace-visible to full members; 'restricted' is visible to the creator, org admins, workspace managers/admins, and accepted grant holders."
3627
+ ),
3513
3628
  version: z15.number().int().describe("Schema version (always 2 here)"),
3514
3629
  generation_error: z15.string().nullable().describe("Error message from the most recent failed generation, if any"),
3515
3630
  generation_progress: generationProgressSchema.nullable().describe(
@@ -3660,6 +3775,31 @@ function getClarityProcessRoomName(processId) {
3660
3775
  }
3661
3776
  __name(getClarityProcessRoomName, "getClarityProcessRoomName");
3662
3777
  __name2(getClarityProcessRoomName, "getClarityProcessRoomName");
3778
+ var clarityExportStatusSchema = z17.enum([
3779
+ "queued",
3780
+ "running",
3781
+ "succeeded",
3782
+ "failed"
3783
+ ]);
3784
+ var clarityExportResultSchema = z17.object({
3785
+ diagramId: z17.string().optional(),
3786
+ diagramName: z17.string().optional(),
3787
+ folderId: z17.string().optional()
3788
+ });
3789
+ var clarityExportBaseSchema = z17.object({
3790
+ processId: z17.guid(),
3791
+ exportRunId: z17.guid()
3792
+ });
3793
+ var clarityExportProgressEventDataSchema = clarityExportBaseSchema.extend({
3794
+ status: clarityExportStatusSchema,
3795
+ label: z17.string().optional()
3796
+ });
3797
+ var clarityExportCompletedEventDataSchema = clarityExportBaseSchema.extend({
3798
+ result: clarityExportResultSchema
3799
+ });
3800
+ var clarityExportFailedEventDataSchema = clarityExportBaseSchema.extend({
3801
+ error: z17.string()
3802
+ });
3663
3803
  var clarityProcessChatConversationStatusSchema = z18.enum([
3664
3804
  "open",
3665
3805
  "running",
@@ -4041,6 +4181,138 @@ function makeSentryReporter(sentry) {
4041
4181
  }
4042
4182
  __name(makeSentryReporter, "makeSentryReporter");
4043
4183
  __name2(makeSentryReporter, "makeSentryReporter");
4184
+ var MAX_BLOCKED_DOMAINS = 1e3;
4185
+ var MAX_GUARDRAILS_TEXT_LENGTH = 2e4;
4186
+ var DOMAIN_LABEL = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
4187
+ function stripToHost(value) {
4188
+ if (/^[a-z][a-z0-9+.-]*:\/\//.test(value)) {
4189
+ try {
4190
+ return new URL(value).hostname;
4191
+ } catch {
4192
+ return value;
4193
+ }
4194
+ }
4195
+ const pathStart = ["/", "?", "#"].reduce((idx, ch) => {
4196
+ const at = value.indexOf(ch);
4197
+ return at !== -1 && (idx === -1 || at < idx) ? at : idx;
4198
+ }, -1);
4199
+ const withoutPath = pathStart === -1 ? value : value.slice(0, pathStart);
4200
+ const portStart = withoutPath.indexOf(":");
4201
+ return portStart === -1 ? withoutPath : withoutPath.slice(0, portStart);
4202
+ }
4203
+ __name(stripToHost, "stripToHost");
4204
+ __name2(stripToHost, "stripToHost");
4205
+ function normalizeBlockedDomain(input) {
4206
+ const trimmed = input.trim().toLowerCase();
4207
+ if (trimmed.length === 0) {
4208
+ return { ok: false, reason: "Empty line" };
4209
+ }
4210
+ const host = stripToHost(trimmed);
4211
+ if (host.includes("*")) {
4212
+ return {
4213
+ ok: false,
4214
+ reason: "Wildcards are not needed \u2014 entering `acme.com` blocks acme.com and all subdomains"
4215
+ };
4216
+ }
4217
+ const normalized = host.replace(/\.$/, "");
4218
+ const wwwStripped = normalized.startsWith("www.") ? normalized.slice(4) : normalized;
4219
+ const candidate = wwwStripped.includes(".") ? wwwStripped : normalized;
4220
+ if (!candidate.includes(".")) {
4221
+ return {
4222
+ ok: false,
4223
+ reason: "Not a valid domain \u2014 must contain at least one dot"
4224
+ };
4225
+ }
4226
+ const labels = candidate.split(".");
4227
+ for (const label of labels) {
4228
+ if (!DOMAIN_LABEL.test(label)) {
4229
+ return {
4230
+ ok: false,
4231
+ reason: `"${label}" is not a valid domain label`
4232
+ };
4233
+ }
4234
+ }
4235
+ return { ok: true, value: candidate };
4236
+ }
4237
+ __name(normalizeBlockedDomain, "normalizeBlockedDomain");
4238
+ __name2(normalizeBlockedDomain, "normalizeBlockedDomain");
4239
+ function parseBlockedDomainsList(text3) {
4240
+ const seen = /* @__PURE__ */ new Set();
4241
+ const domains = [];
4242
+ const errors = [];
4243
+ const lines = text3.split(/\r?\n/);
4244
+ for (let i = 0; i < lines.length; i += 1) {
4245
+ const raw = lines[i];
4246
+ if (raw.trim().length === 0) {
4247
+ continue;
4248
+ }
4249
+ const result = normalizeBlockedDomain(raw);
4250
+ if (!result.ok) {
4251
+ errors.push({ line: i + 1, input: raw, reason: result.reason });
4252
+ continue;
4253
+ }
4254
+ if (seen.has(result.value)) {
4255
+ continue;
4256
+ }
4257
+ seen.add(result.value);
4258
+ domains.push(result.value);
4259
+ }
4260
+ return { domains, errors };
4261
+ }
4262
+ __name(parseBlockedDomainsList, "parseBlockedDomainsList");
4263
+ __name2(parseBlockedDomainsList, "parseBlockedDomainsList");
4264
+ function domainToCdpBlockPatterns(domain) {
4265
+ return [
4266
+ `*://${domain}/*`,
4267
+ `*://${domain}:*/*`,
4268
+ `*://${domain}./*`,
4269
+ `*://${domain}.:*/*`,
4270
+ `*://*.${domain}/*`,
4271
+ `*://*.${domain}:*/*`,
4272
+ `*://*.${domain}./*`,
4273
+ `*://*.${domain}.:*/*`
4274
+ ];
4275
+ }
4276
+ __name(domainToCdpBlockPatterns, "domainToCdpBlockPatterns");
4277
+ __name2(domainToCdpBlockPatterns, "domainToCdpBlockPatterns");
4278
+ function blockedDomainsToCdpPatterns(domains) {
4279
+ return domains.flatMap(domainToCdpBlockPatterns);
4280
+ }
4281
+ __name(blockedDomainsToCdpPatterns, "blockedDomainsToCdpPatterns");
4282
+ __name2(blockedDomainsToCdpPatterns, "blockedDomainsToCdpPatterns");
4283
+ function isUrlBlocked(url, blockedDomains) {
4284
+ if (blockedDomains.length === 0) {
4285
+ return { blocked: false };
4286
+ }
4287
+ let host;
4288
+ try {
4289
+ host = new URL(url).hostname.toLowerCase().replace(/\.$/, "");
4290
+ } catch {
4291
+ return { blocked: false };
4292
+ }
4293
+ for (const domain of blockedDomains) {
4294
+ if (host === domain || host.endsWith(`.${domain}`)) {
4295
+ return { blocked: true, matchedDomain: domain, host };
4296
+ }
4297
+ }
4298
+ return { blocked: false };
4299
+ }
4300
+ __name(isUrlBlocked, "isUrlBlocked");
4301
+ __name2(isUrlBlocked, "isUrlBlocked");
4302
+ function blockedDomainAgentErrorMessage(args) {
4303
+ const { host, matchedDomain } = args;
4304
+ const domainLine = host === matchedDomain ? `"${host}" is on this team's browser blocklist` : `"${host}" matches the blocklist entry "${matchedDomain}" (subdomain match)`;
4305
+ return [
4306
+ `A team admin has restricted access to this domain: ${domainLine}, so it cannot be accessed.`,
4307
+ "",
4308
+ "What to do:",
4309
+ "- Check that you're using the correct URLs in your SOP \u2014 you may be pointing at the wrong site or have a typo in the domain.",
4310
+ `- If you genuinely need this domain, contact your team admin to update Team Settings \u2192 Guardrails (currently blocks "${matchedDomain}").`,
4311
+ "- Do NOT attempt to bypass this restriction by reformatting the URL, using a proxy, or other workarounds \u2014 the request will continue to fail."
4312
+ ].join("\n");
4313
+ }
4314
+ __name(blockedDomainAgentErrorMessage, "blockedDomainAgentErrorMessage");
4315
+ __name2(blockedDomainAgentErrorMessage, "blockedDomainAgentErrorMessage");
4044
4316
  var ORG_ROLE = {
4045
4317
  EXECUTIVE: "organization:executive",
4046
4318
  OWNER: "organization:owner",
@@ -4735,6 +5007,8 @@ var createOrganizationRequestSchema = z28.object({
4735
5007
  });
4736
5008
  var DISCOVERY_MODES = ["request", "auto"];
4737
5009
  var discoveryModeSchema = z28.enum(DISCOVERY_MODES);
5010
+ var LLM_PROVIDERS = ["default", "bedrock"];
5011
+ var DEFAULT_LLM_PROVIDER = "default";
4738
5012
  var updateOrganizationRequestSchema = z28.object({
4739
5013
  name: z28.string().min(1).optional(),
4740
5014
  discoveryMode: discoveryModeSchema.optional()
@@ -4892,6 +5166,10 @@ var adminOrgSummarySchema = z29.object({
4892
5166
  discoveryMode: z29.string(),
4893
5167
  enterpriseBillingEnabled: z29.boolean(),
4894
5168
  connectionsSharingEnabled: z29.boolean(),
5169
+ // Optional for backwards compatibility: a response from an older backend
5170
+ // (pre-llm_provider) parses fine and defaults to "default" here. The output
5171
+ // type stays non-optional, so consumers don't need null handling.
5172
+ llmProvider: z29.enum(LLM_PROVIDERS).default(DEFAULT_LLM_PROVIDER),
4895
5173
  createdAt: z29.string().nullable(),
4896
5174
  deletedAt: z29.string().nullable(),
4897
5175
  teamCount: z29.number().int().nonnegative(),
@@ -4954,7 +5232,8 @@ var adminOrgUpdateRequestSchema = z29.object({
4954
5232
  name: z29.string().trim().min(1).max(200).optional(),
4955
5233
  discoveryMode: z29.enum(DISCOVERY_MODES).optional(),
4956
5234
  enterpriseBillingEnabled: z29.boolean().optional(),
4957
- connectionsSharingEnabled: z29.boolean().optional()
5235
+ connectionsSharingEnabled: z29.boolean().optional(),
5236
+ llmProvider: z29.enum(LLM_PROVIDERS).optional()
4958
5237
  }).refine(
4959
5238
  (val) => Object.values(val).some((v) => v !== void 0),
4960
5239
  "At least one field must be provided"
@@ -5228,7 +5507,14 @@ var integrationConfigApiSchema = z31.object({
5228
5507
  integration_name: z31.string(),
5229
5508
  created_at: z31.string(),
5230
5509
  icon_url: z31.string().nullish(),
5231
- is_connected: z31.boolean().optional()
5510
+ is_connected: z31.boolean().optional(),
5511
+ /**
5512
+ * Names of case queues linked to this integration config on the live build.
5513
+ * Populated only for `case-queue-producer` and `case-queue-consumer` types;
5514
+ * null for every other integration type, and null when a case-queue config
5515
+ * has no queues linked (PostgreSQL `json_agg` returns NULL on empty input).
5516
+ */
5517
+ linked_queue_names: z31.array(z31.string()).nullish()
5232
5518
  });
5233
5519
  var userScheduleBlockersSchema = z31.object({
5234
5520
  user_id: z31.string(),
@@ -5328,7 +5614,6 @@ var agentApiSchema = z31.object({
5328
5614
  pinned_at: z31.string().nullable().optional(),
5329
5615
  created_at: z31.string().nullable(),
5330
5616
  updated_at: z31.string().nullable(),
5331
- last_run_at: z31.string().nullable(),
5332
5617
  created_by: z31.object({
5333
5618
  id: z31.string(),
5334
5619
  name: z31.string().nullable(),
@@ -5338,21 +5623,27 @@ var agentApiSchema = z31.object({
5338
5623
  id: z31.string(),
5339
5624
  name: z31.string().nullable(),
5340
5625
  email: z31.string()
5341
- }).nullable().optional(),
5626
+ }).nullable().optional()
5627
+ });
5628
+ var agentUserContextApiSchema = z31.object({
5629
+ last_run_at: z31.string().nullable(),
5342
5630
  latest_build: buildApiSchema.nullable(),
5343
5631
  integration_configs: z31.array(integrationConfigApiSchema),
5344
5632
  user_triggers: z31.object({
5345
5633
  slack_mention: z31.boolean(),
5346
5634
  slack_channel: z31.boolean(),
5347
5635
  teams_mention: z31.boolean()
5348
- }).optional(),
5349
- case_trigger_enabled: z31.boolean().optional(),
5350
- case_trigger_has_conflict: z31.boolean().optional(),
5351
- case_trigger_conflicting_agents: z31.array(conflictingAgentSchema).optional(),
5352
- case_queue_name: z31.string().nullable().optional()
5636
+ }),
5637
+ case_trigger_enabled: z31.boolean(),
5638
+ case_trigger_has_conflict: z31.boolean(),
5639
+ case_trigger_conflicting_agents: z31.array(conflictingAgentSchema),
5640
+ case_queue_name: z31.string().nullable()
5353
5641
  });
5642
+ var agentListItemApiSchema = agentApiSchema.extend(
5643
+ agentUserContextApiSchema.shape
5644
+ );
5354
5645
  var agentsListApiSchema = z31.object({
5355
- agents: z31.array(agentApiSchema),
5646
+ agents: z31.array(agentListItemApiSchema),
5356
5647
  total: z31.int(),
5357
5648
  limit: z31.int(),
5358
5649
  offset: z31.int()
@@ -5741,13 +6032,13 @@ var caseQueueMinSchema = z41.object({
5741
6032
  var caseQueuesForSlotResponseSchema = z41.object({
5742
6033
  queues: z41.array(caseQueueMinSchema)
5743
6034
  });
5744
- var CASE_APPROVAL_DECISION = {
6035
+ var APPROVAL_DECISION = {
5745
6036
  APPROVED: "approved",
5746
6037
  REJECTED: "rejected"
5747
6038
  };
5748
- var caseApprovalDecisionSchema = z42.enum([
5749
- CASE_APPROVAL_DECISION.APPROVED,
5750
- CASE_APPROVAL_DECISION.REJECTED
6039
+ var approvalDecisionSchema = z42.enum([
6040
+ APPROVAL_DECISION.APPROVED,
6041
+ APPROVAL_DECISION.REJECTED
5751
6042
  ]);
5752
6043
  var HUMAN_REQUEST_TITLE_MAX = 200;
5753
6044
  var HUMAN_REQUEST_PROMPT_MAX = 2e3;
@@ -5763,7 +6054,7 @@ var humanRequestBatchRowSchema = z42.object({
5763
6054
  * single shared question across approvers.
5764
6055
  */
5765
6056
  prompt: z42.string(),
5766
- decision: caseApprovalDecisionSchema.nullable(),
6057
+ decision: approvalDecisionSchema.nullable(),
5767
6058
  responded_at: z42.string().nullable(),
5768
6059
  responded_by_user_id: z42.string().uuid().nullable(),
5769
6060
  responded_by_name: z42.string().nullable(),
@@ -5806,7 +6097,7 @@ var requestCaseApprovalsBatchStatusSchema = z42.enum([
5806
6097
  ]);
5807
6098
  var requestCaseApprovalsDecisionEntrySchema = z42.object({
5808
6099
  assigneeUserId: z42.string().uuid(),
5809
- decision: caseApprovalDecisionSchema,
6100
+ decision: approvalDecisionSchema,
5810
6101
  respondedAt: z42.string(),
5811
6102
  respondedByUserId: z42.string().uuid()
5812
6103
  });
@@ -5873,6 +6164,7 @@ var caseQueueItemEventSchema = z43.object({
5873
6164
  agent_run_id: z43.guid().nullable(),
5874
6165
  human_request_id: z43.guid().nullable(),
5875
6166
  type: z43.string(),
6167
+ reason: z43.string().nullable(),
5876
6168
  created_at: z43.string(),
5877
6169
  agent_id: z43.guid().nullable(),
5878
6170
  agent_name: z43.string().nullable(),
@@ -6006,13 +6298,22 @@ var caseBulkDeleteResponseSchema = z43.object({
6006
6298
  deletedCount: z43.number(),
6007
6299
  interruptedRunIds: z43.array(z43.guid())
6008
6300
  });
6009
- var caseBulkRetryResponseSchema = z43.object({
6010
- retriedCount: z43.number(),
6011
- skippedCount: z43.number()
6012
- });
6013
- var caseBulkDelegateResponseSchema = z43.object({
6014
- delegatedCount: z43.number(),
6015
- skippedCount: z43.number()
6301
+ var caseBulkReprocessResponseSchema = z43.object({
6302
+ reprocessedCount: z43.number(),
6303
+ skippedCount: z43.number(),
6304
+ // Deprecated aliases of `reprocessedCount`, both equal to it. Returned so
6305
+ // clients 308-redirected here from the deprecated `bulk-delegate` /
6306
+ // `bulk-retry` endpoints still find their original field. Optional +
6307
+ // `deprecated` so consumers don't couple to them; removed with those aliases
6308
+ // at the 2026-06-10 sunset.
6309
+ delegatedCount: z43.number().meta({
6310
+ deprecated: true,
6311
+ description: "Deprecated alias of reprocessedCount, kept for clients redirected from bulk-delegate. Removed on 2026-06-10."
6312
+ }).optional(),
6313
+ retriedCount: z43.number().meta({
6314
+ deprecated: true,
6315
+ description: "Deprecated alias of reprocessedCount, kept for clients redirected from bulk-retry. Removed on 2026-06-10."
6316
+ }).optional()
6016
6317
  });
6017
6318
  var caseBulkStatusUpdateResponseSchema = z43.object({
6018
6319
  updatedCount: z43.number(),
@@ -6401,9 +6702,6 @@ var acceptJoinLinkResponseSchema = z45.object({
6401
6702
  var createClarityProcessInviteLinkRequestSchema = z46.object({
6402
6703
  frontendUrl: z46.url()
6403
6704
  });
6404
- var getClarityProcessInviteLinkQuerySchema = z46.object({
6405
- frontendUrl: z46.url()
6406
- });
6407
6705
  var clarityProcessInviteLinkSchema = teamInviteLinkSchema;
6408
6706
  var getClarityProcessInviteLinkResponseSchema = z46.object({
6409
6707
  hasLink: z46.boolean(),
@@ -7358,7 +7656,14 @@ var RunConfigSchema = AgentConfigSchema.extend({
7358
7656
  conversationHistory: z57.array(ThreadContextMessageSchema).optional(),
7359
7657
  chatFiles: z57.array(ChatFileReferenceSchema).optional(),
7360
7658
  /** IANA timezone (e.g. `"Europe/Prague"`). Consumers should fall back to UTC when absent. */
7361
- timezone: z57.string().optional()
7659
+ timezone: z57.string().optional(),
7660
+ /**
7661
+ * ISO 8601 timestamp captured when the run was created. Frozen at
7662
+ * run-creation time and never recomputed, so resumes reuse the same value —
7663
+ * the runtime injects it into the cached system prompt and a changing value
7664
+ * would bust the prompt cache.
7665
+ */
7666
+ sessionStartedAt: z57.string().optional()
7362
7667
  });
7363
7668
  var StoredRunConfigV0Schema = z57.object({
7364
7669
  version: z57.literal("v0")
@@ -7633,73 +7938,101 @@ var teamInsightsUsersResponseSchema = z61.object({
7633
7938
  data: z61.array(teamInsightsUserWithAgentsAndRunsSchema),
7634
7939
  total: z61.number()
7635
7940
  });
7636
- var userDismissalListResponseSchema = z62.object({
7637
- data: z62.array(z62.string())
7941
+ var guardrailsAuthorSchema = z62.object({
7942
+ id: z62.guid(),
7943
+ name: z62.string().nullable(),
7944
+ email: z62.email()
7945
+ });
7946
+ var guardrailsRevisionSchema = z62.object({
7947
+ id: z62.guid(),
7948
+ teamId: z62.guid(),
7949
+ guardrailsText: z62.string().nullable(),
7950
+ blockedDomains: z62.array(z62.string()),
7951
+ createdAt: z62.string(),
7952
+ createdBy: guardrailsAuthorSchema
7953
+ });
7954
+ var getTeamGuardrailsResponseSchema = z62.object({
7955
+ current: guardrailsRevisionSchema.nullable()
7956
+ });
7957
+ var listTeamGuardrailsRevisionsQuerySchema = z62.object({
7958
+ limit: z62.coerce.number().int().min(1).max(100).default(20),
7959
+ offset: z62.coerce.number().int().min(0).default(0)
7960
+ });
7961
+ var listTeamGuardrailsRevisionsResponseSchema = z62.object({
7962
+ revisions: z62.array(guardrailsRevisionSchema),
7963
+ total: z62.number().int().nonnegative()
7964
+ });
7965
+ var createTeamGuardrailsRevisionRequestSchema = z62.object({
7966
+ guardrailsText: z62.string().max(MAX_GUARDRAILS_TEXT_LENGTH).nullable().transform((value) => value && value.trim().length > 0 ? value : null),
7967
+ blockedDomains: z62.array(z62.string()).max(MAX_BLOCKED_DOMAINS)
7968
+ });
7969
+ var userDismissalListResponseSchema = z63.object({
7970
+ data: z63.array(z63.string())
7638
7971
  });
7639
- var userDismissalMutationSchema = z62.object({
7640
- elementKey: z62.string()
7972
+ var userDismissalMutationSchema = z63.object({
7973
+ elementKey: z63.string()
7641
7974
  });
7642
7975
  var PASSWORD_MIN = 1;
7643
7976
  var PASSWORD_MAX = 1024;
7644
7977
  var NAME_MAX = 200;
7645
7978
  var URL_MAX = 500;
7646
7979
  var USERNAME_MAX = 200;
7647
- var vpnProxyConfigSummarySchema = z63.object({
7648
- id: z63.guid(),
7649
- name: z63.string(),
7650
- server: z63.string(),
7651
- username: z63.string(),
7652
- enabled: z63.boolean(),
7653
- passwordSet: z63.boolean(),
7654
- organizationCount: z63.number().int().nonnegative(),
7655
- createdAt: z63.string(),
7656
- updatedAt: z63.string()
7657
- });
7658
- var vpnProxyConfigListResponseSchema = z63.object({
7659
- configs: z63.array(vpnProxyConfigSummarySchema)
7660
- });
7661
- var vpnProxyConfigCreateRequestSchema = z63.object({
7662
- name: z63.string().trim().min(1).max(NAME_MAX),
7663
- server: z63.string().trim().min(1).max(URL_MAX).url(),
7664
- username: z63.string().trim().min(1).max(USERNAME_MAX),
7665
- password: z63.string().min(PASSWORD_MIN).max(PASSWORD_MAX),
7666
- enabled: z63.boolean().prefault(true)
7667
- });
7668
- var vpnProxyConfigCreateResponseSchema = z63.object({
7980
+ var vpnProxyConfigSummarySchema = z64.object({
7981
+ id: z64.guid(),
7982
+ name: z64.string(),
7983
+ server: z64.string(),
7984
+ username: z64.string(),
7985
+ enabled: z64.boolean(),
7986
+ passwordSet: z64.boolean(),
7987
+ organizationCount: z64.number().int().nonnegative(),
7988
+ createdAt: z64.string(),
7989
+ updatedAt: z64.string()
7990
+ });
7991
+ var vpnProxyConfigListResponseSchema = z64.object({
7992
+ configs: z64.array(vpnProxyConfigSummarySchema)
7993
+ });
7994
+ var vpnProxyConfigCreateRequestSchema = z64.object({
7995
+ name: z64.string().trim().min(1).max(NAME_MAX),
7996
+ server: z64.string().trim().min(1).max(URL_MAX).url(),
7997
+ username: z64.string().trim().min(1).max(USERNAME_MAX),
7998
+ password: z64.string().min(PASSWORD_MIN).max(PASSWORD_MAX),
7999
+ enabled: z64.boolean().prefault(true)
8000
+ });
8001
+ var vpnProxyConfigCreateResponseSchema = z64.object({
7669
8002
  config: vpnProxyConfigSummarySchema
7670
8003
  });
7671
- var vpnProxyConfigUpdateRequestSchema = z63.object({
7672
- name: z63.string().trim().min(1).max(NAME_MAX).optional(),
7673
- server: z63.string().trim().min(1).max(URL_MAX).url().optional(),
7674
- username: z63.string().trim().min(1).max(USERNAME_MAX).optional(),
7675
- password: z63.string().min(PASSWORD_MIN).max(PASSWORD_MAX).optional(),
7676
- enabled: z63.boolean().optional()
8004
+ var vpnProxyConfigUpdateRequestSchema = z64.object({
8005
+ name: z64.string().trim().min(1).max(NAME_MAX).optional(),
8006
+ server: z64.string().trim().min(1).max(URL_MAX).url().optional(),
8007
+ username: z64.string().trim().min(1).max(USERNAME_MAX).optional(),
8008
+ password: z64.string().min(PASSWORD_MIN).max(PASSWORD_MAX).optional(),
8009
+ enabled: z64.boolean().optional()
7677
8010
  });
7678
- var vpnProxyConfigUpdateResponseSchema = z63.object({
8011
+ var vpnProxyConfigUpdateResponseSchema = z64.object({
7679
8012
  config: vpnProxyConfigSummarySchema
7680
8013
  });
7681
- var vpnProxyConfigDeleteResponseSchema = z63.object({
7682
- success: z63.literal(true)
8014
+ var vpnProxyConfigDeleteResponseSchema = z64.object({
8015
+ success: z64.literal(true)
7683
8016
  });
7684
- var vpnProxyConfigOrganizationSchema = z63.object({
7685
- id: z63.guid(),
7686
- organizationId: z63.guid(),
7687
- organizationName: z63.string(),
7688
- attachedAt: z63.string()
8017
+ var vpnProxyConfigOrganizationSchema = z64.object({
8018
+ id: z64.guid(),
8019
+ organizationId: z64.guid(),
8020
+ organizationName: z64.string(),
8021
+ attachedAt: z64.string()
7689
8022
  });
7690
- var vpnProxyConfigOrganizationListResponseSchema = z63.object({
7691
- organizations: z63.array(vpnProxyConfigOrganizationSchema)
8023
+ var vpnProxyConfigOrganizationListResponseSchema = z64.object({
8024
+ organizations: z64.array(vpnProxyConfigOrganizationSchema)
7692
8025
  });
7693
- var vpnProxyConfigAttachOrganizationRequestSchema = z63.object({
7694
- organizationId: z63.guid()
8026
+ var vpnProxyConfigAttachOrganizationRequestSchema = z64.object({
8027
+ organizationId: z64.guid()
7695
8028
  });
7696
- var vpnProxyConfigAttachOrganizationResponseSchema = z63.object({
8029
+ var vpnProxyConfigAttachOrganizationResponseSchema = z64.object({
7697
8030
  attachment: vpnProxyConfigOrganizationSchema
7698
8031
  });
7699
- var vpnProxyConfigDetachOrganizationResponseSchema = z63.object({
7700
- success: z63.literal(true)
8032
+ var vpnProxyConfigDetachOrganizationResponseSchema = z64.object({
8033
+ success: z64.literal(true)
7701
8034
  });
7702
- var vpnProxyConfigForOrganizationResponseSchema = z63.object({
8035
+ var vpnProxyConfigForOrganizationResponseSchema = z64.object({
7703
8036
  config: vpnProxyConfigSummarySchema.nullable()
7704
8037
  });
7705
8038
  function canonicalizeSopInput(config) {
@@ -7720,7 +8053,7 @@ function canonicalizeSopInput(config) {
7720
8053
  }
7721
8054
  __name(canonicalizeSopInput, "canonicalizeSopInput");
7722
8055
  __name2(canonicalizeSopInput, "canonicalizeSopInput");
7723
- var caseFilterStatusSchema = z64.enum([
8056
+ var caseFilterStatusSchema = z65.enum([
7724
8057
  "pending",
7725
8058
  "claimed",
7726
8059
  "completed",
@@ -7728,19 +8061,19 @@ var caseFilterStatusSchema = z64.enum([
7728
8061
  "needs_input",
7729
8062
  "postponed"
7730
8063
  ]);
7731
- var casesFiltersSchema = z64.object({
7732
- status: z64.array(caseFilterStatusSchema).optional(),
7733
- created_at_from: z64.string().optional(),
7734
- updated_at_from: z64.string().optional(),
7735
- labels: z64.record(z64.string(), z64.array(z64.string())).optional()
8064
+ var casesFiltersSchema = z65.object({
8065
+ status: z65.array(caseFilterStatusSchema).optional(),
8066
+ created_at_from: z65.string().optional(),
8067
+ updated_at_from: z65.string().optional(),
8068
+ labels: z65.record(z65.string(), z65.array(z65.string())).optional()
7736
8069
  });
7737
- var casesListRequestBodySchema = z64.object({
8070
+ var casesListRequestBodySchema = z65.object({
7738
8071
  filters: casesFiltersSchema.default({}),
7739
- limit: z64.int().min(1).max(100).default(25),
7740
- offset: z64.int().min(0).default(0),
7741
- sort_by: z64.enum(["created_at", "updated_at", "postponed_to"]).default("created_at"),
7742
- sort_order: z64.enum(["asc", "desc"]).default("desc"),
7743
- search: z64.string().optional()
8072
+ limit: z65.int().min(1).max(100).default(25),
8073
+ offset: z65.int().min(0).default(0),
8074
+ sort_by: z65.enum(["created_at", "updated_at", "postponed_to"]).default("created_at"),
8075
+ sort_order: z65.enum(["asc", "desc"]).default("desc"),
8076
+ search: z65.string().optional()
7744
8077
  });
7745
8078
  function toBase64(input) {
7746
8079
  if (typeof btoa === "function") {
@@ -7835,7 +8168,7 @@ function setFilterValuesByCategoryKey(filters, categoryKey, values) {
7835
8168
  const { status: _, ...rest } = filters;
7836
8169
  return rest;
7837
8170
  }
7838
- const parsed = z64.array(caseFilterStatusSchema).safeParse(values);
8171
+ const parsed = z65.array(caseFilterStatusSchema).safeParse(values);
7839
8172
  if (!parsed.success) {
7840
8173
  return filters;
7841
8174
  }
@@ -8975,11 +9308,11 @@ function emptyConfig() {
8975
9308
  __name(emptyConfig, "emptyConfig");
8976
9309
 
8977
9310
  // src/config/env.ts
8978
- import { z as z65 } from "zod";
8979
- var optionalEnvString = z65.string().optional().transform(
9311
+ import { z as z66 } from "zod";
9312
+ var optionalEnvString = z66.string().optional().transform(
8980
9313
  (value) => value === void 0 || value === "" ? void 0 : value
8981
9314
  );
8982
- var CliEnvSchema = z65.object({
9315
+ var CliEnvSchema = z66.object({
8983
9316
  DUVO_PROFILE: optionalEnvString,
8984
9317
  DUVO_API_KEY: optionalEnvString,
8985
9318
  DUVO_API_BASE_URL: optionalEnvString,
@@ -9475,9 +9808,9 @@ async function requireAuthenticatedConfig(command) {
9475
9808
  __name(requireAuthenticatedConfig, "requireAuthenticatedConfig");
9476
9809
 
9477
9810
  // src/commands/shared/team-context.ts
9478
- import { z as z66 } from "zod";
9479
- var teamSchema = z66.object({ id: z66.string() });
9480
- var listMyTeamsResponseSchema = z66.object({ teams: z66.array(teamSchema) });
9811
+ import { z as z67 } from "zod";
9812
+ var teamSchema = z67.object({ id: z67.string() });
9813
+ var listMyTeamsResponseSchema = z67.object({ teams: z67.array(teamSchema) });
9481
9814
  async function resolveRequiredTeamId(config, options = {}) {
9482
9815
  if (options.override) {
9483
9816
  return options.override;
@@ -10268,56 +10601,56 @@ import { readFile as readFile2 } from "node:fs/promises";
10268
10601
  import { confirm as confirm2, isCancel as isCancel2, text } from "@clack/prompts";
10269
10602
 
10270
10603
  // src/api/agent-schemas.ts
10271
- import { z as z68 } from "zod";
10604
+ import { z as z69 } from "zod";
10272
10605
 
10273
10606
  // src/api/json-value.ts
10274
- import { z as z67 } from "zod";
10275
- var jsonValueSchema = z67.lazy(
10276
- () => z67.union([
10277
- z67.string(),
10278
- z67.number(),
10279
- z67.boolean(),
10280
- z67.null(),
10281
- z67.array(jsonValueSchema),
10282
- z67.record(z67.string(), jsonValueSchema)
10607
+ import { z as z68 } from "zod";
10608
+ var jsonValueSchema = z68.lazy(
10609
+ () => z68.union([
10610
+ z68.string(),
10611
+ z68.number(),
10612
+ z68.boolean(),
10613
+ z68.null(),
10614
+ z68.array(jsonValueSchema),
10615
+ z68.record(z68.string(), jsonValueSchema)
10283
10616
  ])
10284
10617
  );
10285
10618
 
10286
10619
  // src/api/agent-schemas.ts
10287
- var publicAgentSchema = z68.object({
10288
- id: z68.string(),
10289
- name: z68.string(),
10290
- slack_enabled: z68.boolean().nullish(),
10291
- microsoft_teams_enabled: z68.boolean().nullish(),
10292
- agentic_memory_enabled: z68.boolean().nullish(),
10293
- thread_id: z68.string().nullish(),
10294
- created_at: z68.string().nullish(),
10295
- updated_at: z68.string().nullish(),
10296
- latest_build: z68.object({ config: jsonValueSchema.nullish() }).nullish()
10297
- });
10298
- var publicBuildSchema = z68.object({
10299
- id: z68.string(),
10300
- agent_id: z68.string(),
10301
- name: z68.string(),
10302
- revision_number: z68.number().nullish(),
10303
- created_at: z68.string().nullish(),
10304
- updated_at: z68.string().nullish()
10305
- });
10306
- var listAgentsResponseSchema = z68.object({
10307
- agents: z68.array(publicAgentSchema),
10308
- total: z68.number().nullish(),
10309
- limit: z68.number().nullish(),
10310
- offset: z68.number().nullish()
10311
- });
10312
- var getAgentResponseSchema = z68.object({
10620
+ var publicAgentSchema = z69.object({
10621
+ id: z69.string(),
10622
+ name: z69.string(),
10623
+ slack_enabled: z69.boolean().nullish(),
10624
+ microsoft_teams_enabled: z69.boolean().nullish(),
10625
+ agentic_memory_enabled: z69.boolean().nullish(),
10626
+ thread_id: z69.string().nullish(),
10627
+ created_at: z69.string().nullish(),
10628
+ updated_at: z69.string().nullish(),
10629
+ latest_build: z69.object({ config: jsonValueSchema.nullish() }).nullish()
10630
+ });
10631
+ var publicBuildSchema = z69.object({
10632
+ id: z69.string(),
10633
+ agent_id: z69.string(),
10634
+ name: z69.string(),
10635
+ revision_number: z69.number().nullish(),
10636
+ created_at: z69.string().nullish(),
10637
+ updated_at: z69.string().nullish()
10638
+ });
10639
+ var listAgentsResponseSchema = z69.object({
10640
+ agents: z69.array(publicAgentSchema),
10641
+ total: z69.number().nullish(),
10642
+ limit: z69.number().nullish(),
10643
+ offset: z69.number().nullish()
10644
+ });
10645
+ var getAgentResponseSchema = z69.object({
10313
10646
  agent: publicAgentSchema
10314
10647
  });
10315
- var createAgentResponseSchema = z68.object({
10648
+ var createAgentResponseSchema = z69.object({
10316
10649
  agent: publicAgentSchema,
10317
10650
  build: publicBuildSchema.optional()
10318
10651
  });
10319
- var deleteAgentResponseSchema = z68.object({
10320
- success: z68.literal(true)
10652
+ var deleteAgentResponseSchema = z69.object({
10653
+ success: z69.literal(true)
10321
10654
  });
10322
10655
  var buildConfigSchema = StoredAgentConfigSchemaV2;
10323
10656
  var DEFAULT_NEW_AGENT_NAME = DEFAULT_AGENT_NAME;
@@ -10625,30 +10958,162 @@ function registerAgentsDelete(agents) {
10625
10958
  }
10626
10959
  __name(registerAgentsDelete, "registerAgentsDelete");
10627
10960
 
10961
+ // src/commands/agents/eval-rubrics.ts
10962
+ var DESCRIPTION_PREVIEW_WIDTH = 60;
10963
+ var RUBRIC_COLUMNS = [
10964
+ { header: "SLUG", cell: /* @__PURE__ */ __name((row) => row.slug, "cell") },
10965
+ { header: "TITLE", cell: /* @__PURE__ */ __name((row) => row.title, "cell") },
10966
+ {
10967
+ header: "DESCRIPTION",
10968
+ cell: /* @__PURE__ */ __name((row) => row.description, "cell"),
10969
+ maxWidth: DESCRIPTION_PREVIEW_WIDTH
10970
+ }
10971
+ ];
10972
+ var PLATFORM_RUBRIC_COLUMNS = [
10973
+ { header: "KEY", cell: /* @__PURE__ */ __name((row) => row.key, "cell") },
10974
+ { header: "CAUSE", cell: /* @__PURE__ */ __name((row) => row.cause, "cell") },
10975
+ {
10976
+ header: "DESCRIPTION",
10977
+ cell: /* @__PURE__ */ __name((row) => row.description, "cell"),
10978
+ maxWidth: DESCRIPTION_PREVIEW_WIDTH
10979
+ }
10980
+ ];
10981
+ function registerAgentsEvalRubrics(agents) {
10982
+ agents.command("eval-rubrics <agent-id>").description("List an agent's active evaluation rubrics").option(
10983
+ "--build <build-id>",
10984
+ "rubrics for a specific revision (defaults to the agent's live build)"
10985
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function evalRubricsAction(agentId, options) {
10986
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
10987
+ const searchParams = new URLSearchParams();
10988
+ if (options.build) {
10989
+ searchParams.append("build_id", options.build);
10990
+ }
10991
+ const raw = await httpRequest({
10992
+ method: "GET",
10993
+ path: `/v2/agents/${encodeURIComponent(agentId)}/eval-rubrics`,
10994
+ apiKey,
10995
+ apiBaseUrl,
10996
+ searchParams
10997
+ });
10998
+ if (options.json) {
10999
+ printJson(raw);
11000
+ return;
11001
+ }
11002
+ const parsed = evalRubricsResponseSchema.safeParse(raw);
11003
+ if (!parsed.success) {
11004
+ throw new CliError(
11005
+ `Unexpected response from the API: ${parsed.error.message}`
11006
+ );
11007
+ }
11008
+ const { rubrics, platform_rubrics: platformRubrics } = parsed.data;
11009
+ if (platformRubrics.length > 0) {
11010
+ console.log("Platform rubrics:");
11011
+ console.log(renderTable(PLATFORM_RUBRIC_COLUMNS, platformRubrics));
11012
+ console.log("");
11013
+ }
11014
+ console.log("Assignment-specific rubrics:");
11015
+ if (rubrics.length === 0) {
11016
+ console.log("No assignment-specific rubrics defined for this agent.");
11017
+ return;
11018
+ }
11019
+ console.log(renderTable(RUBRIC_COLUMNS, rubrics));
11020
+ }, "evalRubricsAction"));
11021
+ }
11022
+ __name(registerAgentsEvalRubrics, "registerAgentsEvalRubrics");
11023
+
11024
+ // src/commands/agents/eval-scores.ts
11025
+ var SCOPES = ["all", "custom"];
11026
+ var DEFAULT_LOOKBACK_DAYS = 30;
11027
+ var FLAG_COLUMNS = [
11028
+ { header: "FLAG", cell: /* @__PURE__ */ __name((row) => row.flag, "cell") },
11029
+ { header: "LABEL", cell: /* @__PURE__ */ __name((row) => row.label ?? "", "cell") },
11030
+ { header: "COUNT", cell: /* @__PURE__ */ __name((row) => String(row.count), "cell") }
11031
+ ];
11032
+ function isScope(value) {
11033
+ return SCOPES.includes(value);
11034
+ }
11035
+ __name(isScope, "isScope");
11036
+ function defaultSince() {
11037
+ return new Date(
11038
+ Date.now() - DEFAULT_LOOKBACK_DAYS * 24 * 60 * 60 * 1e3
11039
+ ).toISOString();
11040
+ }
11041
+ __name(defaultSince, "defaultSince");
11042
+ function registerAgentsEvalScores(agents) {
11043
+ agents.command("eval-scores <agent-id>").description("Show aggregate evaluation scores for an agent's jobs").option(
11044
+ "--since <iso>",
11045
+ `only count jobs evaluated after this ISO timestamp (default: last ${DEFAULT_LOOKBACK_DAYS} days)`
11046
+ ).option(
11047
+ "--scope <scope>",
11048
+ "'all' (platform + custom rubrics) or 'custom' (live-build custom rubrics only)"
11049
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function evalScoresAction(agentId, options) {
11050
+ if (options.scope !== void 0 && !isScope(options.scope)) {
11051
+ throw new CliError(
11052
+ `Invalid --scope "${options.scope}". Expected one of: ${SCOPES.join(", ")}.`
11053
+ );
11054
+ }
11055
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
11056
+ const searchParams = new URLSearchParams();
11057
+ searchParams.append("since", options.since ?? defaultSince());
11058
+ if (options.scope) {
11059
+ searchParams.append("scope", options.scope);
11060
+ }
11061
+ const raw = await httpRequest({
11062
+ method: "GET",
11063
+ path: `/v2/agent/${encodeURIComponent(agentId)}/eval-scores`,
11064
+ apiKey,
11065
+ apiBaseUrl,
11066
+ searchParams
11067
+ });
11068
+ if (options.json) {
11069
+ printJson(raw);
11070
+ return;
11071
+ }
11072
+ const parsed = evalScoresResponseSchema.safeParse(raw);
11073
+ if (!parsed.success) {
11074
+ throw new CliError(
11075
+ `Unexpected response from the API: ${parsed.error.message}`
11076
+ );
11077
+ }
11078
+ const { total_evaluated, with_issues, flag_distribution } = parsed.data;
11079
+ console.log(
11080
+ renderKeyValue([
11081
+ { label: "Evaluated", value: String(total_evaluated) },
11082
+ { label: "With issues", value: String(with_issues) }
11083
+ ])
11084
+ );
11085
+ if (flag_distribution.length > 0) {
11086
+ console.log("");
11087
+ console.log(renderTable(FLAG_COLUMNS, flag_distribution));
11088
+ }
11089
+ }, "evalScoresAction"));
11090
+ }
11091
+ __name(registerAgentsEvalScores, "registerAgentsEvalScores");
11092
+
10628
11093
  // src/api/build-schemas.ts
10629
- import { z as z69 } from "zod";
10630
- var publicBuildSchema2 = z69.object({
10631
- id: z69.string(),
10632
- agent_id: z69.string(),
10633
- name: z69.string(),
10634
- status: z69.string().nullish(),
11094
+ import { z as z70 } from "zod";
11095
+ var publicBuildSchema2 = z70.object({
11096
+ id: z70.string(),
11097
+ agent_id: z70.string(),
11098
+ name: z70.string(),
11099
+ status: z70.string().nullish(),
10635
11100
  config: jsonValueSchema.nullish(),
10636
- revision_number: z69.number().nullish(),
10637
- created_at: z69.string().nullish(),
10638
- updated_at: z69.string().nullish()
11101
+ revision_number: z70.number().nullish(),
11102
+ created_at: z70.string().nullish(),
11103
+ updated_at: z70.string().nullish()
10639
11104
  });
10640
- var listBuildsResponseSchema2 = z69.object({
10641
- builds: z69.array(publicBuildSchema2),
10642
- total: z69.number().nullish(),
10643
- limit: z69.number().nullish(),
10644
- offset: z69.number().nullish()
11105
+ var listBuildsResponseSchema2 = z70.object({
11106
+ builds: z70.array(publicBuildSchema2),
11107
+ total: z70.number().nullish(),
11108
+ limit: z70.number().nullish(),
11109
+ offset: z70.number().nullish()
10645
11110
  });
10646
- var getBuildResponseSchema = z69.object({
11111
+ var getBuildResponseSchema = z70.object({
10647
11112
  build: publicBuildSchema2
10648
11113
  });
10649
- var createBuildResponseSchema = z69.object({
11114
+ var createBuildResponseSchema = z70.object({
10650
11115
  build: publicBuildSchema2,
10651
- agent: z69.object({ id: z69.string() })
11116
+ agent: z70.object({ id: z70.string() })
10652
11117
  });
10653
11118
 
10654
11119
  // src/commands/agents/get.ts
@@ -10898,35 +11363,35 @@ function registerAgentsModels(agents) {
10898
11363
  __name(registerAgentsModels, "registerAgentsModels");
10899
11364
 
10900
11365
  // src/api/schedule-schemas.ts
10901
- import { z as z70 } from "zod";
10902
- var publicScheduleSchema = z70.object({
10903
- id: z70.string(),
10904
- build_id: z70.string(),
10905
- agent_id: z70.string(),
10906
- user_id: z70.string(),
10907
- enabled: z70.boolean(),
10908
- frequency: z70.string(),
10909
- time: z70.string().nullish(),
10910
- timezone: z70.string(),
10911
- day: z70.string().nullish(),
10912
- day_of_month: z70.number().nullish(),
10913
- cron: z70.string().nullish(),
10914
- source: z70.string().nullish(),
10915
- task: z70.string().nullish(),
10916
- recurring: z70.boolean().nullish(),
10917
- created_at: z70.string(),
10918
- updated_at: z70.string()
10919
- });
10920
- var listSchedulesResponseSchema = z70.object({
10921
- schedules: z70.array(publicScheduleSchema)
10922
- });
10923
- var deleteScheduleResponseSchema = z70.object({
10924
- success: z70.literal(true)
10925
- });
10926
-
10927
- // src/commands/agents/schedules/render-schedule.ts
10928
- function renderScheduleDetails(schedule) {
10929
- return renderKeyValue([
11366
+ import { z as z71 } from "zod";
11367
+ var publicScheduleSchema = z71.object({
11368
+ id: z71.string(),
11369
+ build_id: z71.string(),
11370
+ agent_id: z71.string(),
11371
+ user_id: z71.string(),
11372
+ enabled: z71.boolean(),
11373
+ frequency: z71.string(),
11374
+ time: z71.string().nullish(),
11375
+ timezone: z71.string(),
11376
+ day: z71.string().nullish(),
11377
+ day_of_month: z71.number().nullish(),
11378
+ cron: z71.string().nullish(),
11379
+ source: z71.string().nullish(),
11380
+ task: z71.string().nullish(),
11381
+ recurring: z71.boolean().nullish(),
11382
+ created_at: z71.string(),
11383
+ updated_at: z71.string()
11384
+ });
11385
+ var listSchedulesResponseSchema = z71.object({
11386
+ schedules: z71.array(publicScheduleSchema)
11387
+ });
11388
+ var deleteScheduleResponseSchema = z71.object({
11389
+ success: z71.literal(true)
11390
+ });
11391
+
11392
+ // src/commands/agents/schedules/render-schedule.ts
11393
+ function renderScheduleDetails(schedule) {
11394
+ return renderKeyValue([
10930
11395
  { label: "ID", value: schedule.id },
10931
11396
  { label: "Agent", value: schedule.agent_id },
10932
11397
  { label: "Build", value: schedule.build_id },
@@ -11369,33 +11834,33 @@ function registerAgentsSetModel(agents) {
11369
11834
  __name(registerAgentsSetModel, "registerAgentsSetModel");
11370
11835
 
11371
11836
  // src/api/trigger-schemas.ts
11372
- import { z as z71 } from "zod";
11373
- var triggerSchema = z71.object({
11374
- id: z71.string(),
11375
- agent_id: z71.string(),
11376
- user_id: z71.string(),
11377
- integration_slug: z71.string(),
11378
- trigger_type: z71.string(),
11379
- filter_config: z71.record(z71.string(), z71.unknown()),
11380
- integration_instance_id: z71.string(),
11381
- enabled: z71.boolean(),
11382
- created_at: z71.string(),
11383
- updated_at: z71.string()
11837
+ import { z as z72 } from "zod";
11838
+ var triggerSchema = z72.object({
11839
+ id: z72.string(),
11840
+ agent_id: z72.string(),
11841
+ user_id: z72.string(),
11842
+ integration_slug: z72.string(),
11843
+ trigger_type: z72.string(),
11844
+ filter_config: z72.record(z72.string(), z72.unknown()),
11845
+ integration_instance_id: z72.string(),
11846
+ enabled: z72.boolean(),
11847
+ created_at: z72.string(),
11848
+ updated_at: z72.string()
11384
11849
  });
11385
- var listTriggersResponseSchema = z71.object({
11386
- triggers: z71.array(triggerSchema)
11850
+ var listTriggersResponseSchema = z72.object({
11851
+ triggers: z72.array(triggerSchema)
11387
11852
  });
11388
- var triggerTypeSchema = z71.object({
11389
- integration_slug: z71.string(),
11390
- integration_name: z71.string(),
11391
- icon_url: z71.string(),
11392
- trigger_type: z71.string(),
11393
- label: z71.string(),
11394
- description: z71.string(),
11395
- filter_schema: z71.record(z71.string(), z71.unknown())
11853
+ var triggerTypeSchema = z72.object({
11854
+ integration_slug: z72.string(),
11855
+ integration_name: z72.string(),
11856
+ icon_url: z72.string(),
11857
+ trigger_type: z72.string(),
11858
+ label: z72.string(),
11859
+ description: z72.string(),
11860
+ filter_schema: z72.record(z72.string(), z72.unknown())
11396
11861
  });
11397
- var listTriggerTypesResponseSchema = z71.object({
11398
- trigger_types: z71.array(triggerTypeSchema)
11862
+ var listTriggerTypesResponseSchema = z72.object({
11863
+ trigger_types: z72.array(triggerTypeSchema)
11399
11864
  });
11400
11865
 
11401
11866
  // src/commands/agents/triggers/list.ts
@@ -11525,7 +11990,7 @@ function registerAgentsTriggersSet(triggers) {
11525
11990
  __name(registerAgentsTriggersSet, "registerAgentsTriggersSet");
11526
11991
 
11527
11992
  // src/commands/agents/triggers/types.ts
11528
- var DESCRIPTION_PREVIEW_WIDTH = 50;
11993
+ var DESCRIPTION_PREVIEW_WIDTH2 = 50;
11529
11994
  var TABLE_COLUMNS9 = [
11530
11995
  { header: "INTEGRATION", cell: /* @__PURE__ */ __name((row) => row.integration_slug, "cell") },
11531
11996
  { header: "TRIGGER TYPE", cell: /* @__PURE__ */ __name((row) => row.trigger_type, "cell") },
@@ -11533,7 +11998,7 @@ var TABLE_COLUMNS9 = [
11533
11998
  {
11534
11999
  header: "DESCRIPTION",
11535
12000
  cell: /* @__PURE__ */ __name((row) => row.description, "cell"),
11536
- maxWidth: DESCRIPTION_PREVIEW_WIDTH
12001
+ maxWidth: DESCRIPTION_PREVIEW_WIDTH2
11537
12002
  }
11538
12003
  ];
11539
12004
  function registerAgentsTriggersTypes(triggers) {
@@ -11712,6 +12177,8 @@ function registerAgents(program) {
11712
12177
  registerAgentsModels(agents);
11713
12178
  registerAgentsSetModel(agents);
11714
12179
  registerAgentsDelete(agents);
12180
+ registerAgentsEvalScores(agents);
12181
+ registerAgentsEvalRubrics(agents);
11715
12182
  registerAgentsSchedules(agents);
11716
12183
  registerAgentsCaseTriggers(agents);
11717
12184
  registerAgentsTriggers(agents);
@@ -12017,55 +12484,55 @@ function fieldsToSearchParams(fields) {
12017
12484
  __name(fieldsToSearchParams, "fieldsToSearchParams");
12018
12485
 
12019
12486
  // src/api/integration-schemas.ts
12020
- import { z as z72 } from "zod";
12021
- var integrationSchema = z72.object({
12022
- id: z72.string(),
12023
- name: z72.string(),
12024
- type: z72.string(),
12025
- provider: z72.string(),
12026
- user_id: z72.string().nullable(),
12027
- team_id: z72.string(),
12028
- server_url: z72.string().optional(),
12029
- transport_type: z72.string().optional(),
12030
- auth_method: z72.string().nullish(),
12031
- composio_mcp_id: z72.string().nullish(),
12032
- custom_integration_id: z72.string().nullish(),
12033
- icon_url: z72.string().nullish(),
12034
- oauth_provider: z72.string().nullish(),
12035
- oauth_provider_key: z72.string().nullish(),
12036
- oauth_scopes: z72.array(z72.string()).nullish(),
12037
- integration_id: z72.string().nullish(),
12038
- created_at: z72.string(),
12039
- updated_at: z72.string()
12040
- });
12041
- var integrationsListResponseSchema2 = z72.object({
12042
- integrations: z72.array(integrationSchema)
12487
+ import { z as z73 } from "zod";
12488
+ var integrationSchema = z73.object({
12489
+ id: z73.string(),
12490
+ name: z73.string(),
12491
+ type: z73.string(),
12492
+ provider: z73.string(),
12493
+ user_id: z73.string().nullable(),
12494
+ team_id: z73.string(),
12495
+ server_url: z73.string().optional(),
12496
+ transport_type: z73.string().optional(),
12497
+ auth_method: z73.string().nullish(),
12498
+ composio_mcp_id: z73.string().nullish(),
12499
+ custom_integration_id: z73.string().nullish(),
12500
+ icon_url: z73.string().nullish(),
12501
+ oauth_provider: z73.string().nullish(),
12502
+ oauth_provider_key: z73.string().nullish(),
12503
+ oauth_scopes: z73.array(z73.string()).nullish(),
12504
+ integration_id: z73.string().nullish(),
12505
+ created_at: z73.string(),
12506
+ updated_at: z73.string()
12507
+ });
12508
+ var integrationsListResponseSchema2 = z73.object({
12509
+ integrations: z73.array(integrationSchema)
12043
12510
  });
12044
12511
  var connectionResponseSchema = integrationSchema;
12045
- var buildIntegrationConfigSchema2 = z72.object({
12046
- id: z72.string(),
12047
- integration_id: z72.string().nullable(),
12048
- custom_integration_id: z72.string().nullable(),
12049
- integration_type: z72.string(),
12050
- integration_name: z72.string(),
12051
- created_at: z72.string()
12512
+ var buildIntegrationConfigSchema2 = z73.object({
12513
+ id: z73.string(),
12514
+ integration_id: z73.string().nullable(),
12515
+ custom_integration_id: z73.string().nullable(),
12516
+ integration_type: z73.string(),
12517
+ integration_name: z73.string(),
12518
+ created_at: z73.string()
12052
12519
  });
12053
- var listBuildIntegrationsResponseSchema2 = z72.object({
12054
- integrations: z72.array(buildIntegrationConfigSchema2)
12520
+ var listBuildIntegrationsResponseSchema2 = z73.object({
12521
+ integrations: z73.array(buildIntegrationConfigSchema2)
12055
12522
  });
12056
- var attachBuildIntegrationsResponseSchema = z72.object({
12057
- success: z72.boolean(),
12058
- count: z72.number()
12523
+ var attachBuildIntegrationsResponseSchema = z73.object({
12524
+ success: z73.boolean(),
12525
+ count: z73.number()
12059
12526
  });
12060
- var buildIntegrationConnectionSchema = z72.object({
12061
- connection_id: z72.string(),
12062
- created_at: z72.string()
12527
+ var buildIntegrationConnectionSchema = z73.object({
12528
+ connection_id: z73.string(),
12529
+ created_at: z73.string()
12063
12530
  });
12064
- var listBuildIntegrationConnectionsResponseSchema = z72.object({
12065
- connections: z72.array(buildIntegrationConnectionSchema)
12531
+ var listBuildIntegrationConnectionsResponseSchema = z73.object({
12532
+ connections: z73.array(buildIntegrationConnectionSchema)
12066
12533
  });
12067
- var successResponseSchema = z72.object({
12068
- success: z72.boolean()
12534
+ var successResponseSchema = z73.object({
12535
+ success: z73.boolean()
12069
12536
  });
12070
12537
 
12071
12538
  // src/commands/build-integrations/attach.ts
@@ -12108,15 +12575,15 @@ function registerBuildIntegrationsAttach(buildIntegrations) {
12108
12575
  __name(registerBuildIntegrationsAttach, "registerBuildIntegrationsAttach");
12109
12576
 
12110
12577
  // src/commands/build-integrations/case-queue-setup.ts
12111
- import { z as z73 } from "zod";
12112
- var slotSchema = z73.object({
12113
- config_id: z73.string(),
12114
- integration_type: z73.string(),
12115
- linked_queue_count: z73.number()
12578
+ import { z as z74 } from "zod";
12579
+ var slotSchema = z74.object({
12580
+ config_id: z74.string(),
12581
+ integration_type: z74.string(),
12582
+ linked_queue_count: z74.number()
12116
12583
  });
12117
- var responseSchema2 = z73.object({
12118
- configs: z73.array(slotSchema),
12119
- has_available_queues: z73.boolean()
12584
+ var responseSchema2 = z74.object({
12585
+ configs: z74.array(slotSchema),
12586
+ has_available_queues: z74.boolean()
12120
12587
  });
12121
12588
  var TABLE_COLUMNS10 = [
12122
12589
  { header: "SLOT ID", cell: /* @__PURE__ */ __name((row) => row.config_id, "cell") },
@@ -12611,9 +13078,9 @@ function registerBuildsList(builds) {
12611
13078
  __name(registerBuildsList, "registerBuildsList");
12612
13079
 
12613
13080
  // src/commands/builds/promote.ts
12614
- import { z as z74 } from "zod";
12615
- var promoteResponseSchema = z74.object({
12616
- success: z74.boolean()
13081
+ import { z as z75 } from "zod";
13082
+ var promoteResponseSchema = z75.object({
13083
+ success: z75.boolean()
12617
13084
  });
12618
13085
  function registerBuildsPromote(builds) {
12619
13086
  builds.command("promote <id>").description(
@@ -12739,50 +13206,6 @@ function parseCaseIds(raw) {
12739
13206
  }
12740
13207
  __name(parseCaseIds, "parseCaseIds");
12741
13208
 
12742
- // src/commands/cases/bulk-delegate.ts
12743
- function registerCasesBulkDelegate(cases) {
12744
- cases.command("bulk-delegate").description(
12745
- "Delegate multiple cases to a chosen agent (1-100). Interrupts any active runs."
12746
- ).requiredOption("--queue <id>", "ID of the queue the cases belong to").requiredOption(
12747
- "--agent <id>",
12748
- "agent ID to delegate to (must be a queue consumer; list via `duvo queues agents <queue-id>`)"
12749
- ).requiredOption("--ids <list>", "comma-separated case IDs (1-100)").option("-y, --yes", "skip confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function bulkDelegateAction(options) {
12750
- const caseIds = parseCaseIds(options.ids);
12751
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
12752
- await confirmDestructive({
12753
- message: `Delegate ${caseIds.length} case(s) in queue "${options.queue}" to agent "${options.agent}"?`,
12754
- skip: Boolean(options.yes)
12755
- });
12756
- const raw = await httpRequest({
12757
- method: "POST",
12758
- path: `/v2/queues/${encodeURIComponent(options.queue)}/cases/bulk-delegate`,
12759
- apiKey,
12760
- apiBaseUrl,
12761
- body: { case_ids: caseIds, agent_id: options.agent }
12762
- });
12763
- if (options.json) {
12764
- printJson(raw);
12765
- return;
12766
- }
12767
- const parsed = caseBulkDelegateResponseSchema.safeParse(raw);
12768
- if (!parsed.success) {
12769
- throw new CliError(
12770
- `Unexpected response from the API: ${parsed.error.message}`
12771
- );
12772
- }
12773
- const result = parsed.data;
12774
- console.log(green("Bulk delegate complete."));
12775
- console.log();
12776
- console.log(
12777
- renderKeyValue([
12778
- { label: "Delegated", value: String(result.delegatedCount) },
12779
- { label: "Skipped", value: String(result.skippedCount) }
12780
- ])
12781
- );
12782
- }, "bulkDelegateAction"));
12783
- }
12784
- __name(registerCasesBulkDelegate, "registerCasesBulkDelegate");
12785
-
12786
13209
  // src/commands/cases/bulk-delete.ts
12787
13210
  function registerCasesBulkDelete(cases) {
12788
13211
  cases.command("bulk-delete").description(
@@ -12882,46 +13305,49 @@ async function fetchCaseTitles(ids, apiKey, apiBaseUrl) {
12882
13305
  }
12883
13306
  __name(fetchCaseTitles, "fetchCaseTitles");
12884
13307
 
12885
- // src/commands/cases/bulk-retry.ts
12886
- function registerCasesBulkRetry(cases) {
12887
- cases.command("bulk-retry").description(
12888
- "Retry multiple cases by resetting them to pending (1-100). Interrupts any active runs."
12889
- ).requiredOption("--queue <id>", "ID of the queue the cases belong to").requiredOption("--ids <list>", "comma-separated case IDs (1-100)").option("-y, --yes", "skip confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function bulkRetryAction(options) {
13308
+ // src/commands/cases/bulk-reprocess.ts
13309
+ function registerCasesBulkReprocess(cases) {
13310
+ cases.command("bulk-reprocess").description(
13311
+ "Re-process multiple cases on a chosen agent (1-100). Interrupts any active runs."
13312
+ ).requiredOption("--queue <id>", "ID of the queue the cases belong to").requiredOption(
13313
+ "--agent <id>",
13314
+ "agent ID to re-process on (must be a queue consumer; list via `duvo queues agents <queue-id>`)"
13315
+ ).requiredOption("--ids <list>", "comma-separated case IDs (1-100)").option("-y, --yes", "skip confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function bulkReprocessAction(options) {
12890
13316
  const caseIds = parseCaseIds(options.ids);
12891
13317
  const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
12892
13318
  await confirmDestructive({
12893
- message: `Retry ${caseIds.length} case(s) in queue "${options.queue}"?`,
13319
+ message: `Re-process ${caseIds.length} case(s) in queue "${options.queue}" on agent "${options.agent}"?`,
12894
13320
  skip: Boolean(options.yes)
12895
13321
  });
12896
13322
  const raw = await httpRequest({
12897
13323
  method: "POST",
12898
- path: `/v2/queues/${encodeURIComponent(options.queue)}/cases/bulk-retry`,
13324
+ path: `/v2/queues/${encodeURIComponent(options.queue)}/cases/bulk-reprocess`,
12899
13325
  apiKey,
12900
13326
  apiBaseUrl,
12901
- body: { case_ids: caseIds }
13327
+ body: { case_ids: caseIds, agent_id: options.agent }
12902
13328
  });
12903
13329
  if (options.json) {
12904
13330
  printJson(raw);
12905
13331
  return;
12906
13332
  }
12907
- const parsed = caseBulkRetryResponseSchema.safeParse(raw);
13333
+ const parsed = caseBulkReprocessResponseSchema.safeParse(raw);
12908
13334
  if (!parsed.success) {
12909
13335
  throw new CliError(
12910
13336
  `Unexpected response from the API: ${parsed.error.message}`
12911
13337
  );
12912
13338
  }
12913
13339
  const result = parsed.data;
12914
- console.log(green("Bulk retry complete."));
13340
+ console.log(green("Bulk reprocess complete."));
12915
13341
  console.log();
12916
13342
  console.log(
12917
13343
  renderKeyValue([
12918
- { label: "Retried", value: String(result.retriedCount) },
13344
+ { label: "Re-processed", value: String(result.reprocessedCount) },
12919
13345
  { label: "Skipped", value: String(result.skippedCount) }
12920
13346
  ])
12921
13347
  );
12922
- }, "bulkRetryAction"));
13348
+ }, "bulkReprocessAction"));
12923
13349
  }
12924
- __name(registerCasesBulkRetry, "registerCasesBulkRetry");
13350
+ __name(registerCasesBulkReprocess, "registerCasesBulkReprocess");
12925
13351
 
12926
13352
  // src/commands/cases/bulk-update-status.ts
12927
13353
  var CASE_TERMINAL_STATUSES = ["completed", "failed"];
@@ -13665,7 +14091,7 @@ function parseSortOrder(raw) {
13665
14091
  __name(parseSortOrder, "parseSortOrder");
13666
14092
 
13667
14093
  // src/commands/cases/runs.ts
13668
- import { z as z75 } from "zod";
14094
+ import { z as z76 } from "zod";
13669
14095
  var MIN_LIMIT4 = 1;
13670
14096
  var MAX_LIMIT4 = 10;
13671
14097
  var DEFAULT_LIMIT4 = 3;
@@ -13683,17 +14109,17 @@ var RUNS_TABLE_COLUMNS = [
13683
14109
  cell: /* @__PURE__ */ __name((row) => row.has_pending_human_request ? row.pending_human_request_title ?? "(unknown)" : "", "cell")
13684
14110
  }
13685
14111
  ];
13686
- var recentMessageSchema = z75.object({
13687
- id: z75.string(),
13688
- type: z75.string(),
13689
- role: z75.string(),
13690
- timestamp: z75.string(),
13691
- text_content: z75.string().nullish(),
13692
- tool_call: z75.object({ id: z75.string(), name: z75.string() }).passthrough().nullish(),
13693
- tool_result: z75.object({ tool_call_id: z75.string() }).passthrough().nullish()
13694
- });
13695
- var recentMessagesResponseSchema = z75.object({
13696
- messages: z75.array(recentMessageSchema)
14112
+ var recentMessageSchema = z76.object({
14113
+ id: z76.string(),
14114
+ type: z76.string(),
14115
+ role: z76.string(),
14116
+ timestamp: z76.string(),
14117
+ text_content: z76.string().nullish(),
14118
+ tool_call: z76.object({ id: z76.string(), name: z76.string() }).passthrough().nullish(),
14119
+ tool_result: z76.object({ tool_call_id: z76.string() }).passthrough().nullish()
14120
+ });
14121
+ var recentMessagesResponseSchema = z76.object({
14122
+ messages: z76.array(recentMessageSchema)
13697
14123
  });
13698
14124
  var TEXT_PREVIEW_WIDTH = 60;
13699
14125
  var MESSAGES_TABLE_COLUMNS = [
@@ -13814,123 +14240,611 @@ function registerCases(program) {
13814
14240
  registerCasesDelete(cases);
13815
14241
  registerCasesClear(cases);
13816
14242
  registerCasesBulkDelete(cases);
13817
- registerCasesBulkRetry(cases);
14243
+ registerCasesBulkReprocess(cases);
13818
14244
  registerCasesBulkUpdateStatus(cases);
13819
- registerCasesBulkDelegate(cases);
13820
14245
  registerCasesRuns(cases);
13821
14246
  registerCasesLabels(cases);
13822
14247
  }
13823
14248
  __name(registerCases, "registerCases");
13824
14249
 
13825
14250
  // src/commands/clarity/index.ts
13826
- import { z as z79 } from "zod";
14251
+ import { z as z84 } from "zod";
13827
14252
 
13828
- // src/commands/clarity/render.ts
13829
- var DEFAULT_HUMAN_SUMMARY_LIMIT = 1200;
13830
- var PROCESS_TABLE_COLUMNS = [
13831
- { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
13832
- { header: "VERSION", cell: /* @__PURE__ */ __name((row) => String(row.version), "cell") },
13833
- { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
14253
+ // src/api/clarity-schemas.ts
14254
+ import { z as z77 } from "zod";
14255
+ var clarityListProcessSchema = z77.object({
14256
+ id: z77.guid(),
14257
+ name: z77.string(),
14258
+ status: clarityProcessStatusSchema,
14259
+ visibility: clarityProcessVisibilitySchema,
14260
+ version: z77.number().int(),
14261
+ capture_count: z77.number().int(),
14262
+ capture_counts: z77.object({
14263
+ video: z77.number().int(),
14264
+ interview: z77.number().int(),
14265
+ document: z77.number().int()
14266
+ }).optional(),
14267
+ pending_invitation_count: z77.number().int(),
14268
+ contributors: z77.array(
14269
+ z77.object({
14270
+ user_id: z77.string(),
14271
+ user_name: z77.string()
14272
+ })
14273
+ ),
14274
+ created_at: z77.string(),
14275
+ created_by_name: z77.string().nullable()
14276
+ });
14277
+ var listClarityProcessesResponseSchema = z77.object({
14278
+ processes: z77.array(clarityListProcessSchema),
14279
+ total: z77.number().int(),
14280
+ limit: z77.number().int(),
14281
+ offset: z77.number().int()
14282
+ });
14283
+ var createClarityInviteLinkResponseSchema = z77.object({
14284
+ invite_link: z77.object({
14285
+ id: z77.guid(),
14286
+ url: z77.url(),
14287
+ created_at: z77.string(),
14288
+ created_by: z77.object({
14289
+ id: z77.guid(),
14290
+ email: z77.email().nullable()
14291
+ })
14292
+ })
14293
+ });
14294
+ var createArtifactImportUploadUrlResponseSchema = z77.object({
14295
+ signed_url: z77.url(),
14296
+ capture_id: z77.guid(),
14297
+ expires_at: z77.iso.datetime()
14298
+ });
14299
+ var completeArtifactImportResponseSchema = z77.object({
14300
+ capture: clarityCaptureSchema.extend({
14301
+ createdAt: z77.iso.datetime(),
14302
+ updatedAt: z77.iso.datetime()
14303
+ })
14304
+ });
14305
+ var legacyClarityProcessResponseSchema = legacyClarityProcessDetailSchema;
14306
+
14307
+ // src/commands/clarity/artifact-chat.ts
14308
+ var SNAPSHOT_KIND_CHOICES = claritySnapshotKindSchema.options;
14309
+ var CONVERSATION_COLUMNS = [
13834
14310
  {
13835
- header: "CAPTURES",
13836
- cell: /* @__PURE__ */ __name((row) => String(row.capture_count), "cell")
14311
+ header: "ID",
14312
+ cell: /* @__PURE__ */ __name((row) => row.id, "cell")
13837
14313
  },
13838
14314
  {
13839
- header: "NAME",
13840
- cell: /* @__PURE__ */ __name((row) => row.name, "cell"),
14315
+ header: "SNAPSHOT",
14316
+ cell: /* @__PURE__ */ __name((row) => row.snapshot_kind, "cell")
14317
+ },
14318
+ {
14319
+ header: "STATUS",
14320
+ cell: /* @__PURE__ */ __name((row) => row.status, "cell")
14321
+ },
14322
+ {
14323
+ header: "TITLE",
14324
+ cell: /* @__PURE__ */ __name((row) => row.title ?? "", "cell"),
13841
14325
  maxWidth: 48
14326
+ },
14327
+ {
14328
+ header: "UPDATED",
14329
+ cell: /* @__PURE__ */ __name((row) => row.updated_at, "cell")
13842
14330
  }
13843
14331
  ];
13844
- var CAPTURE_TABLE_COLUMNS = [
13845
- { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
13846
- { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
13847
- { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
14332
+ var MESSAGE_COLUMNS = [
13848
14333
  {
13849
- header: "USABLE",
13850
- cell: /* @__PURE__ */ __name((row) => describeCaptureUsability(row).usable ? "yes" : "no", "cell")
14334
+ header: "ID",
14335
+ cell: /* @__PURE__ */ __name((row) => row.id, "cell")
14336
+ },
14337
+ {
14338
+ header: "ROLE",
14339
+ cell: /* @__PURE__ */ __name((row) => row.role, "cell")
14340
+ },
14341
+ {
14342
+ header: "KIND",
14343
+ cell: /* @__PURE__ */ __name((row) => row.kind, "cell")
13851
14344
  },
13852
- { header: "USER", cell: /* @__PURE__ */ __name((row) => row.userName ?? row.userId, "cell") },
13853
14345
  {
13854
14346
  header: "CREATED",
13855
- cell: /* @__PURE__ */ __name((row) => formatIso(row.createdAt), "cell")
14347
+ cell: /* @__PURE__ */ __name((row) => row.created_at, "cell")
14348
+ },
14349
+ {
14350
+ header: "BODY",
14351
+ cell: /* @__PURE__ */ __name((row) => describeMessageBody(row.body), "cell"),
14352
+ maxWidth: 64
13856
14353
  }
13857
14354
  ];
13858
- function renderProcessTable(rows) {
13859
- return renderTable(PROCESS_TABLE_COLUMNS, rows);
14355
+ function registerClarityArtifactChatConversations(clarity) {
14356
+ clarity.command("artifact-chat-conversations <process-id>").description("List artifact-chat conversations for a v2 process").requiredOption(
14357
+ "--snapshot-kind <current_process|transformation_proposal>",
14358
+ "artifact kind to list conversations for",
14359
+ parseSnapshotKind
14360
+ ).option("--json", "output JSON").action(/* @__PURE__ */ __name(async function action(processId, options) {
14361
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14362
+ const searchParams = new URLSearchParams();
14363
+ searchParams.append("snapshot_kind", options.snapshotKind);
14364
+ const raw = await httpRequest({
14365
+ method: "GET",
14366
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/artifact-chat/conversations`,
14367
+ apiKey,
14368
+ apiBaseUrl,
14369
+ searchParams
14370
+ });
14371
+ const parsed = listArtifactChatConversationsResponseSchema.safeParse(raw);
14372
+ if (!parsed.success) {
14373
+ throw new CliError(
14374
+ `Unexpected response from the API: ${parsed.error.message}`
14375
+ );
14376
+ }
14377
+ const response = parsed.data;
14378
+ if (options.json) {
14379
+ printJson(response);
14380
+ return;
14381
+ }
14382
+ if (response.conversations.length === 0) {
14383
+ console.log("No artifact-chat conversations found.");
14384
+ return;
14385
+ }
14386
+ console.log(renderTable(CONVERSATION_COLUMNS, response.conversations));
14387
+ }, "action"));
13860
14388
  }
13861
- __name(renderProcessTable, "renderProcessTable");
13862
- function renderCapturesTable(rows) {
13863
- return renderTable(CAPTURE_TABLE_COLUMNS, rows);
14389
+ __name(registerClarityArtifactChatConversations, "registerClarityArtifactChatConversations");
14390
+ function registerClarityArtifactChatMessages(clarity) {
14391
+ clarity.command("artifact-chat-messages <process-id> <conversation-id>").description("Read messages for one artifact-chat conversation").option("--json", "output JSON").action(/* @__PURE__ */ __name(async function action(processId, conversationId, options) {
14392
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14393
+ const raw = await httpRequest({
14394
+ method: "GET",
14395
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/artifact-chat/conversations/${encodeURIComponent(conversationId)}/messages`,
14396
+ apiKey,
14397
+ apiBaseUrl
14398
+ });
14399
+ const parsed = getArtifactChatMessagesResponseSchema.safeParse(raw);
14400
+ if (!parsed.success) {
14401
+ throw new CliError(
14402
+ `Unexpected response from the API: ${parsed.error.message}`
14403
+ );
14404
+ }
14405
+ const response = parsed.data;
14406
+ if (options.json) {
14407
+ printJson(response);
14408
+ return;
14409
+ }
14410
+ const conversation = renderKeyValue([
14411
+ { label: "Conversation", value: response.conversation.id },
14412
+ { label: "Snapshot", value: response.conversation.snapshot_kind },
14413
+ { label: "Status", value: response.conversation.status },
14414
+ { label: "Title", value: response.conversation.title ?? "" }
14415
+ ]);
14416
+ if (response.messages.length === 0) {
14417
+ console.log(`${conversation}
14418
+
14419
+ No artifact-chat messages found.`);
14420
+ return;
14421
+ }
14422
+ console.log(
14423
+ `${conversation}
14424
+
14425
+ ${renderTable(MESSAGE_COLUMNS, response.messages)}`
14426
+ );
14427
+ }, "action"));
13864
14428
  }
13865
- __name(renderCapturesTable, "renderCapturesTable");
13866
- function renderVersionReport(process2) {
13867
- const current = process2.current_process_versions;
13868
- const proposals = process2.transformation_proposal_versions;
13869
- const defaultCurrent = selectDefaultVersion(current);
13870
- const defaultProposal = selectDefaultVersion(proposals);
13871
- const currentTable = current.length === 0 ? "No current-process versions found." : renderTable(
13872
- [
13873
- { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
13874
- { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
13875
- {
13876
- header: "DEFAULT",
13877
- cell: /* @__PURE__ */ __name((row) => row.id === defaultCurrent?.id ? "yes" : "", "cell")
13878
- },
13879
- {
13880
- header: "CREATED",
13881
- cell: /* @__PURE__ */ __name((row) => row.created_at, "cell")
13882
- },
13883
- {
13884
- header: "CREATOR",
13885
- cell: /* @__PURE__ */ __name((row) => row.creator_type ?? "", "cell")
13886
- }
13887
- ],
13888
- current
13889
- );
13890
- const proposalTable = proposals.length === 0 ? "No transformation-proposal versions found." : renderTable(
13891
- [
13892
- { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
13893
- { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
13894
- {
13895
- header: "DEFAULT",
13896
- cell: /* @__PURE__ */ __name((row) => row.id === defaultProposal?.id ? "yes" : "", "cell")
13897
- },
13898
- {
13899
- header: "ANCHOR",
13900
- cell: /* @__PURE__ */ __name((row) => row.clarity_current_process_id ?? "", "cell"),
13901
- maxWidth: 38
13902
- },
13903
- {
13904
- header: "CREATED",
13905
- cell: /* @__PURE__ */ __name((row) => row.created_at, "cell")
13906
- }
13907
- ],
13908
- proposals
13909
- );
13910
- return [
13911
- "Default versions",
13912
- renderKeyValue([
13913
- {
13914
- label: "Current",
13915
- value: defaultCurrent?.id ?? "none"
13916
- },
13917
- {
13918
- label: "Proposal",
13919
- value: defaultProposal === null ? "none" : `${defaultProposal.id} (anchor ${defaultProposal.clarity_current_process_id ?? "none"})`
13920
- }
13921
- ]),
13922
- "",
13923
- "Current process versions",
13924
- currentTable,
13925
- "",
13926
- "Transformation proposal versions",
13927
- proposalTable,
13928
- "",
13929
- "Use `duvo clarity compare <process-id> --current <id> --proposal <id>` to compare exact snapshots."
13930
- ].join("\n");
14429
+ __name(registerClarityArtifactChatMessages, "registerClarityArtifactChatMessages");
14430
+ function parseSnapshotKind(value) {
14431
+ const parsed = claritySnapshotKindSchema.safeParse(value);
14432
+ if (!parsed.success) {
14433
+ throw new CliError(
14434
+ `--snapshot-kind must be one of: ${SNAPSHOT_KIND_CHOICES.join(", ")}`
14435
+ );
14436
+ }
14437
+ return parsed.data;
13931
14438
  }
13932
- __name(renderVersionReport, "renderVersionReport");
13933
- function selectDefaultVersion(rows) {
14439
+ __name(parseSnapshotKind, "parseSnapshotKind");
14440
+ function describeMessageBody(body) {
14441
+ switch (body.kind) {
14442
+ case "text":
14443
+ case "error":
14444
+ case "info":
14445
+ return body.text;
14446
+ case "patch":
14447
+ return `${body.status}: ${body.summary}`;
14448
+ case "hitl_question":
14449
+ return `${body.questions.length} question(s)`;
14450
+ case "hitl_answer":
14451
+ return `${Object.keys(body.answers).length} answer(s)`;
14452
+ }
14453
+ }
14454
+ __name(describeMessageBody, "describeMessageBody");
14455
+
14456
+ // src/commands/clarity/artifact-import.ts
14457
+ import { readFile as readFile5 } from "node:fs/promises";
14458
+ import { basename, extname } from "node:path";
14459
+ var ARTIFACT_CONTENT_TYPES = [
14460
+ "image/svg+xml",
14461
+ "application/xml",
14462
+ "text/xml",
14463
+ "image/png",
14464
+ "image/jpeg"
14465
+ ];
14466
+ var ARTIFACT_UPLOAD_TIMEOUT_MS = 3e5;
14467
+ function registerClarityImportArtifact(clarity) {
14468
+ clarity.command("import-artifact <process-id> <file>").description(
14469
+ "Import a local Miro SVG, XML, PNG, or JPEG export into a Clarity process"
14470
+ ).option("--content-type <type>", "artifact content type").option(
14471
+ "--extra-capture-request-id <id>",
14472
+ "bind the import to an extra-capture request"
14473
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, filePath, options) {
14474
+ const fileName = basename(filePath);
14475
+ const contentType = resolveArtifactContentType(
14476
+ fileName,
14477
+ options.contentType
14478
+ );
14479
+ const config = await requireAuthenticatedConfig(this);
14480
+ const bytes = await readLocalArtifact(filePath);
14481
+ const upload = await createUploadUrl(config, processId, {
14482
+ fileName,
14483
+ contentType,
14484
+ extraCaptureRequestId: options.extraCaptureRequestId
14485
+ });
14486
+ await uploadToSignedUrl(upload.signed_url, bytes, contentType);
14487
+ const complete = await completeArtifactImport(
14488
+ config,
14489
+ processId,
14490
+ upload.capture_id,
14491
+ { fileName, contentType }
14492
+ );
14493
+ if (options.json) {
14494
+ printJson({ upload, complete });
14495
+ return;
14496
+ }
14497
+ renderCompletedImport(complete);
14498
+ }, "action"));
14499
+ }
14500
+ __name(registerClarityImportArtifact, "registerClarityImportArtifact");
14501
+ async function createUploadUrl(config, processId, input) {
14502
+ const body = {
14503
+ file_name: input.fileName,
14504
+ content_type: input.contentType
14505
+ };
14506
+ if (input.extraCaptureRequestId !== void 0) {
14507
+ body.extra_capture_request_id = input.extraCaptureRequestId;
14508
+ }
14509
+ const raw = await httpRequest({
14510
+ method: "POST",
14511
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/artifact-imports/create-upload-url`,
14512
+ apiKey: config.apiKey,
14513
+ apiBaseUrl: config.apiBaseUrl,
14514
+ body
14515
+ });
14516
+ const parsed = createArtifactImportUploadUrlResponseSchema.safeParse(raw);
14517
+ if (!parsed.success) {
14518
+ throw new CliError(
14519
+ `Unexpected response from the API: ${parsed.error.message}`
14520
+ );
14521
+ }
14522
+ return parsed.data;
14523
+ }
14524
+ __name(createUploadUrl, "createUploadUrl");
14525
+ async function completeArtifactImport(config, processId, captureId, input) {
14526
+ const raw = await httpRequest({
14527
+ method: "POST",
14528
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/artifact-imports/${encodeURIComponent(captureId)}/complete`,
14529
+ apiKey: config.apiKey,
14530
+ apiBaseUrl: config.apiBaseUrl,
14531
+ body: {
14532
+ file_name: input.fileName,
14533
+ content_type: input.contentType
14534
+ }
14535
+ });
14536
+ const parsed = completeArtifactImportResponseSchema.safeParse(raw);
14537
+ if (!parsed.success) {
14538
+ throw new CliError(
14539
+ `Unexpected response from the API: ${parsed.error.message}`
14540
+ );
14541
+ }
14542
+ return parsed.data;
14543
+ }
14544
+ __name(completeArtifactImport, "completeArtifactImport");
14545
+ async function readLocalArtifact(filePath) {
14546
+ try {
14547
+ return await readFile5(filePath);
14548
+ } catch (error) {
14549
+ const message = error instanceof Error ? error.message : String(error);
14550
+ throw new CliError(`Cannot read "${filePath}": ${message}`);
14551
+ }
14552
+ }
14553
+ __name(readLocalArtifact, "readLocalArtifact");
14554
+ async function uploadToSignedUrl(signedUrl, bytes, contentType) {
14555
+ let response;
14556
+ try {
14557
+ response = await fetch(signedUrl, {
14558
+ method: "PUT",
14559
+ headers: { "Content-Type": contentType },
14560
+ body: new Uint8Array(bytes),
14561
+ signal: AbortSignal.timeout(ARTIFACT_UPLOAD_TIMEOUT_MS)
14562
+ });
14563
+ } catch (error) {
14564
+ const message = error instanceof Error ? error.message : String(error);
14565
+ throw new CliError(`Artifact upload failed: ${message}`);
14566
+ }
14567
+ if (!response.ok) {
14568
+ const text3 = await response.text().catch(() => "");
14569
+ throw new CliError(
14570
+ `Artifact upload failed with HTTP ${response.status}${text3 ? `: ${text3}` : ""}`
14571
+ );
14572
+ }
14573
+ }
14574
+ __name(uploadToSignedUrl, "uploadToSignedUrl");
14575
+ function resolveArtifactContentType(fileName, contentType) {
14576
+ if (contentType !== void 0) {
14577
+ return parseArtifactContentType(contentType);
14578
+ }
14579
+ const extension = extname(fileName).toLowerCase();
14580
+ if (extension === ".svg") {
14581
+ return "image/svg+xml";
14582
+ }
14583
+ if (extension === ".xml") {
14584
+ return "application/xml";
14585
+ }
14586
+ if (extension === ".png") {
14587
+ return "image/png";
14588
+ }
14589
+ if (extension === ".jpg" || extension === ".jpeg") {
14590
+ return "image/jpeg";
14591
+ }
14592
+ throw new CliError(
14593
+ "Cannot infer content type. Supported extensions: .svg, .xml, .png, .jpg, .jpeg."
14594
+ );
14595
+ }
14596
+ __name(resolveArtifactContentType, "resolveArtifactContentType");
14597
+ function parseArtifactContentType(contentType) {
14598
+ if (ARTIFACT_CONTENT_TYPES.includes(contentType)) {
14599
+ return contentType;
14600
+ }
14601
+ throw new CliError(
14602
+ `Invalid content type "${contentType}". Expected one of: ${ARTIFACT_CONTENT_TYPES.join(", ")}.`
14603
+ );
14604
+ }
14605
+ __name(parseArtifactContentType, "parseArtifactContentType");
14606
+ function renderCompletedImport(response) {
14607
+ console.log(
14608
+ renderKeyValue([
14609
+ { label: "Capture ID", value: response.capture.id },
14610
+ { label: "Status", value: response.capture.status },
14611
+ { label: "Type", value: response.capture.type },
14612
+ { label: "Created", value: response.capture.createdAt },
14613
+ { label: "Updated", value: response.capture.updatedAt }
14614
+ ])
14615
+ );
14616
+ }
14617
+ __name(renderCompletedImport, "renderCompletedImport");
14618
+
14619
+ // src/commands/clarity/assign-extra-capture-request.ts
14620
+ import { z as z78 } from "zod";
14621
+ var responseSchema3 = z78.object({
14622
+ request: clarityProposalExtraCaptureRequestSchema
14623
+ });
14624
+ function renderRequest(request) {
14625
+ console.log(
14626
+ renderKeyValue([
14627
+ { label: "ID", value: request.id },
14628
+ { label: "Step ID", value: request.step_id },
14629
+ { label: "Status", value: request.status },
14630
+ { label: "Priority", value: request.priority },
14631
+ { label: "Assigned to", value: request.requested_user_id ?? "" },
14632
+ { label: "Gap", value: request.gap },
14633
+ { label: "Updated", value: request.updated_at }
14634
+ ])
14635
+ );
14636
+ }
14637
+ __name(renderRequest, "renderRequest");
14638
+ function registerClarityAssignExtraCaptureRequest(clarity) {
14639
+ clarity.command(
14640
+ "assign-extra-capture-request <process-id> <proposal-id> <request-id>"
14641
+ ).description(
14642
+ "Assign (or unassign) a team member to an extra-capture request"
14643
+ ).option("--user-id <id>", "team member to assign (omit to unassign)").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, proposalId, requestId, options) {
14644
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14645
+ const raw = await httpRequest({
14646
+ method: "PATCH",
14647
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposals/${encodeURIComponent(proposalId)}/extra-capture-requests/${encodeURIComponent(requestId)}/assign`,
14648
+ apiKey,
14649
+ apiBaseUrl,
14650
+ body: { user_id: options.userId ?? null }
14651
+ });
14652
+ if (options.json) {
14653
+ printJson(raw);
14654
+ return;
14655
+ }
14656
+ const parsed = responseSchema3.safeParse(raw);
14657
+ if (!parsed.success) {
14658
+ throw new CliError(
14659
+ `Unexpected response from the API: ${parsed.error.message}`
14660
+ );
14661
+ }
14662
+ renderRequest(parsed.data.request);
14663
+ }, "action"));
14664
+ }
14665
+ __name(registerClarityAssignExtraCaptureRequest, "registerClarityAssignExtraCaptureRequest");
14666
+
14667
+ // src/commands/clarity/build-automation.ts
14668
+ import { z as z79 } from "zod";
14669
+ var responseSchema4 = z79.object({
14670
+ automation_run: z79.object({
14671
+ id: z79.string(),
14672
+ status: z79.string()
14673
+ })
14674
+ });
14675
+ function registerClarityBuildAutomation(clarity) {
14676
+ clarity.command("build-automation <process-id>").description(
14677
+ "Hand the latest transformation proposal off to the workflow-builder pipeline (async)"
14678
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, options) {
14679
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14680
+ const raw = await httpRequest({
14681
+ method: "POST",
14682
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/automation`,
14683
+ apiKey,
14684
+ apiBaseUrl
14685
+ });
14686
+ if (options.json) {
14687
+ printJson(raw);
14688
+ return;
14689
+ }
14690
+ const parsed = responseSchema4.safeParse(raw);
14691
+ if (!parsed.success) {
14692
+ throw new CliError(
14693
+ `Unexpected response from the API: ${parsed.error.message}`
14694
+ );
14695
+ }
14696
+ const { automation_run: run } = parsed.data;
14697
+ console.log(
14698
+ renderKeyValue([
14699
+ { label: "Run ID", value: run.id },
14700
+ { label: "Status", value: run.status }
14701
+ ])
14702
+ );
14703
+ }, "action"));
14704
+ }
14705
+ __name(registerClarityBuildAutomation, "registerClarityBuildAutomation");
14706
+
14707
+ // src/commands/clarity/create-invite-link.ts
14708
+ function registerClarityCreateInviteLink(clarity) {
14709
+ clarity.command("create-invite-link <process-id>").description(
14710
+ "Create or regenerate a Clarity interview invite link for a process"
14711
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, options) {
14712
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14713
+ const raw = await httpRequest({
14714
+ method: "POST",
14715
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/invite-link`,
14716
+ apiKey,
14717
+ apiBaseUrl
14718
+ });
14719
+ const parsed = createClarityInviteLinkResponseSchema.safeParse(raw);
14720
+ if (!parsed.success) {
14721
+ throw new CliError(
14722
+ `Unexpected response from the API: ${parsed.error.message}`
14723
+ );
14724
+ }
14725
+ if (options.json) {
14726
+ printJson(raw);
14727
+ return;
14728
+ }
14729
+ const { invite_link: inviteLink } = parsed.data;
14730
+ console.log(
14731
+ renderKeyValue([
14732
+ { label: "ID", value: inviteLink.id },
14733
+ { label: "URL", value: inviteLink.url },
14734
+ { label: "Created", value: inviteLink.created_at },
14735
+ { label: "Created by", value: inviteLink.created_by.email ?? "" }
14736
+ ])
14737
+ );
14738
+ }, "action"));
14739
+ }
14740
+ __name(registerClarityCreateInviteLink, "registerClarityCreateInviteLink");
14741
+
14742
+ // src/commands/clarity/render.ts
14743
+ var DEFAULT_HUMAN_SUMMARY_LIMIT = 1200;
14744
+ var PROCESS_TABLE_COLUMNS = [
14745
+ { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
14746
+ { header: "VERSION", cell: /* @__PURE__ */ __name((row) => String(row.version), "cell") },
14747
+ { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
14748
+ {
14749
+ header: "CAPTURES",
14750
+ cell: /* @__PURE__ */ __name((row) => String(row.capture_count), "cell")
14751
+ },
14752
+ {
14753
+ header: "NAME",
14754
+ cell: /* @__PURE__ */ __name((row) => row.name, "cell"),
14755
+ maxWidth: 48
14756
+ }
14757
+ ];
14758
+ var CAPTURE_TABLE_COLUMNS = [
14759
+ { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
14760
+ { header: "TYPE", cell: /* @__PURE__ */ __name((row) => row.type, "cell") },
14761
+ { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
14762
+ {
14763
+ header: "USABLE",
14764
+ cell: /* @__PURE__ */ __name((row) => describeCaptureUsability(row).usable ? "yes" : "no", "cell")
14765
+ },
14766
+ { header: "USER", cell: /* @__PURE__ */ __name((row) => row.userName ?? row.userId, "cell") },
14767
+ {
14768
+ header: "CREATED",
14769
+ cell: /* @__PURE__ */ __name((row) => formatIso(row.createdAt), "cell")
14770
+ }
14771
+ ];
14772
+ function renderProcessTable(rows) {
14773
+ return renderTable(PROCESS_TABLE_COLUMNS, rows);
14774
+ }
14775
+ __name(renderProcessTable, "renderProcessTable");
14776
+ function renderCapturesTable(rows) {
14777
+ return renderTable(CAPTURE_TABLE_COLUMNS, rows);
14778
+ }
14779
+ __name(renderCapturesTable, "renderCapturesTable");
14780
+ function renderVersionReport(process2) {
14781
+ const current = process2.current_process_versions;
14782
+ const proposals = process2.transformation_proposal_versions;
14783
+ const defaultCurrent = selectDefaultVersion(current);
14784
+ const defaultProposal = selectDefaultVersion(proposals);
14785
+ const currentTable = current.length === 0 ? "No current-process versions found." : renderTable(
14786
+ [
14787
+ { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
14788
+ { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
14789
+ {
14790
+ header: "DEFAULT",
14791
+ cell: /* @__PURE__ */ __name((row) => row.id === defaultCurrent?.id ? "yes" : "", "cell")
14792
+ },
14793
+ {
14794
+ header: "CREATED",
14795
+ cell: /* @__PURE__ */ __name((row) => row.created_at, "cell")
14796
+ },
14797
+ {
14798
+ header: "CREATOR",
14799
+ cell: /* @__PURE__ */ __name((row) => row.creator_type ?? "", "cell")
14800
+ }
14801
+ ],
14802
+ current
14803
+ );
14804
+ const proposalTable = proposals.length === 0 ? "No transformation-proposal versions found." : renderTable(
14805
+ [
14806
+ { header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
14807
+ { header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
14808
+ {
14809
+ header: "DEFAULT",
14810
+ cell: /* @__PURE__ */ __name((row) => row.id === defaultProposal?.id ? "yes" : "", "cell")
14811
+ },
14812
+ {
14813
+ header: "ANCHOR",
14814
+ cell: /* @__PURE__ */ __name((row) => row.clarity_current_process_id ?? "", "cell"),
14815
+ maxWidth: 38
14816
+ },
14817
+ {
14818
+ header: "CREATED",
14819
+ cell: /* @__PURE__ */ __name((row) => row.created_at, "cell")
14820
+ }
14821
+ ],
14822
+ proposals
14823
+ );
14824
+ return [
14825
+ "Default versions",
14826
+ renderKeyValue([
14827
+ {
14828
+ label: "Current",
14829
+ value: defaultCurrent?.id ?? "none"
14830
+ },
14831
+ {
14832
+ label: "Proposal",
14833
+ value: defaultProposal === null ? "none" : `${defaultProposal.id} (anchor ${defaultProposal.clarity_current_process_id ?? "none"})`
14834
+ }
14835
+ ]),
14836
+ "",
14837
+ "Current process versions",
14838
+ currentTable,
14839
+ "",
14840
+ "Transformation proposal versions",
14841
+ proposalTable,
14842
+ "",
14843
+ "Use `duvo clarity compare <process-id> --current <id> --proposal <id>` to compare exact snapshots."
14844
+ ].join("\n");
14845
+ }
14846
+ __name(renderVersionReport, "renderVersionReport");
14847
+ function selectDefaultVersion(rows) {
13934
14848
  const live = rows.find((row) => row.status === "live");
13935
14849
  return live ?? rows[0] ?? null;
13936
14850
  }
@@ -14816,27 +15730,263 @@ function formatOptionalBoolean(value) {
14816
15730
  }
14817
15731
  __name(formatOptionalBoolean, "formatOptionalBoolean");
14818
15732
 
14819
- // src/commands/clarity/get-current-process.ts
14820
- import { z as z76 } from "zod";
14821
- var snapshotSchema = z76.object({
14822
- snapshot: z76.object({
14823
- id: z76.string(),
14824
- status: z76.string(),
14825
- creator_type: z76.string(),
14826
- user_id: z76.string().nullable(),
14827
- sandbox_id: z76.string().nullable(),
14828
- created_at: z76.string(),
14829
- updated_at: z76.string()
14830
- })
15733
+ // src/commands/clarity/generate-current-process.ts
15734
+ function registerClarityGenerateCurrentProcess(clarity) {
15735
+ clarity.command("generate-current-process <process-id>").description(
15736
+ "Trigger current-process generation for a Clarity v2 process (async)"
15737
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, options) {
15738
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
15739
+ const raw = await httpRequest({
15740
+ method: "POST",
15741
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/current-process`,
15742
+ apiKey,
15743
+ apiBaseUrl
15744
+ });
15745
+ if (options.json) {
15746
+ printJson(raw);
15747
+ return;
15748
+ }
15749
+ console.log("Generation started.");
15750
+ }, "action"));
15751
+ }
15752
+ __name(registerClarityGenerateCurrentProcess, "registerClarityGenerateCurrentProcess");
15753
+
15754
+ // src/commands/clarity/generate-transformation-proposal.ts
15755
+ function registerClarityGenerateTransformationProposal(clarity) {
15756
+ clarity.command("generate-transformation-proposal <process-id>").description(
15757
+ "Trigger transformation-proposal generation for a Clarity v2 process (async)"
15758
+ ).option(
15759
+ "--current-process-id <id>",
15760
+ "current-process snapshot to anchor generation to"
15761
+ ).option(
15762
+ "--regenerate-from <id>",
15763
+ "previous transformation proposal to regenerate from"
15764
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, options) {
15765
+ if (options.currentProcessId !== void 0 && options.regenerateFrom !== void 0) {
15766
+ throw new CliError(
15767
+ "Pass either --current-process-id or --regenerate-from, not both."
15768
+ );
15769
+ }
15770
+ const body = buildGenerateTransformationProposalBody(options);
15771
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
15772
+ const raw = await httpRequest({
15773
+ method: "POST",
15774
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposal`,
15775
+ apiKey,
15776
+ apiBaseUrl,
15777
+ body
15778
+ });
15779
+ if (options.json) {
15780
+ printJson(raw);
15781
+ return;
15782
+ }
15783
+ console.log("Generation started.");
15784
+ }, "action"));
15785
+ }
15786
+ __name(registerClarityGenerateTransformationProposal, "registerClarityGenerateTransformationProposal");
15787
+ function buildGenerateTransformationProposalBody(options) {
15788
+ if (options.regenerateFrom !== void 0) {
15789
+ return { regenerate_from: options.regenerateFrom };
15790
+ }
15791
+ if (options.currentProcessId !== void 0) {
15792
+ return { current_process_id: options.currentProcessId };
15793
+ }
15794
+ return void 0;
15795
+ }
15796
+ __name(buildGenerateTransformationProposalBody, "buildGenerateTransformationProposalBody");
15797
+
15798
+ // src/commands/clarity/get-current-process.ts
15799
+ import { z as z80 } from "zod";
15800
+
15801
+ // src/commands/clarity/read-api.ts
15802
+ var AUTH_ERROR_MARKER = "Unauthorized.";
15803
+ var NOT_FOUND_ERROR_PREFIX = "Not found:";
15804
+ var FETCH_FAILED_MARKER = "fetch failed";
15805
+ async function listClarityProcesses(config, teamId, params) {
15806
+ const searchParams = new URLSearchParams();
15807
+ searchParams.append("limit", String(params.limit));
15808
+ searchParams.append("offset", String(params.offset));
15809
+ if (params.search !== void 0) {
15810
+ searchParams.append("search", params.search);
15811
+ }
15812
+ if (params.status !== void 0) {
15813
+ searchParams.append("status", params.status);
15814
+ }
15815
+ if (params.version !== void 0) {
15816
+ searchParams.append("version", String(params.version));
15817
+ }
15818
+ const raw = await getClarityJson(config, {
15819
+ method: "GET",
15820
+ path: buildTeamPath(teamId, "/clarity-v2/processes"),
15821
+ searchParams,
15822
+ resource: "Clarity process list"
15823
+ });
15824
+ return parseResponse(listClarityProcessesResponseSchema, raw);
15825
+ }
15826
+ __name(listClarityProcesses, "listClarityProcesses");
15827
+ async function getClarityV2Process(config, processId) {
15828
+ const raw = await getClarityJson(config, {
15829
+ method: "GET",
15830
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}`,
15831
+ resource: "Clarity v2 process"
15832
+ });
15833
+ return parseResponse(clarityV2ProcessReadModelSchema, raw);
15834
+ }
15835
+ __name(getClarityV2Process, "getClarityV2Process");
15836
+ async function getLegacyClarityProcess(config, processId) {
15837
+ const raw = await getClarityJson(config, {
15838
+ method: "GET",
15839
+ path: `/v2/clarity/processes/${encodeURIComponent(processId)}`,
15840
+ resource: "legacy Clarity process"
15841
+ });
15842
+ return parseResponse(legacyClarityProcessResponseSchema, raw);
15843
+ }
15844
+ __name(getLegacyClarityProcess, "getLegacyClarityProcess");
15845
+ async function getCurrentProcessSnapshot(config, processId, snapshotId) {
15846
+ const raw = await getClarityJson(config, {
15847
+ method: "GET",
15848
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(
15849
+ processId
15850
+ )}/current-process/${encodeURIComponent(snapshotId)}`,
15851
+ resource: "Clarity current-process snapshot"
15852
+ });
15853
+ return parseResponse(
15854
+ clarityV2CurrentProcessSnapshotDetailResponseSchema,
15855
+ raw
15856
+ );
15857
+ }
15858
+ __name(getCurrentProcessSnapshot, "getCurrentProcessSnapshot");
15859
+ async function getTransformationProposalSnapshot(config, processId, snapshotId) {
15860
+ const raw = await getClarityJson(config, {
15861
+ method: "GET",
15862
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(
15863
+ processId
15864
+ )}/transformation-proposal/${encodeURIComponent(snapshotId)}`,
15865
+ resource: "Clarity transformation-proposal snapshot"
15866
+ });
15867
+ return parseResponse(
15868
+ clarityV2TransformationProposalSnapshotDetailResponseSchema,
15869
+ raw
15870
+ );
15871
+ }
15872
+ __name(getTransformationProposalSnapshot, "getTransformationProposalSnapshot");
15873
+ async function listExtraCaptureRequests(config, processId, proposalId, params = {}) {
15874
+ const searchParams = new URLSearchParams();
15875
+ searchParams.append("limit", String(params.limit ?? 100));
15876
+ searchParams.append("offset", String(params.offset ?? 0));
15877
+ const raw = await getClarityJson(config, {
15878
+ method: "GET",
15879
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(
15880
+ processId
15881
+ )}/transformation-proposals/${encodeURIComponent(
15882
+ proposalId
15883
+ )}/extra-capture-requests`,
15884
+ searchParams,
15885
+ resource: "Clarity extra-capture requests"
15886
+ });
15887
+ return parseResponse(
15888
+ clarityProposalExtraCaptureRequestListResponseSchema,
15889
+ raw
15890
+ );
15891
+ }
15892
+ __name(listExtraCaptureRequests, "listExtraCaptureRequests");
15893
+ function isLegacyV2ReadError(error) {
15894
+ return error instanceof CliHttpError && error.status === 403 && (error.apiErrorCode === "PROCESS_NOT_ON_V2" || error.apiErrorMessage === "Process is not on v2");
15895
+ }
15896
+ __name(isLegacyV2ReadError, "isLegacyV2ReadError");
15897
+ async function requireV2Process(config, processId) {
15898
+ try {
15899
+ return await getClarityV2Process(config, processId);
15900
+ } catch (error) {
15901
+ if (isLegacyV2ReadError(error)) {
15902
+ throw new CliError(
15903
+ "This command requires Clarity v2. Use `duvo clarity overview <process-id>` to read legacy v1 context."
15904
+ );
15905
+ }
15906
+ throw error;
15907
+ }
15908
+ }
15909
+ __name(requireV2Process, "requireV2Process");
15910
+ async function getClarityJson(config, options) {
15911
+ try {
15912
+ return await httpRequest({
15913
+ method: options.method,
15914
+ path: options.path,
15915
+ apiKey: config.apiKey,
15916
+ apiBaseUrl: config.apiBaseUrl,
15917
+ searchParams: options.searchParams
15918
+ });
15919
+ } catch (error) {
15920
+ throw toClarityCliError(error, {
15921
+ apiBaseUrl: config.apiBaseUrl,
15922
+ resource: options.resource
15923
+ });
15924
+ }
15925
+ }
15926
+ __name(getClarityJson, "getClarityJson");
15927
+ function toClarityCliError(error, context) {
15928
+ if (isLegacyV2ReadError(error)) {
15929
+ return error;
15930
+ }
15931
+ if (error instanceof CliHttpError && error.status === 403) {
15932
+ return new CliError(
15933
+ `${context.resource} is not accessible with the active profile. Check the process ID and active profile with \`duvo whoami\` or reauthenticate with \`duvo login\`.`,
15934
+ EXIT_CODE.FORBIDDEN
15935
+ );
15936
+ }
15937
+ if (error instanceof CliError) {
15938
+ if (error.message.includes(AUTH_ERROR_MARKER)) {
15939
+ return new CliError(
15940
+ "Authentication failed. Run `duvo login` to reauthenticate, or update your API key with `duvo login --api-key <key>`.",
15941
+ EXIT_CODE.AUTH
15942
+ );
15943
+ }
15944
+ if (error.message.startsWith(NOT_FOUND_ERROR_PREFIX)) {
15945
+ return new CliError(
15946
+ `${context.resource} was not found for the active profile. Check the process/snapshot ID and active profile; cross-team resources are not revealed.`,
15947
+ EXIT_CODE.NOT_FOUND
15948
+ );
15949
+ }
15950
+ return error;
15951
+ }
15952
+ if (error instanceof TypeError && error.message.includes(FETCH_FAILED_MARKER)) {
15953
+ return new CliError(
15954
+ `Could not reach the Duvo API at ${context.apiBaseUrl}. Check the API base URL and network connection.`
15955
+ );
15956
+ }
15957
+ return error;
15958
+ }
15959
+ __name(toClarityCliError, "toClarityCliError");
15960
+ function parseResponse(schema, raw) {
15961
+ const parsed = schema.safeParse(raw);
15962
+ if (!parsed.success) {
15963
+ throw new CliError(
15964
+ `Unexpected response from the API: ${parsed.error.message}`
15965
+ );
15966
+ }
15967
+ return parsed.data;
15968
+ }
15969
+ __name(parseResponse, "parseResponse");
15970
+
15971
+ // src/commands/clarity/get-current-process.ts
15972
+ var snapshotSchema = z80.object({
15973
+ snapshot: z80.object({
15974
+ id: z80.string(),
15975
+ status: z80.string(),
15976
+ creator_type: z80.string(),
15977
+ user_id: z80.string().nullable(),
15978
+ sandbox_id: z80.string().nullable(),
15979
+ created_at: z80.string(),
15980
+ updated_at: z80.string()
15981
+ })
14831
15982
  });
14832
15983
  function registerClarityGetCurrentProcess(clarity) {
14833
15984
  clarity.command("get-current-process <process-id> <snapshot-id>").description("Get a specific current-process snapshot by ID").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, snapshotId, options) {
14834
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14835
- const raw = await httpRequest({
15985
+ const config = await requireAuthenticatedConfig(this);
15986
+ const raw = await getClarityJson(config, {
14836
15987
  method: "GET",
14837
15988
  path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/current-process/${encodeURIComponent(snapshotId)}`,
14838
- apiKey,
14839
- apiBaseUrl
15989
+ resource: "Clarity current-process snapshot"
14840
15990
  });
14841
15991
  if (options.json) {
14842
15992
  printJson(raw);
@@ -14865,26 +16015,25 @@ function registerClarityGetCurrentProcess(clarity) {
14865
16015
  __name(registerClarityGetCurrentProcess, "registerClarityGetCurrentProcess");
14866
16016
 
14867
16017
  // src/commands/clarity/get-transformation-proposal.ts
14868
- import { z as z77 } from "zod";
14869
- var snapshotSchema2 = z77.object({
14870
- snapshot: z77.object({
14871
- id: z77.string(),
14872
- status: z77.string(),
14873
- creator_type: z77.string(),
14874
- user_id: z77.string().nullable(),
14875
- sandbox_id: z77.string().nullable(),
14876
- created_at: z77.string(),
14877
- updated_at: z77.string()
16018
+ import { z as z81 } from "zod";
16019
+ var snapshotSchema2 = z81.object({
16020
+ snapshot: z81.object({
16021
+ id: z81.string(),
16022
+ status: z81.string(),
16023
+ creator_type: z81.string(),
16024
+ user_id: z81.string().nullable(),
16025
+ sandbox_id: z81.string().nullable(),
16026
+ created_at: z81.string(),
16027
+ updated_at: z81.string()
14878
16028
  })
14879
16029
  });
14880
16030
  function registerClarityGetTransformationProposal(clarity) {
14881
16031
  clarity.command("get-transformation-proposal <process-id> <proposal-id>").description("Get a specific transformation-proposal snapshot by ID").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, proposalId, options) {
14882
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14883
- const raw = await httpRequest({
16032
+ const config = await requireAuthenticatedConfig(this);
16033
+ const raw = await getClarityJson(config, {
14884
16034
  method: "GET",
14885
16035
  path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposal/${encodeURIComponent(proposalId)}`,
14886
- apiKey,
14887
- apiBaseUrl
16036
+ resource: "Clarity transformation-proposal snapshot"
14888
16037
  });
14889
16038
  if (options.json) {
14890
16039
  printJson(raw);
@@ -14915,24 +16064,13 @@ __name(registerClarityGetTransformationProposal, "registerClarityGetTransformati
14915
16064
  // src/commands/clarity/get.ts
14916
16065
  function registerClarityGet(clarity) {
14917
16066
  clarity.command("get <process-id>").description("Get a Clarity process read model by ID").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function getAction(processId, options) {
14918
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
14919
- const raw = await httpRequest({
14920
- method: "GET",
14921
- path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}`,
14922
- apiKey,
14923
- apiBaseUrl
14924
- });
16067
+ const config = await requireAuthenticatedConfig(this);
16068
+ const result = await requireV2Process(config, processId);
14925
16069
  if (options.json) {
14926
- printJson(raw);
16070
+ printJson(result);
14927
16071
  return;
14928
16072
  }
14929
- const parsed = clarityV2ProcessReadModelSchema.safeParse(raw);
14930
- if (!parsed.success) {
14931
- throw new CliError(
14932
- `Unexpected response from the API: ${parsed.error.message}`
14933
- );
14934
- }
14935
- const { process: process2 } = parsed.data;
16073
+ const { process: process2 } = result;
14936
16074
  console.log(
14937
16075
  renderKeyValue([
14938
16076
  { label: "ID", value: process2.id },
@@ -14954,7 +16092,7 @@ function registerClarityGet(clarity) {
14954
16092
  const {
14955
16093
  current_process_versions: cpVersions,
14956
16094
  transformation_proposal_versions: tpVersions
14957
- } = parsed.data;
16095
+ } = result;
14958
16096
  if (cpVersions.length > 0) {
14959
16097
  console.log(`
14960
16098
  Current process versions (${cpVersions.length}):`);
@@ -15014,15 +16152,14 @@ function registerClarityListExtraCaptureRequests(clarity) {
15014
16152
  max: MAX_LIMIT5
15015
16153
  });
15016
16154
  const offset = parseOffset(options.offset);
15017
- const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16155
+ const config = await requireAuthenticatedConfig(this);
15018
16156
  const searchParams = new URLSearchParams();
15019
16157
  searchParams.append("limit", String(limit));
15020
16158
  searchParams.append("offset", String(offset));
15021
- const raw = await httpRequest({
16159
+ const raw = await getClarityJson(config, {
15022
16160
  method: "GET",
15023
16161
  path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposals/${encodeURIComponent(proposalId)}/extra-capture-requests`,
15024
- apiKey,
15025
- apiBaseUrl,
16162
+ resource: "Clarity extra-capture requests",
15026
16163
  searchParams
15027
16164
  });
15028
16165
  if (options.json) {
@@ -15048,193 +16185,180 @@ function registerClarityListExtraCaptureRequests(clarity) {
15048
16185
  }
15049
16186
  __name(registerClarityListExtraCaptureRequests, "registerClarityListExtraCaptureRequests");
15050
16187
 
15051
- // src/api/clarity-schemas.ts
15052
- import { z as z78 } from "zod";
15053
- var clarityListProcessSchema = z78.object({
15054
- id: z78.guid(),
15055
- name: z78.string(),
15056
- status: clarityProcessStatusSchema,
15057
- version: z78.number().int(),
15058
- capture_count: z78.number().int(),
15059
- capture_counts: z78.object({
15060
- video: z78.number().int(),
15061
- interview: z78.number().int(),
15062
- document: z78.number().int()
15063
- }).optional(),
15064
- pending_invitation_count: z78.number().int(),
15065
- contributors: z78.array(
15066
- z78.object({
15067
- user_id: z78.string(),
15068
- user_name: z78.string()
15069
- })
15070
- ),
15071
- created_at: z78.string(),
15072
- created_by_name: z78.string().nullable()
15073
- });
15074
- var listClarityProcessesResponseSchema = z78.object({
15075
- processes: z78.array(clarityListProcessSchema),
15076
- total: z78.number().int(),
15077
- limit: z78.number().int(),
15078
- offset: z78.number().int()
15079
- });
15080
- var legacyClarityProcessResponseSchema = legacyClarityProcessDetailSchema;
15081
-
15082
- // src/commands/clarity/read-api.ts
15083
- var AUTH_ERROR_MARKER = "Unauthorized.";
15084
- var NOT_FOUND_ERROR_PREFIX = "Not found:";
15085
- var FETCH_FAILED_MARKER = "fetch failed";
15086
- async function listClarityProcesses(config, teamId, params) {
15087
- const searchParams = new URLSearchParams();
15088
- searchParams.append("limit", String(params.limit));
15089
- searchParams.append("offset", String(params.offset));
15090
- if (params.search !== void 0) {
15091
- searchParams.append("search", params.search);
15092
- }
15093
- if (params.status !== void 0) {
15094
- searchParams.append("status", params.status);
15095
- }
15096
- if (params.version !== void 0) {
15097
- searchParams.append("version", String(params.version));
15098
- }
15099
- const raw = await getClarityJson(config, {
15100
- method: "GET",
15101
- path: buildTeamPath(teamId, "/clarity-v2/processes"),
15102
- searchParams,
15103
- resource: "Clarity process list"
15104
- });
15105
- return parseResponse(listClarityProcessesResponseSchema, raw);
15106
- }
15107
- __name(listClarityProcesses, "listClarityProcesses");
15108
- async function getClarityV2Process(config, processId) {
15109
- const raw = await getClarityJson(config, {
15110
- method: "GET",
15111
- path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}`,
15112
- resource: "Clarity v2 process"
15113
- });
15114
- return parseResponse(clarityV2ProcessReadModelSchema, raw);
15115
- }
15116
- __name(getClarityV2Process, "getClarityV2Process");
15117
- async function getLegacyClarityProcess(config, processId) {
15118
- const raw = await getClarityJson(config, {
15119
- method: "GET",
15120
- path: `/v2/clarity/processes/${encodeURIComponent(processId)}`,
15121
- resource: "legacy Clarity process"
15122
- });
15123
- return parseResponse(legacyClarityProcessResponseSchema, raw);
15124
- }
15125
- __name(getLegacyClarityProcess, "getLegacyClarityProcess");
15126
- async function getCurrentProcessSnapshot(config, processId, snapshotId) {
15127
- const raw = await getClarityJson(config, {
15128
- method: "GET",
15129
- path: `/v2/clarity-v2/processes/${encodeURIComponent(
15130
- processId
15131
- )}/current-process/${encodeURIComponent(snapshotId)}`,
15132
- resource: "Clarity current-process snapshot"
15133
- });
15134
- return parseResponse(
15135
- clarityV2CurrentProcessSnapshotDetailResponseSchema,
15136
- raw
15137
- );
15138
- }
15139
- __name(getCurrentProcessSnapshot, "getCurrentProcessSnapshot");
15140
- async function getTransformationProposalSnapshot(config, processId, snapshotId) {
15141
- const raw = await getClarityJson(config, {
15142
- method: "GET",
15143
- path: `/v2/clarity-v2/processes/${encodeURIComponent(
15144
- processId
15145
- )}/transformation-proposal/${encodeURIComponent(snapshotId)}`,
15146
- resource: "Clarity transformation-proposal snapshot"
15147
- });
15148
- return parseResponse(
15149
- clarityV2TransformationProposalSnapshotDetailResponseSchema,
15150
- raw
15151
- );
15152
- }
15153
- __name(getTransformationProposalSnapshot, "getTransformationProposalSnapshot");
15154
- async function listExtraCaptureRequests(config, processId, proposalId, params = {}) {
15155
- const searchParams = new URLSearchParams();
15156
- searchParams.append("limit", String(params.limit ?? 100));
15157
- searchParams.append("offset", String(params.offset ?? 0));
15158
- const raw = await getClarityJson(config, {
15159
- method: "GET",
15160
- path: `/v2/clarity-v2/processes/${encodeURIComponent(
15161
- processId
15162
- )}/transformation-proposals/${encodeURIComponent(
15163
- proposalId
15164
- )}/extra-capture-requests`,
15165
- searchParams,
15166
- resource: "Clarity extra-capture requests"
15167
- });
15168
- return parseResponse(
15169
- clarityProposalExtraCaptureRequestListResponseSchema,
15170
- raw
15171
- );
15172
- }
15173
- __name(listExtraCaptureRequests, "listExtraCaptureRequests");
15174
- function isLegacyV2ReadError(error) {
15175
- return error instanceof CliHttpError && error.status === 403 && (error.apiErrorCode === "PROCESS_NOT_ON_V2" || error.apiErrorMessage === "Process is not on v2");
15176
- }
15177
- __name(isLegacyV2ReadError, "isLegacyV2ReadError");
15178
- async function getClarityJson(config, options) {
15179
- try {
15180
- return await httpRequest({
15181
- method: options.method,
15182
- path: options.path,
15183
- apiKey: config.apiKey,
15184
- apiBaseUrl: config.apiBaseUrl,
15185
- searchParams: options.searchParams
15186
- });
15187
- } catch (error) {
15188
- throw toClarityCliError(error, {
15189
- apiBaseUrl: config.apiBaseUrl,
15190
- resource: options.resource
16188
+ // src/commands/clarity/postprocess.ts
16189
+ var SNAPSHOT_TYPES = ["current_process", "transformation_proposal"];
16190
+ function registerClarityPostprocess(clarity) {
16191
+ clarity.command("postprocess <process-id> <snapshot-type> <snapshot-id>").description(
16192
+ `Re-run postprocessing agents on an existing snapshot. snapshot-type must be one of: ${SNAPSHOT_TYPES.join(", ")}`
16193
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, snapshotType, snapshotId, options) {
16194
+ if (!SNAPSHOT_TYPES.includes(snapshotType)) {
16195
+ throw new CliError(
16196
+ `snapshot-type must be one of: ${SNAPSHOT_TYPES.join(", ")}`
16197
+ );
16198
+ }
16199
+ const type = snapshotType;
16200
+ const body = type === "current_process" ? { type, current_process_id: snapshotId } : { type, transformation_proposal_id: snapshotId };
16201
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16202
+ const raw = await httpRequest({
16203
+ method: "POST",
16204
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/postprocess`,
16205
+ apiKey,
16206
+ apiBaseUrl,
16207
+ body
15191
16208
  });
15192
- }
16209
+ if (options.json) {
16210
+ printJson(raw);
16211
+ return;
16212
+ }
16213
+ console.log("Postprocessing started.");
16214
+ }, "action"));
15193
16215
  }
15194
- __name(getClarityJson, "getClarityJson");
15195
- function toClarityCliError(error, context) {
15196
- if (isLegacyV2ReadError(error)) {
15197
- return error;
15198
- }
15199
- if (error instanceof CliHttpError && error.status === 403) {
15200
- return new CliError(
15201
- `${context.resource} is not accessible with the active profile. Check the process ID and active profile with \`duvo whoami\` or reauthenticate with \`duvo login\`.`,
15202
- EXIT_CODE.FORBIDDEN
15203
- );
15204
- }
15205
- if (error instanceof CliError) {
15206
- if (error.message.includes(AUTH_ERROR_MARKER)) {
15207
- return new CliError(
15208
- "Authentication failed. Run `duvo login` to reauthenticate, or update your API key with `duvo login --api-key <key>`.",
15209
- EXIT_CODE.AUTH
16216
+ __name(registerClarityPostprocess, "registerClarityPostprocess");
16217
+
16218
+ // src/commands/clarity/promote-current-process.ts
16219
+ import { z as z82 } from "zod";
16220
+ var snapshotSchema3 = z82.object({
16221
+ snapshot: z82.object({
16222
+ id: z82.string(),
16223
+ status: z82.string(),
16224
+ creator_type: z82.string(),
16225
+ created_at: z82.string(),
16226
+ updated_at: z82.string()
16227
+ })
16228
+ });
16229
+ function registerClarityPromoteCurrentProcess(clarity) {
16230
+ clarity.command("promote-current-process <process-id> <snapshot-id>").description("Promote a current-process snapshot to live").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, snapshotId, options) {
16231
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16232
+ const raw = await httpRequest({
16233
+ method: "POST",
16234
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/current-process/${encodeURIComponent(snapshotId)}/promote`,
16235
+ apiKey,
16236
+ apiBaseUrl
16237
+ });
16238
+ if (options.json) {
16239
+ printJson(raw);
16240
+ return;
16241
+ }
16242
+ const parsed = snapshotSchema3.safeParse(raw);
16243
+ if (!parsed.success) {
16244
+ throw new CliError(
16245
+ `Unexpected response from the API: ${parsed.error.message}`
15210
16246
  );
15211
16247
  }
15212
- if (error.message.startsWith(NOT_FOUND_ERROR_PREFIX)) {
15213
- return new CliError(
15214
- `${context.resource} was not found for the active profile. Check the process/snapshot ID and active profile; cross-team resources are not revealed.`,
15215
- EXIT_CODE.NOT_FOUND
16248
+ const { snapshot } = parsed.data;
16249
+ console.log(
16250
+ renderKeyValue([
16251
+ { label: "ID", value: snapshot.id },
16252
+ { label: "Status", value: snapshot.status },
16253
+ { label: "Creator type", value: snapshot.creator_type },
16254
+ { label: "Created", value: snapshot.created_at },
16255
+ { label: "Updated", value: snapshot.updated_at }
16256
+ ])
16257
+ );
16258
+ }, "action"));
16259
+ }
16260
+ __name(registerClarityPromoteCurrentProcess, "registerClarityPromoteCurrentProcess");
16261
+
16262
+ // src/commands/clarity/promote-transformation-proposal.ts
16263
+ import { z as z83 } from "zod";
16264
+ var snapshotSchema4 = z83.object({
16265
+ snapshot: z83.object({
16266
+ id: z83.string(),
16267
+ status: z83.string(),
16268
+ creator_type: z83.string(),
16269
+ created_at: z83.string(),
16270
+ updated_at: z83.string()
16271
+ })
16272
+ });
16273
+ function registerClarityPromoteTransformationProposal(clarity) {
16274
+ clarity.command("promote-transformation-proposal <process-id> <proposal-id>").description("Promote a transformation-proposal snapshot to live").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, proposalId, options) {
16275
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16276
+ const raw = await httpRequest({
16277
+ method: "POST",
16278
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposal/${encodeURIComponent(proposalId)}/promote`,
16279
+ apiKey,
16280
+ apiBaseUrl
16281
+ });
16282
+ if (options.json) {
16283
+ printJson(raw);
16284
+ return;
16285
+ }
16286
+ const parsed = snapshotSchema4.safeParse(raw);
16287
+ if (!parsed.success) {
16288
+ throw new CliError(
16289
+ `Unexpected response from the API: ${parsed.error.message}`
15216
16290
  );
15217
16291
  }
15218
- return error;
15219
- }
15220
- if (error instanceof TypeError && error.message.includes(FETCH_FAILED_MARKER)) {
15221
- return new CliError(
15222
- `Could not reach the Duvo API at ${context.apiBaseUrl}. Check the API base URL and network connection.`
16292
+ const { snapshot } = parsed.data;
16293
+ console.log(
16294
+ renderKeyValue([
16295
+ { label: "ID", value: snapshot.id },
16296
+ { label: "Status", value: snapshot.status },
16297
+ { label: "Creator type", value: snapshot.creator_type },
16298
+ { label: "Created", value: snapshot.created_at },
16299
+ { label: "Updated", value: snapshot.updated_at }
16300
+ ])
15223
16301
  );
15224
- }
15225
- return error;
16302
+ }, "action"));
15226
16303
  }
15227
- __name(toClarityCliError, "toClarityCliError");
15228
- function parseResponse(schema, raw) {
15229
- const parsed = schema.safeParse(raw);
15230
- if (!parsed.success) {
15231
- throw new CliError(
15232
- `Unexpected response from the API: ${parsed.error.message}`
15233
- );
15234
- }
15235
- return parsed.data;
16304
+ __name(registerClarityPromoteTransformationProposal, "registerClarityPromoteTransformationProposal");
16305
+
16306
+ // src/commands/clarity/revert-current-process.ts
16307
+ function registerClarityRevertCurrentProcess(clarity) {
16308
+ clarity.command("revert-current-process <process-id> <snapshot-id>").description("Delete (revert) a current-process snapshot").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, snapshotId, options) {
16309
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16310
+ const raw = await httpRequest({
16311
+ method: "DELETE",
16312
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/current-process/${encodeURIComponent(snapshotId)}`,
16313
+ apiKey,
16314
+ apiBaseUrl
16315
+ });
16316
+ if (options.json) {
16317
+ printJson(raw);
16318
+ return;
16319
+ }
16320
+ console.log("Snapshot reverted.");
16321
+ }, "action"));
15236
16322
  }
15237
- __name(parseResponse, "parseResponse");
16323
+ __name(registerClarityRevertCurrentProcess, "registerClarityRevertCurrentProcess");
16324
+
16325
+ // src/commands/clarity/revert-transformation-proposal.ts
16326
+ function registerClarityRevertTransformationProposal(clarity) {
16327
+ clarity.command("revert-transformation-proposal <process-id> <proposal-id>").description("Delete (revert) a transformation-proposal snapshot").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, proposalId, options) {
16328
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16329
+ const raw = await httpRequest({
16330
+ method: "DELETE",
16331
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposal/${encodeURIComponent(proposalId)}`,
16332
+ apiKey,
16333
+ apiBaseUrl
16334
+ });
16335
+ if (options.json) {
16336
+ printJson(raw);
16337
+ return;
16338
+ }
16339
+ console.log("Snapshot reverted.");
16340
+ }, "action"));
16341
+ }
16342
+ __name(registerClarityRevertTransformationProposal, "registerClarityRevertTransformationProposal");
16343
+
16344
+ // src/commands/clarity/stop-transformation-proposal.ts
16345
+ function registerClarityStopTransformationProposal(clarity) {
16346
+ clarity.command("stop-transformation-proposal <process-id>").description("Stop an in-flight transformation-proposal generation").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function action(processId, options) {
16347
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
16348
+ const raw = await httpRequest({
16349
+ method: "POST",
16350
+ path: `/v2/clarity-v2/processes/${encodeURIComponent(processId)}/transformation-proposal/stop`,
16351
+ apiKey,
16352
+ apiBaseUrl
16353
+ });
16354
+ if (options.json) {
16355
+ printJson(raw);
16356
+ return;
16357
+ }
16358
+ console.log("Generation stopped.");
16359
+ }, "action"));
16360
+ }
16361
+ __name(registerClarityStopTransformationProposal, "registerClarityStopTransformationProposal");
15238
16362
 
15239
16363
  // src/commands/clarity/index.ts
15240
16364
  var DEFAULT_LIMIT6 = 50;
@@ -15342,8 +16466,200 @@ var CLARITY_READ_TOOLS = [
15342
16466
  }
15343
16467
  ],
15344
16468
  description: "Read active extra-capture requests for a v2 transformation proposal."
16469
+ },
16470
+ {
16471
+ name: "listClarityArtifactChatConversations",
16472
+ scope: "v2",
16473
+ read_only: true,
16474
+ commands: ["duvo clarity artifact-chat-conversations"],
16475
+ endpoints: [
16476
+ {
16477
+ method: "GET",
16478
+ path: "/v2/clarity-v2/processes/:processId/artifact-chat/conversations"
16479
+ }
16480
+ ],
16481
+ description: "List recent artifact-chat conversations for a v2 process and snapshot kind."
16482
+ },
16483
+ {
16484
+ name: "getClarityArtifactChatMessages",
16485
+ scope: "v2",
16486
+ read_only: true,
16487
+ commands: ["duvo clarity artifact-chat-messages"],
16488
+ endpoints: [
16489
+ {
16490
+ method: "GET",
16491
+ path: "/v2/clarity-v2/processes/:processId/artifact-chat/conversations/:conversationId/messages"
16492
+ }
16493
+ ],
16494
+ description: "Read messages for one artifact-chat conversation in a v2 process."
16495
+ }
16496
+ ];
16497
+ var CLARITY_WRITE_TOOLS = [
16498
+ {
16499
+ name: "generateClarityCurrentProcess",
16500
+ scope: "v2",
16501
+ read_only: false,
16502
+ commands: ["duvo clarity generate-current-process"],
16503
+ endpoints: [
16504
+ {
16505
+ method: "POST",
16506
+ path: "/v2/clarity-v2/processes/:processId/current-process"
16507
+ }
16508
+ ],
16509
+ description: "Start asynchronous current-process generation."
16510
+ },
16511
+ {
16512
+ name: "generateClarityTransformationProposal",
16513
+ scope: "v2",
16514
+ read_only: false,
16515
+ commands: ["duvo clarity generate-transformation-proposal"],
16516
+ endpoints: [
16517
+ {
16518
+ method: "POST",
16519
+ path: "/v2/clarity-v2/processes/:processId/transformation-proposal"
16520
+ }
16521
+ ],
16522
+ description: "Start asynchronous transformation-proposal generation or regeneration."
16523
+ },
16524
+ {
16525
+ name: "promoteClarityCurrentProcess",
16526
+ scope: "v2",
16527
+ read_only: false,
16528
+ commands: ["duvo clarity promote-current-process"],
16529
+ endpoints: [
16530
+ {
16531
+ method: "POST",
16532
+ path: "/v2/clarity-v2/processes/:processId/current-process/:snapshotId/promote"
16533
+ }
16534
+ ],
16535
+ description: "Promote a current-process snapshot to live."
16536
+ },
16537
+ {
16538
+ name: "promoteClarityTransformationProposal",
16539
+ scope: "v2",
16540
+ read_only: false,
16541
+ commands: ["duvo clarity promote-transformation-proposal"],
16542
+ endpoints: [
16543
+ {
16544
+ method: "POST",
16545
+ path: "/v2/clarity-v2/processes/:processId/transformation-proposal/:proposalId/promote"
16546
+ }
16547
+ ],
16548
+ description: "Promote a transformation-proposal snapshot to live."
16549
+ },
16550
+ {
16551
+ name: "revertClarityCurrentProcess",
16552
+ scope: "v2",
16553
+ read_only: false,
16554
+ commands: ["duvo clarity revert-current-process"],
16555
+ endpoints: [
16556
+ {
16557
+ method: "DELETE",
16558
+ path: "/v2/clarity-v2/processes/:processId/current-process/:snapshotId"
16559
+ }
16560
+ ],
16561
+ description: "Delete a current-process snapshot."
16562
+ },
16563
+ {
16564
+ name: "revertClarityTransformationProposal",
16565
+ scope: "v2",
16566
+ read_only: false,
16567
+ commands: ["duvo clarity revert-transformation-proposal"],
16568
+ endpoints: [
16569
+ {
16570
+ method: "DELETE",
16571
+ path: "/v2/clarity-v2/processes/:processId/transformation-proposal/:proposalId"
16572
+ }
16573
+ ],
16574
+ description: "Delete a transformation-proposal snapshot."
16575
+ },
16576
+ {
16577
+ name: "assignClarityExtraCaptureRequest",
16578
+ scope: "v2",
16579
+ read_only: false,
16580
+ commands: ["duvo clarity assign-extra-capture-request"],
16581
+ endpoints: [
16582
+ {
16583
+ method: "PATCH",
16584
+ path: "/v2/clarity-v2/processes/:processId/transformation-proposals/:proposalId/extra-capture-requests/:requestId/assign"
16585
+ }
16586
+ ],
16587
+ description: "Assign or unassign an extra-capture request."
16588
+ },
16589
+ {
16590
+ name: "postprocessClaritySnapshot",
16591
+ scope: "v2",
16592
+ read_only: false,
16593
+ commands: ["duvo clarity postprocess"],
16594
+ endpoints: [
16595
+ {
16596
+ method: "POST",
16597
+ path: "/v2/clarity-v2/processes/:processId/postprocess"
16598
+ }
16599
+ ],
16600
+ description: "Re-run postprocessing for an existing snapshot."
16601
+ },
16602
+ {
16603
+ name: "buildClarityAutomation",
16604
+ scope: "v2",
16605
+ read_only: false,
16606
+ commands: ["duvo clarity build-automation"],
16607
+ endpoints: [
16608
+ {
16609
+ method: "POST",
16610
+ path: "/v2/clarity-v2/processes/:processId/automation"
16611
+ }
16612
+ ],
16613
+ description: "Start workflow-builder automation generation from the latest proposal."
16614
+ },
16615
+ {
16616
+ name: "stopClarityTransformationProposal",
16617
+ scope: "v2",
16618
+ read_only: false,
16619
+ commands: ["duvo clarity stop-transformation-proposal"],
16620
+ endpoints: [
16621
+ {
16622
+ method: "POST",
16623
+ path: "/v2/clarity-v2/processes/:processId/transformation-proposal/stop"
16624
+ }
16625
+ ],
16626
+ description: "Stop an in-flight transformation-proposal generation."
16627
+ },
16628
+ {
16629
+ name: "createClarityInviteLink",
16630
+ scope: "v2",
16631
+ read_only: false,
16632
+ commands: ["duvo clarity create-invite-link"],
16633
+ endpoints: [
16634
+ {
16635
+ method: "POST",
16636
+ path: "/v2/clarity-v2/processes/:processId/invite-link"
16637
+ }
16638
+ ],
16639
+ description: "Create or regenerate a public Clarity interview invite link."
16640
+ },
16641
+ {
16642
+ name: "importClarityArtifact",
16643
+ scope: "v2",
16644
+ read_only: false,
16645
+ commands: ["duvo clarity import-artifact"],
16646
+ endpoints: [
16647
+ {
16648
+ method: "POST",
16649
+ path: "/v2/clarity-v2/processes/:processId/artifact-imports/create-upload-url"
16650
+ },
16651
+ {
16652
+ method: "POST",
16653
+ path: "/v2/clarity-v2/processes/:processId/artifact-imports/:captureId/complete"
16654
+ }
16655
+ ],
16656
+ description: "Upload and complete a local Miro SVG, XML, PNG, or JPEG export."
15345
16657
  }
15346
16658
  ];
16659
+ var CLARITY_TOOLS = [
16660
+ ...CLARITY_READ_TOOLS,
16661
+ ...CLARITY_WRITE_TOOLS
16662
+ ];
15347
16663
  var CLARITY_TOOL_COLUMNS = [
15348
16664
  { header: "TOOL", cell: /* @__PURE__ */ __name((row) => row.name, "cell") },
15349
16665
  { header: "SCOPE", cell: /* @__PURE__ */ __name((row) => row.scope, "cell") },
@@ -15354,7 +16670,7 @@ var CLARITY_TOOL_COLUMNS = [
15354
16670
  },
15355
16671
  {
15356
16672
  header: "ENDPOINTS",
15357
- cell: /* @__PURE__ */ __name((row) => row.endpoints.map((endpoint) => endpoint.path).join(", "), "cell"),
16673
+ cell: /* @__PURE__ */ __name((row) => row.endpoints.map((endpoint) => `${endpoint.method} ${endpoint.path}`).join(", "), "cell"),
15358
16674
  maxWidth: 62
15359
16675
  }
15360
16676
  ];
@@ -15381,6 +16697,20 @@ function registerClarity(program) {
15381
16697
  registerClarityGetCurrentProcess(clarity);
15382
16698
  registerClarityGetTransformationProposal(clarity);
15383
16699
  registerClarityListExtraCaptureRequests(clarity);
16700
+ registerClarityArtifactChatConversations(clarity);
16701
+ registerClarityArtifactChatMessages(clarity);
16702
+ registerClarityGenerateCurrentProcess(clarity);
16703
+ registerClarityGenerateTransformationProposal(clarity);
16704
+ registerClarityPromoteCurrentProcess(clarity);
16705
+ registerClarityPromoteTransformationProposal(clarity);
16706
+ registerClarityRevertCurrentProcess(clarity);
16707
+ registerClarityRevertTransformationProposal(clarity);
16708
+ registerClarityAssignExtraCaptureRequest(clarity);
16709
+ registerClarityPostprocess(clarity);
16710
+ registerClarityBuildAutomation(clarity);
16711
+ registerClarityStopTransformationProposal(clarity);
16712
+ registerClarityCreateInviteLink(clarity);
16713
+ registerClarityImportArtifact(clarity);
15384
16714
  }
15385
16715
  __name(registerClarity, "registerClarity");
15386
16716
  function registerList(clarity) {
@@ -15739,7 +17069,7 @@ function registerExport(clarity) {
15739
17069
  __name(registerExport, "registerExport");
15740
17070
  function registerDoctor(clarity) {
15741
17071
  clarity.command("doctor [process-id]").description(
15742
- "Check auth, API reachability, read-only tools, and optionally one process context"
17072
+ "Check auth, API reachability, Clarity tools, and optionally one process context"
15743
17073
  ).option("--json", "output JSON").action(/* @__PURE__ */ __name(async function doctorAction(processId, options) {
15744
17074
  const environment = await buildEnvironmentDoctorChecks(this);
15745
17075
  const processChecks = processId === void 0 ? [] : await buildProcessDoctorChecks(environment.config, processId);
@@ -15757,15 +17087,15 @@ function registerDoctor(clarity) {
15757
17087
  }
15758
17088
  __name(registerDoctor, "registerDoctor");
15759
17089
  function registerTools(clarity) {
15760
- clarity.command("tools").description("List read-only Clarity tools used by the CLI").option("--json", "output JSON").action((options) => {
17090
+ clarity.command("tools").description("List Clarity tools used by the CLI").option("--json", "output JSON").action((options) => {
15761
17091
  if (options.json) {
15762
- printJson({ tools: CLARITY_READ_TOOLS });
17092
+ printJson({ tools: CLARITY_TOOLS });
15763
17093
  return;
15764
17094
  }
15765
- console.log(renderTable(CLARITY_TOOL_COLUMNS, CLARITY_READ_TOOLS));
17095
+ console.log(renderTable(CLARITY_TOOL_COLUMNS, CLARITY_TOOLS));
15766
17096
  console.log("");
15767
17097
  console.log(
15768
- "All listed Clarity tools are read-only GET calls. Generation, promotion, revert, assignment, postprocess, and automation-build commands are not exposed."
17098
+ "Clarity tools include read-only GET calls and explicit write commands for generation, promotion, revert, assignment, postprocess, automation, artifact import, and invite links."
15769
17099
  );
15770
17100
  });
15771
17101
  }
@@ -15887,17 +17217,6 @@ async function loadV2Overview(config, processId, options) {
15887
17217
  };
15888
17218
  }
15889
17219
  __name(loadV2Overview, "loadV2Overview");
15890
- async function requireV2Process(config, processId) {
15891
- try {
15892
- return await getClarityV2Process(config, processId);
15893
- } catch (error) {
15894
- if (isLegacyV2ReadError(error)) {
15895
- throw new CliError(CLARITY_V2_REQUIRED_MESSAGE);
15896
- }
15897
- throw error;
15898
- }
15899
- }
15900
- __name(requireV2Process, "requireV2Process");
15901
17220
  function buildWarnings(context) {
15902
17221
  const warnings = [];
15903
17222
  const processId = context.process.process.id;
@@ -15976,14 +17295,14 @@ __name(buildProposalAnchorCheck, "buildProposalAnchorCheck");
15976
17295
  async function buildEnvironmentDoctorChecks(command) {
15977
17296
  const checks = [
15978
17297
  {
15979
- name: "read_only_surface",
17298
+ name: "command_surface",
15980
17299
  ok: true,
15981
- detail: "The Clarity CLI registers read commands only; generation, promotion, revert, assignment, postprocess, and automation build routes are not exposed."
17300
+ detail: "The Clarity CLI registers read commands and explicit write commands for public Clarity v2 routes."
15982
17301
  },
15983
17302
  {
15984
- name: "read_tools_available",
17303
+ name: "tools_available",
15985
17304
  ok: true,
15986
- detail: `${CLARITY_READ_TOOLS.length} read-only Clarity tools available.`,
17305
+ detail: `${CLARITY_TOOLS.length} Clarity tools available.`,
15987
17306
  next_command: "duvo clarity tools"
15988
17307
  }
15989
17308
  ];
@@ -16086,8 +17405,8 @@ async function buildTeamContextCheck(config) {
16086
17405
  }
16087
17406
  }
16088
17407
  __name(buildTeamContextCheck, "buildTeamContextCheck");
16089
- var listMyTeamsResponseSchema2 = z79.object({
16090
- teams: z79.array(z79.object({ id: z79.string() }))
17408
+ var listMyTeamsResponseSchema2 = z84.object({
17409
+ teams: z84.array(z84.object({ id: z84.string() }))
16091
17410
  });
16092
17411
  async function buildClarityApiReachableCheck(command, config) {
16093
17412
  let teamId;
@@ -16835,16 +18154,16 @@ function registerConnectionsList(connections) {
16835
18154
  __name(registerConnectionsList, "registerConnectionsList");
16836
18155
 
16837
18156
  // src/commands/connections/probe.ts
16838
- import { z as z80 } from "zod";
16839
- var toolSchema = z80.object({
16840
- name: z80.string(),
16841
- description: z80.string().optional(),
16842
- input_schema: z80.record(z80.string(), z80.unknown()).optional()
18157
+ import { z as z85 } from "zod";
18158
+ var toolSchema = z85.object({
18159
+ name: z85.string(),
18160
+ description: z85.string().optional(),
18161
+ input_schema: z85.record(z85.string(), z85.unknown()).optional()
16843
18162
  });
16844
- var probeResponseSchema = z80.object({
16845
- success: z80.boolean(),
16846
- tools: z80.array(toolSchema).optional(),
16847
- error: z80.string().optional()
18163
+ var probeResponseSchema = z85.object({
18164
+ success: z85.boolean(),
18165
+ tools: z85.array(toolSchema).optional(),
18166
+ error: z85.string().optional()
16848
18167
  });
16849
18168
  var DESCRIPTION_MAX_WIDTH = 80;
16850
18169
  var TABLE_COLUMNS21 = [
@@ -17063,48 +18382,48 @@ function registerConnections(program) {
17063
18382
  __name(registerConnections, "registerConnections");
17064
18383
 
17065
18384
  // src/api/credential-schemas.ts
17066
- import { z as z81 } from "zod";
17067
- var dateLike = z81.string();
17068
- var secretSchema = z81.object({
17069
- id: z81.string(),
17070
- team_id: z81.string(),
17071
- user_id: z81.string().nullable(),
17072
- name: z81.string(),
17073
- service_slug: z81.string().nullable(),
17074
- env_var_keys: z81.array(z81.string()),
17075
- created_by: z81.string(),
18385
+ import { z as z86 } from "zod";
18386
+ var dateLike = z86.string();
18387
+ var secretSchema = z86.object({
18388
+ id: z86.string(),
18389
+ team_id: z86.string(),
18390
+ user_id: z86.string().nullable(),
18391
+ name: z86.string(),
18392
+ service_slug: z86.string().nullable(),
18393
+ env_var_keys: z86.array(z86.string()),
18394
+ created_by: z86.string(),
17076
18395
  created_at: dateLike,
17077
18396
  updated_at: dateLike
17078
18397
  });
17079
- var secretsListResponseSchema = z81.array(secretSchema);
18398
+ var secretsListResponseSchema = z86.array(secretSchema);
17080
18399
  var secretResponseSchema = secretSchema;
17081
- var browserLoginSchema = z81.object({
17082
- id: z81.string(),
17083
- user_id: z81.string().nullable(),
17084
- team_id: z81.string(),
17085
- domain: z81.string(),
17086
- username: z81.string().nullable(),
18400
+ var browserLoginSchema = z86.object({
18401
+ id: z86.string(),
18402
+ user_id: z86.string().nullable(),
18403
+ team_id: z86.string(),
18404
+ domain: z86.string(),
18405
+ username: z86.string().nullable(),
17087
18406
  password: encryptedDataSchema.nullable(),
17088
18407
  otp_secret: encryptedDataSchema.nullable(),
17089
18408
  created_at: dateLike,
17090
18409
  updated_at: dateLike
17091
18410
  });
17092
- var browserLoginsListResponseSchema = z81.array(credentialPreviewSchema);
17093
- var revisionLoginSummarySchema = z81.object({
17094
- id: z81.string(),
17095
- user_id: z81.string().nullable(),
17096
- team_id: z81.string().nullable(),
17097
- domain: z81.string(),
17098
- username: z81.string().nullable(),
18411
+ var browserLoginsListResponseSchema = z86.array(credentialPreviewSchema);
18412
+ var revisionLoginSummarySchema = z86.object({
18413
+ id: z86.string(),
18414
+ user_id: z86.string().nullable(),
18415
+ team_id: z86.string().nullable(),
18416
+ domain: z86.string(),
18417
+ username: z86.string().nullable(),
17099
18418
  created_at: dateLike,
17100
18419
  updated_at: dateLike
17101
18420
  });
17102
- var revisionLoginsListResponseSchema = z81.array(
18421
+ var revisionLoginsListResponseSchema = z86.array(
17103
18422
  revisionLoginSummarySchema
17104
18423
  );
17105
- var revisionSecretsListResponseSchema = z81.array(secretSchema);
17106
- var successResponseSchema2 = z81.object({
17107
- success: z81.boolean()
18424
+ var revisionSecretsListResponseSchema = z86.array(secretSchema);
18425
+ var successResponseSchema2 = z86.object({
18426
+ success: z86.boolean()
17108
18427
  });
17109
18428
  var attachSuccessResponseSchema = successResponseSchema2;
17110
18429
  var deleteSecretResponseSchema = successResponseSchema2;
@@ -20472,94 +21791,176 @@ function registerRevisionSecrets(program) {
20472
21791
  __name(registerRevisionSecrets, "registerRevisionSecrets");
20473
21792
 
20474
21793
  // src/api/run-schemas.ts
20475
- import { z as z82 } from "zod";
20476
- var publicRunSchema = z82.object({
20477
- id: z82.string(),
20478
- agent_id: z82.string(),
20479
- build_id: z82.string(),
20480
- status: z82.string(),
20481
- source: z82.string().nullish(),
20482
- sandbox_id: z82.string().nullish(),
20483
- started_at: z82.string().nullish(),
20484
- completed_at: z82.string().nullish(),
20485
- created_at: z82.string(),
20486
- updated_at: z82.string().nullish(),
20487
- human_in_the_loop_enabled: z82.boolean().nullish()
20488
- });
20489
- var startRunResponseSchema = z82.object({
21794
+ import { z as z87 } from "zod";
21795
+ var publicRunSchema = z87.object({
21796
+ id: z87.string(),
21797
+ agent_id: z87.string(),
21798
+ build_id: z87.string(),
21799
+ status: z87.string(),
21800
+ source: z87.string().nullish(),
21801
+ sandbox_id: z87.string().nullish(),
21802
+ started_at: z87.string().nullish(),
21803
+ completed_at: z87.string().nullish(),
21804
+ created_at: z87.string(),
21805
+ updated_at: z87.string().nullish(),
21806
+ human_in_the_loop_enabled: z87.boolean().nullish()
21807
+ });
21808
+ var startRunResponseSchema = z87.object({
20490
21809
  run: publicRunSchema
20491
21810
  });
20492
- var questionOptionSchema = z82.object({
20493
- label: z82.string(),
20494
- description: z82.string().nullish()
20495
- });
20496
- var questionSchema = z82.object({
20497
- question: z82.string(),
20498
- header: z82.string().nullish(),
20499
- options: z82.array(questionOptionSchema).nullish(),
20500
- multi_select: z82.boolean().nullish()
20501
- });
20502
- var pendingHumanRequestSchema = z82.object({
20503
- id: z82.string(),
20504
- title: z82.string(),
20505
- description: z82.string().nullish(),
20506
- created_at: z82.string(),
20507
- type: z82.string(),
20508
- questions: z82.array(questionSchema).nullish()
20509
- });
20510
- var getRunResponseSchema = z82.object({
21811
+ var questionOptionSchema = z87.object({
21812
+ label: z87.string(),
21813
+ description: z87.string().nullish()
21814
+ });
21815
+ var questionSchema = z87.object({
21816
+ question: z87.string(),
21817
+ header: z87.string().nullish(),
21818
+ options: z87.array(questionOptionSchema).nullish(),
21819
+ multi_select: z87.boolean().nullish()
21820
+ });
21821
+ var pendingHumanRequestSchema = z87.object({
21822
+ id: z87.string(),
21823
+ title: z87.string(),
21824
+ description: z87.string().nullish(),
21825
+ created_at: z87.string(),
21826
+ type: z87.string(),
21827
+ questions: z87.array(questionSchema).nullish()
21828
+ });
21829
+ var getRunResponseSchema = z87.object({
20511
21830
  run: publicRunSchema.nullable(),
20512
21831
  pending_human_request: pendingHumanRequestSchema.nullish()
20513
21832
  });
20514
- var stopRunResponseSchema = z82.object({
20515
- success: z82.boolean(),
20516
- message: z82.string().nullish()
20517
- });
20518
- var runMessageSchema = z82.object({
20519
- id: z82.string(),
20520
- type: z82.string(),
20521
- role: z82.string(),
20522
- timestamp: z82.string(),
20523
- text_content: z82.string().nullish(),
20524
- tool_call: z82.object({
20525
- id: z82.string(),
20526
- name: z82.string(),
20527
- arguments: z82.record(z82.string(), z82.unknown()).nullish()
21833
+ var stopRunResponseSchema = z87.object({
21834
+ success: z87.boolean(),
21835
+ message: z87.string().nullish()
21836
+ });
21837
+ var runMessageSchema = z87.object({
21838
+ id: z87.string(),
21839
+ type: z87.string(),
21840
+ role: z87.string(),
21841
+ timestamp: z87.string(),
21842
+ text_content: z87.string().nullish(),
21843
+ tool_call: z87.object({
21844
+ id: z87.string(),
21845
+ name: z87.string(),
21846
+ arguments: z87.record(z87.string(), z87.unknown()).nullish()
20528
21847
  }).nullish(),
20529
- tool_result: z82.object({
20530
- tool_call_id: z82.string(),
20531
- result: z82.unknown().nullish(),
20532
- error: z82.string().nullish()
21848
+ tool_result: z87.object({
21849
+ tool_call_id: z87.string(),
21850
+ result: z87.unknown().nullish(),
21851
+ error: z87.string().nullish()
20533
21852
  }).nullish()
20534
21853
  });
20535
- var listRunMessagesResponseSchema = z82.object({
20536
- messages: z82.array(runMessageSchema),
20537
- total: z82.number().nullish(),
20538
- limit: z82.number().nullish(),
20539
- offset: z82.number().nullish()
21854
+ var listRunMessagesResponseSchema = z87.object({
21855
+ messages: z87.array(runMessageSchema),
21856
+ total: z87.number().nullish(),
21857
+ limit: z87.number().nullish(),
21858
+ offset: z87.number().nullish()
20540
21859
  });
20541
- var postedMessageSchema = z82.object({
20542
- id: z82.string(),
20543
- type: z82.string(),
20544
- role: z82.string(),
20545
- timestamp: z82.string(),
20546
- text_content: z82.string()
21860
+ var postedMessageSchema = z87.object({
21861
+ id: z87.string(),
21862
+ type: z87.string(),
21863
+ role: z87.string(),
21864
+ timestamp: z87.string(),
21865
+ text_content: z87.string()
20547
21866
  });
20548
- var postRunMessageResponseSchema = z82.object({
21867
+ var postRunMessageResponseSchema = z87.object({
20549
21868
  message: postedMessageSchema
20550
21869
  });
20551
- var respondHumanRequestResponseSchema = z82.object({
20552
- human_request: z82.object({
20553
- id: z82.string(),
20554
- run_id: z82.string(),
20555
- title: z82.string(),
20556
- description: z82.string().nullish(),
20557
- response: z82.string().nullish(),
20558
- responded_at: z82.string().nullish(),
20559
- created_at: z82.string()
21870
+ var respondHumanRequestResponseSchema = z87.object({
21871
+ human_request: z87.object({
21872
+ id: z87.string(),
21873
+ run_id: z87.string(),
21874
+ title: z87.string(),
21875
+ description: z87.string().nullish(),
21876
+ response: z87.string().nullish(),
21877
+ responded_at: z87.string().nullish(),
21878
+ created_at: z87.string()
20560
21879
  })
20561
21880
  });
20562
21881
 
21882
+ // src/commands/runs/evaluation.ts
21883
+ async function resolveAgentId(runId, apiKey, apiBaseUrl) {
21884
+ const raw = await httpRequest({
21885
+ method: "GET",
21886
+ path: `/v2/runs/${encodeURIComponent(runId)}`,
21887
+ apiKey,
21888
+ apiBaseUrl
21889
+ });
21890
+ const parsed = getRunResponseSchema.safeParse(raw);
21891
+ if (!parsed.success) {
21892
+ throw new CliError(
21893
+ `Unexpected response from the API: ${parsed.error.message}`
21894
+ );
21895
+ }
21896
+ const { run } = parsed.data;
21897
+ if (!run) {
21898
+ throw new CliError(`Run "${runId}" not found.`);
21899
+ }
21900
+ return run.agent_id;
21901
+ }
21902
+ __name(resolveAgentId, "resolveAgentId");
21903
+ function registerRunsEvaluation(runs) {
21904
+ runs.command("evaluation <run-id>").alias("eval").description("Get the latest evaluation for an agent run").option(
21905
+ "--agent <agent-id>",
21906
+ "agent ID for the run (resolved from the run automatically when omitted)"
21907
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function evaluationAction(runId, options) {
21908
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
21909
+ const agentId = options.agent ?? await resolveAgentId(runId, apiKey, apiBaseUrl);
21910
+ const raw = await httpRequest({
21911
+ method: "GET",
21912
+ path: `/v2/agent/${encodeURIComponent(agentId)}/runs/${encodeURIComponent(runId)}/evaluation`,
21913
+ apiKey,
21914
+ apiBaseUrl
21915
+ });
21916
+ if (options.json) {
21917
+ printJson(raw);
21918
+ return;
21919
+ }
21920
+ const parsed = runEvaluationResponseSchema.safeParse(raw);
21921
+ if (!parsed.success) {
21922
+ throw new CliError(
21923
+ `Unexpected response from the API: ${parsed.error.message}`
21924
+ );
21925
+ }
21926
+ const evaluation = parsed.data.data;
21927
+ if (!evaluation) {
21928
+ console.log(`No evaluation available for run "${runId}".`);
21929
+ return;
21930
+ }
21931
+ console.log(
21932
+ renderKeyValue([
21933
+ { label: "ID", value: evaluation.id },
21934
+ { label: "Run", value: evaluation.run_id },
21935
+ { label: "Source", value: evaluation.source ?? "" },
21936
+ { label: "Created", value: evaluation.created_at }
21937
+ ])
21938
+ );
21939
+ const flags = Object.entries(evaluation.output.data).filter(
21940
+ ([key]) => key !== "final_comment"
21941
+ );
21942
+ if (flags.length > 0) {
21943
+ console.log("");
21944
+ console.log("Rubric:");
21945
+ console.log(
21946
+ renderKeyValue(
21947
+ flags.map(([key, value]) => ({
21948
+ label: key,
21949
+ value: value === null ? "" : String(value)
21950
+ }))
21951
+ )
21952
+ );
21953
+ }
21954
+ const finalComment = evaluation.output.data.final_comment;
21955
+ if (typeof finalComment === "string" && finalComment.length > 0) {
21956
+ console.log("");
21957
+ console.log("Final comment:");
21958
+ console.log(finalComment);
21959
+ }
21960
+ }, "evaluationAction"));
21961
+ }
21962
+ __name(registerRunsEvaluation, "registerRunsEvaluation");
21963
+
20563
21964
  // src/commands/runs/get.ts
20564
21965
  function registerRunsGet(runs) {
20565
21966
  runs.command("get <id>").description("Get an agent run by ID").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function getAction(id, options) {
@@ -21160,6 +22561,7 @@ function registerRuns(program) {
21160
22561
  registerRunsStart(runs);
21161
22562
  registerRunsList(runs);
21162
22563
  registerRunsGet(runs);
22564
+ registerRunsEvaluation(runs);
21163
22565
  registerRunsMessages(runs);
21164
22566
  registerRunsSendMessage(runs);
21165
22567
  registerRunsRespond(runs);
@@ -21168,28 +22570,28 @@ function registerRuns(program) {
21168
22570
  __name(registerRuns, "registerRuns");
21169
22571
 
21170
22572
  // src/api/sandbox-schemas.ts
21171
- import { z as z83 } from "zod";
21172
- var createSandboxResponseSchema = z83.object({
21173
- sandbox_id: z83.string(),
21174
- expires_at: z83.string()
22573
+ import { z as z88 } from "zod";
22574
+ var createSandboxResponseSchema = z88.object({
22575
+ sandbox_id: z88.string(),
22576
+ expires_at: z88.string()
21175
22577
  });
21176
- var createSandboxUploadUrlResponseSchema = z83.object({
21177
- upload_url: z83.string(),
21178
- path: z83.string(),
21179
- expires_in_seconds: z83.number()
22578
+ var createSandboxUploadUrlResponseSchema = z88.object({
22579
+ upload_url: z88.string(),
22580
+ path: z88.string(),
22581
+ expires_in_seconds: z88.number()
21180
22582
  });
21181
- var sandboxFileSchema = z83.object({
21182
- name: z83.string(),
21183
- path: z83.string(),
21184
- type: z83.enum(["file", "dir"]),
21185
- size_bytes: z83.number()
22583
+ var sandboxFileSchema = z88.object({
22584
+ name: z88.string(),
22585
+ path: z88.string(),
22586
+ type: z88.enum(["file", "dir"]),
22587
+ size_bytes: z88.number()
21186
22588
  });
21187
- var listSandboxFilesResponseSchema = z83.object({
21188
- files: z83.array(sandboxFileSchema)
22589
+ var listSandboxFilesResponseSchema = z88.object({
22590
+ files: z88.array(sandboxFileSchema)
21189
22591
  });
21190
- var uploadSandboxFileResponseSchema = z83.object({
21191
- path: z83.string(),
21192
- size_bytes: z83.number()
22592
+ var uploadSandboxFileResponseSchema = z88.object({
22593
+ path: z88.string(),
22594
+ size_bytes: z88.number()
21193
22595
  });
21194
22596
  var DEFAULT_SANDBOX_FILES_PATH = "/workspace";
21195
22597
 
@@ -21317,8 +22719,8 @@ function registerSandboxesPrepareUploadUrl(sandboxes) {
21317
22719
  __name(registerSandboxesPrepareUploadUrl, "registerSandboxesPrepareUploadUrl");
21318
22720
 
21319
22721
  // src/commands/sandboxes/upload.ts
21320
- import { readFile as readFile5, stat } from "node:fs/promises";
21321
- import { basename } from "node:path";
22722
+ import { readFile as readFile6, stat } from "node:fs/promises";
22723
+ import { basename as basename2 } from "node:path";
21322
22724
  var MAX_DIRECT_UPLOAD_BYTES = 10 * 1024 * 1024;
21323
22725
  function registerSandboxesUpload(sandboxes) {
21324
22726
  sandboxes.command("upload <sandbox_id> <file>").description(
@@ -21344,11 +22746,11 @@ function registerSandboxesUpload(sandboxes) {
21344
22746
  `File "${file}" is ${stats.size} bytes, larger than the ${MAX_DIRECT_UPLOAD_BYTES}-byte direct-upload limit. Use \`duvo sandboxes prepare-upload-url\` for larger files.`
21345
22747
  );
21346
22748
  }
21347
- const content = await readFile5(file).catch((error) => {
22749
+ const content = await readFile6(file).catch((error) => {
21348
22750
  const message = error instanceof Error ? error.message : String(error);
21349
22751
  throw new CliError(`Could not read file "${file}": ${message}`);
21350
22752
  });
21351
- const filename = basename(file);
22753
+ const filename = basename2(file);
21352
22754
  const formData = new FormData();
21353
22755
  formData.append("file", new Blob([new Uint8Array(content)]), filename);
21354
22756
  if (trimmedPath !== void 0) {
@@ -21800,13 +23202,13 @@ __name(registerSkillsAssignments, "registerSkillsAssignments");
21800
23202
 
21801
23203
  // src/commands/skills/create.ts
21802
23204
  import { readFileSync as readFileSync4 } from "node:fs";
21803
- import { z as z84 } from "zod";
21804
- var createSkillResponseSchema = z84.object({
21805
- skill: z84.object({
21806
- id: z84.string(),
21807
- name: z84.string(),
21808
- description: z84.string(),
21809
- team_id: z84.string()
23205
+ import { z as z89 } from "zod";
23206
+ var createSkillResponseSchema = z89.object({
23207
+ skill: z89.object({
23208
+ id: z89.string(),
23209
+ name: z89.string(),
23210
+ description: z89.string(),
23211
+ team_id: z89.string()
21810
23212
  })
21811
23213
  });
21812
23214
  function registerSkillsCreate(skills) {
@@ -22170,13 +23572,13 @@ function readExistingContent(source) {
22170
23572
  __name(readExistingContent, "readExistingContent");
22171
23573
 
22172
23574
  // src/commands/skills/install.ts
22173
- import { z as z85 } from "zod";
22174
- var installSkillResponseSchema = z85.object({
22175
- skill: z85.object({
22176
- id: z85.string(),
22177
- name: z85.string(),
22178
- description: z85.string(),
22179
- team_id: z85.string()
23575
+ import { z as z90 } from "zod";
23576
+ var installSkillResponseSchema = z90.object({
23577
+ skill: z90.object({
23578
+ id: z90.string(),
23579
+ name: z90.string(),
23580
+ description: z90.string(),
23581
+ team_id: z90.string()
22180
23582
  })
22181
23583
  });
22182
23584
  function registerSkillsInstall(skills) {
@@ -22364,15 +23766,15 @@ function registerSkillsSystem(skills) {
22364
23766
  __name(registerSkillsSystem, "registerSkillsSystem");
22365
23767
 
22366
23768
  // src/commands/skills/upload.ts
22367
- import { readFile as readFile6, stat as stat2 } from "node:fs/promises";
22368
- import { basename as basename2 } from "node:path";
22369
- import { z as z86 } from "zod";
22370
- var uploadSkillResponseSchema = z86.object({
22371
- skill: z86.object({
22372
- id: z86.string(),
22373
- name: z86.string(),
22374
- description: z86.string(),
22375
- team_id: z86.string()
23769
+ import { readFile as readFile7, stat as stat2 } from "node:fs/promises";
23770
+ import { basename as basename3 } from "node:path";
23771
+ import { z as z91 } from "zod";
23772
+ var uploadSkillResponseSchema = z91.object({
23773
+ skill: z91.object({
23774
+ id: z91.string(),
23775
+ name: z91.string(),
23776
+ description: z91.string(),
23777
+ team_id: z91.string()
22376
23778
  })
22377
23779
  });
22378
23780
  function registerSkillsUpload(skills) {
@@ -22386,11 +23788,11 @@ function registerSkillsUpload(skills) {
22386
23788
  if (!fileStats.isFile()) {
22387
23789
  throw new CliError(`Could not read file "${file}": not a regular file`);
22388
23790
  }
22389
- const content = await readFile6(file).catch((error) => {
23791
+ const content = await readFile7(file).catch((error) => {
22390
23792
  const message = error instanceof Error ? error.message : String(error);
22391
23793
  throw new CliError(`Could not read file "${file}": ${message}`);
22392
23794
  });
22393
- const filename = basename2(file);
23795
+ const filename = basename3(file);
22394
23796
  const formData = new FormData();
22395
23797
  formData.append("file", new Blob([new Uint8Array(content)]), filename);
22396
23798
  const config = await requireAuthenticatedConfig(this);
@@ -22587,11 +23989,11 @@ function registerTeamMembers(team) {
22587
23989
  __name(registerTeamMembers, "registerTeamMembers");
22588
23990
 
22589
23991
  // src/commands/team/use.ts
22590
- import { z as z87 } from "zod";
23992
+ import { z as z92 } from "zod";
22591
23993
  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;
22592
- var teamIdSchema = z87.string().regex(TEAM_ID_SHAPE);
22593
- var listMyTeamsResponseSchema3 = z87.object({
22594
- teams: z87.array(z87.object({ id: z87.string() }))
23994
+ var teamIdSchema = z92.string().regex(TEAM_ID_SHAPE);
23995
+ var listMyTeamsResponseSchema3 = z92.object({
23996
+ teams: z92.array(z92.object({ id: z92.string() }))
22595
23997
  });
22596
23998
  function registerTeamUse(team) {
22597
23999
  team.command("use <team-id>").description(
@@ -22673,14 +24075,14 @@ function registerTeam(program) {
22673
24075
  __name(registerTeam, "registerTeam");
22674
24076
 
22675
24077
  // src/commands/teams/list.ts
22676
- import { z as z88 } from "zod";
22677
- var teamApiSchema2 = z88.object({
22678
- id: z88.string(),
22679
- name: z88.string(),
22680
- organization_id: z88.string().nullable()
24078
+ import { z as z93 } from "zod";
24079
+ var teamApiSchema2 = z93.object({
24080
+ id: z93.string(),
24081
+ name: z93.string(),
24082
+ organization_id: z93.string().nullable()
22681
24083
  });
22682
- var listMyTeamsResponseSchema4 = z88.object({
22683
- teams: z88.array(teamApiSchema2)
24084
+ var listMyTeamsResponseSchema4 = z93.object({
24085
+ teams: z93.array(teamApiSchema2)
22684
24086
  });
22685
24087
  function registerTeamsList(program) {
22686
24088
  const teams = program.command("teams").description("Inspect the teams your credentials can act on");
@@ -22776,7 +24178,7 @@ __name(resolveActiveTeamId, "resolveActiveTeamId");
22776
24178
  var version = resolveVersion();
22777
24179
  function resolveVersion() {
22778
24180
  if (true) {
22779
- return "1.3.0";
24181
+ return "1.5.0";
22780
24182
  }
22781
24183
  const packageJsonPath = join2(
22782
24184
  dirname2(fileURLToPath(import.meta.url)),
@@ -22845,7 +24247,7 @@ function checkForUpdate() {
22845
24247
  __name(checkForUpdate, "checkForUpdate");
22846
24248
  function loadPackageMeta() {
22847
24249
  if (true) {
22848
- return { name: "@duvoai/cli", version: "1.3.0" };
24250
+ return { name: "@duvoai/cli", version: "1.5.0" };
22849
24251
  }
22850
24252
  const require2 = createRequire(import.meta.url);
22851
24253
  const raw = require2("../package.json");