@duvoai/cli 1.77.1 → 1.78.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 +234 -24
- package/package.json +1 -1
package/dist/bin/duvo.js
CHANGED
|
@@ -1469,6 +1469,7 @@ var updateTeamClaritySettingsSchema = z7.object({
|
|
|
1469
1469
|
industry: z7.string().trim().max(255).nullable().optional(),
|
|
1470
1470
|
annualRevenue: z7.number().nonnegative().nullable().optional()
|
|
1471
1471
|
});
|
|
1472
|
+
var MAX_CLARITY_PROCESSING_FAILURE_REASON_LENGTH = 500;
|
|
1472
1473
|
var clarityCaptureSchema = z7.object({
|
|
1473
1474
|
id: z7.guid(),
|
|
1474
1475
|
processId: z7.guid(),
|
|
@@ -1479,6 +1480,7 @@ var clarityCaptureSchema = z7.object({
|
|
|
1479
1480
|
videoTranscript: z7.string().nullable(),
|
|
1480
1481
|
documentFileName: z7.string().nullable().optional(),
|
|
1481
1482
|
documentTextMetadata: clarityDocumentTextMetadataSchema.nullable().optional(),
|
|
1483
|
+
processingFailureReason: z7.string().max(MAX_CLARITY_PROCESSING_FAILURE_REASON_LENGTH).nullable().optional(),
|
|
1482
1484
|
transcript: z7.array(conversationMessageSchema).nullable(),
|
|
1483
1485
|
/**
|
|
1484
1486
|
* Whether a non-empty interview transcript exists server-side. Set by
|
|
@@ -3559,7 +3561,14 @@ var clarityV2SnapshotStatusSchema = z8.enum([
|
|
|
3559
3561
|
"draft",
|
|
3560
3562
|
"generating"
|
|
3561
3563
|
]);
|
|
3562
|
-
var
|
|
3564
|
+
var CLARITY_V2_SNAPSHOT_CREATOR_TYPES = [
|
|
3565
|
+
"human",
|
|
3566
|
+
"ai",
|
|
3567
|
+
"seed"
|
|
3568
|
+
];
|
|
3569
|
+
var clarityV2SnapshotCreatorTypeSchema = extensibleEnum(
|
|
3570
|
+
CLARITY_V2_SNAPSHOT_CREATOR_TYPES
|
|
3571
|
+
);
|
|
3563
3572
|
var CLARITY_INTERVIEW_AREA_STATUSES = [
|
|
3564
3573
|
"not_started",
|
|
3565
3574
|
"partial",
|
|
@@ -3684,6 +3693,7 @@ var MAX_INTERVIEW_FRAME_BASE64_BYTES = 1e7;
|
|
|
3684
3693
|
var MAX_INTERVIEW_FRAMES_PER_TURN = 16;
|
|
3685
3694
|
var MAX_INTERVIEW_FRAMES_PER_AUTO_SAVE = 20;
|
|
3686
3695
|
var MAX_INTERVIEW_AUTO_SAVE_BATCH_BASE64_BYTES = 10 * 1024 * 1024;
|
|
3696
|
+
var INTERVIEW_RECORDING_PART_BYTES = 8 * 1024 * 1024;
|
|
3687
3697
|
var MAX_INTERVIEW_TRANSCRIPT_ENTRIES = 5e3;
|
|
3688
3698
|
var clarityInterviewFrameSchema = z9.object({
|
|
3689
3699
|
base64: z9.string().max(MAX_INTERVIEW_FRAME_BASE64_BYTES),
|
|
@@ -3996,6 +4006,19 @@ var interviewUploadUrlsResponseSchema = z10.object({
|
|
|
3996
4006
|
frameUploadUrls: z10.array(interviewFrameUploadSchema),
|
|
3997
4007
|
expiresAt: z10.string()
|
|
3998
4008
|
});
|
|
4009
|
+
var recordingPartQuerySchema = z10.object({
|
|
4010
|
+
type: clarityCaptureSubTypeSchema,
|
|
4011
|
+
screenshareStartTime: z10.coerce.number().int().nonnegative(),
|
|
4012
|
+
partCount: z10.coerce.number().int().min(1).max(4096)
|
|
4013
|
+
});
|
|
4014
|
+
var composeRecordingPartsBodySchema = z10.object({
|
|
4015
|
+
type: clarityCaptureSubTypeSchema,
|
|
4016
|
+
screenshareStartTime: z10.int().nonnegative(),
|
|
4017
|
+
partCount: z10.int().min(1).max(4096)
|
|
4018
|
+
});
|
|
4019
|
+
var composeRecordingPartsResponseSchema = z10.object({
|
|
4020
|
+
recordingGcsPath: z10.string()
|
|
4021
|
+
});
|
|
3999
4022
|
var CLARITY_DOCUMENT_CONTENT_TYPES = [
|
|
4000
4023
|
"application/pdf",
|
|
4001
4024
|
"text/plain",
|
|
@@ -4162,7 +4185,7 @@ var versioningApiFields = {
|
|
|
4162
4185
|
"Versioning state. Only one 'live' row per process at a time; drafts may be edited or generating before promotion."
|
|
4163
4186
|
),
|
|
4164
4187
|
creator_type: clarityV2SnapshotCreatorTypeSchema.describe(
|
|
4165
|
-
"Whether this row was created by a user edit ('human')
|
|
4188
|
+
"Whether this row was created by a user edit ('human'), an AI pipeline run ('ai'), or a module template's seeded document ('seed'). The value set may grow; see x-extensible-enum."
|
|
4166
4189
|
),
|
|
4167
4190
|
user_id: z12.guid().nullable().describe("Creator user id (the human who edited or triggered the run)."),
|
|
4168
4191
|
sandbox_id: z12.string().nullable().describe("E2B sandbox id that produced AI rows; null for user edits."),
|
|
@@ -6745,6 +6768,7 @@ var INTEGRATION_SLUGS = [
|
|
|
6745
6768
|
"duvo-computer-use-rdp",
|
|
6746
6769
|
"eu-commodity-prices",
|
|
6747
6770
|
"asana",
|
|
6771
|
+
"jira",
|
|
6748
6772
|
"ssh",
|
|
6749
6773
|
"scheduling",
|
|
6750
6774
|
"github",
|
|
@@ -6806,6 +6830,7 @@ var SERVER_RESOLVED_MCP_URL_SLUGS = /* @__PURE__ */ new Set([
|
|
|
6806
6830
|
"intercom",
|
|
6807
6831
|
"github",
|
|
6808
6832
|
"maersk",
|
|
6833
|
+
"jira",
|
|
6809
6834
|
"dsv",
|
|
6810
6835
|
"infor-nexus"
|
|
6811
6836
|
]);
|
|
@@ -15900,6 +15925,11 @@ var activeBannerSchema = z68.object({
|
|
|
15900
15925
|
var activeBannerResponseSchema = z68.object({
|
|
15901
15926
|
banner: activeBannerSchema.nullable()
|
|
15902
15927
|
});
|
|
15928
|
+
function getUserAgentChatRoomName(userId, teamId) {
|
|
15929
|
+
return `user:${userId}:team:${teamId}:agent-chat`;
|
|
15930
|
+
}
|
|
15931
|
+
__name(getUserAgentChatRoomName, "getUserAgentChatRoomName");
|
|
15932
|
+
__name3(getUserAgentChatRoomName, "getUserAgentChatRoomName");
|
|
15903
15933
|
var PLAN_FEATURE2 = {
|
|
15904
15934
|
BROWSER_AUTOMATION: "browser_automation",
|
|
15905
15935
|
ADVANCED_INTEGRATIONS: "advanced_integrations",
|
|
@@ -20221,6 +20251,7 @@ var updateTeamClaritySettingsSchema2 = z252.object({
|
|
|
20221
20251
|
industry: z252.string().trim().max(255).nullable().optional(),
|
|
20222
20252
|
annualRevenue: z252.number().nonnegative().nullable().optional()
|
|
20223
20253
|
});
|
|
20254
|
+
var MAX_CLARITY_PROCESSING_FAILURE_REASON_LENGTH2 = 500;
|
|
20224
20255
|
var clarityCaptureSchema2 = z252.object({
|
|
20225
20256
|
id: z252.guid(),
|
|
20226
20257
|
processId: z252.guid(),
|
|
@@ -20231,6 +20262,7 @@ var clarityCaptureSchema2 = z252.object({
|
|
|
20231
20262
|
videoTranscript: z252.string().nullable(),
|
|
20232
20263
|
documentFileName: z252.string().nullable().optional(),
|
|
20233
20264
|
documentTextMetadata: clarityDocumentTextMetadataSchema2.nullable().optional(),
|
|
20265
|
+
processingFailureReason: z252.string().max(MAX_CLARITY_PROCESSING_FAILURE_REASON_LENGTH2).nullable().optional(),
|
|
20234
20266
|
transcript: z252.array(conversationMessageSchema2).nullable(),
|
|
20235
20267
|
/**
|
|
20236
20268
|
* Whether a non-empty interview transcript exists server-side. Set by
|
|
@@ -21590,6 +21622,7 @@ var MAX_INTERVIEW_FRAME_BASE64_BYTES2 = 1e7;
|
|
|
21590
21622
|
var MAX_INTERVIEW_FRAMES_PER_TURN2 = 16;
|
|
21591
21623
|
var MAX_INTERVIEW_FRAMES_PER_AUTO_SAVE2 = 20;
|
|
21592
21624
|
var MAX_INTERVIEW_AUTO_SAVE_BATCH_BASE64_BYTES2 = 10 * 1024 * 1024;
|
|
21625
|
+
var INTERVIEW_RECORDING_PART_BYTES2 = 8 * 1024 * 1024;
|
|
21593
21626
|
var MAX_INTERVIEW_TRANSCRIPT_ENTRIES2 = 5e3;
|
|
21594
21627
|
var clarityInterviewFrameSchema2 = z262.object({
|
|
21595
21628
|
base64: z262.string().max(MAX_INTERVIEW_FRAME_BASE64_BYTES2),
|
|
@@ -25921,7 +25954,14 @@ var clarityV2SnapshotStatusSchema2 = z332.enum([
|
|
|
25921
25954
|
"draft",
|
|
25922
25955
|
"generating"
|
|
25923
25956
|
]);
|
|
25924
|
-
var
|
|
25957
|
+
var CLARITY_V2_SNAPSHOT_CREATOR_TYPES2 = [
|
|
25958
|
+
"human",
|
|
25959
|
+
"ai",
|
|
25960
|
+
"seed"
|
|
25961
|
+
];
|
|
25962
|
+
var clarityV2SnapshotCreatorTypeSchema2 = extensibleEnum2(
|
|
25963
|
+
CLARITY_V2_SNAPSHOT_CREATOR_TYPES2
|
|
25964
|
+
);
|
|
25925
25965
|
var clarityInterviewVoiceProviderSchema2 = z342.enum([
|
|
25926
25966
|
"OpenAi-realtime",
|
|
25927
25967
|
"Google-live"
|
|
@@ -26198,6 +26238,19 @@ var interviewUploadUrlsResponseSchema2 = z342.object({
|
|
|
26198
26238
|
frameUploadUrls: z342.array(interviewFrameUploadSchema2),
|
|
26199
26239
|
expiresAt: z342.string()
|
|
26200
26240
|
});
|
|
26241
|
+
var recordingPartQuerySchema2 = z342.object({
|
|
26242
|
+
type: clarityCaptureSubTypeSchema2,
|
|
26243
|
+
screenshareStartTime: z342.coerce.number().int().nonnegative(),
|
|
26244
|
+
partCount: z342.coerce.number().int().min(1).max(4096)
|
|
26245
|
+
});
|
|
26246
|
+
var composeRecordingPartsBodySchema2 = z342.object({
|
|
26247
|
+
type: clarityCaptureSubTypeSchema2,
|
|
26248
|
+
screenshareStartTime: z342.int().nonnegative(),
|
|
26249
|
+
partCount: z342.int().min(1).max(4096)
|
|
26250
|
+
});
|
|
26251
|
+
var composeRecordingPartsResponseSchema2 = z342.object({
|
|
26252
|
+
recordingGcsPath: z342.string()
|
|
26253
|
+
});
|
|
26201
26254
|
var CLARITY_DOCUMENT_CONTENT_TYPES2 = [
|
|
26202
26255
|
"application/pdf",
|
|
26203
26256
|
"text/plain",
|
|
@@ -26364,7 +26417,7 @@ var versioningApiFields2 = {
|
|
|
26364
26417
|
"Versioning state. Only one 'live' row per process at a time; drafts may be edited or generating before promotion."
|
|
26365
26418
|
),
|
|
26366
26419
|
creator_type: clarityV2SnapshotCreatorTypeSchema2.describe(
|
|
26367
|
-
"Whether this row was created by a user edit ('human')
|
|
26420
|
+
"Whether this row was created by a user edit ('human'), an AI pipeline run ('ai'), or a module template's seeded document ('seed'). The value set may grow; see x-extensible-enum."
|
|
26368
26421
|
),
|
|
26369
26422
|
user_id: z362.guid().nullable().describe("Creator user id (the human who edited or triggered the run)."),
|
|
26370
26423
|
sandbox_id: z362.string().nullable().describe("E2B sandbox id that produced AI rows; null for user edits."),
|
|
@@ -28237,6 +28290,7 @@ var MCP_OAUTH_CATALOG_SERVER_URLS = {
|
|
|
28237
28290
|
attio: "https://mcp.attio.com/mcp",
|
|
28238
28291
|
amplitude: "https://mcp.amplitude.com/mcp",
|
|
28239
28292
|
asana: "https://mcp.asana.com/v2/mcp",
|
|
28293
|
+
jira: "https://mcp.atlassian.com/v2/mcp",
|
|
28240
28294
|
"notion-native": "https://mcp.notion.com/mcp",
|
|
28241
28295
|
granola: "https://mcp.granola.ai/mcp",
|
|
28242
28296
|
apify: "https://mcp.apify.com",
|
|
@@ -31712,6 +31766,7 @@ var INTEGRATION_SLUGS2 = [
|
|
|
31712
31766
|
"duvo-computer-use-rdp",
|
|
31713
31767
|
"eu-commodity-prices",
|
|
31714
31768
|
"asana",
|
|
31769
|
+
"jira",
|
|
31715
31770
|
"ssh",
|
|
31716
31771
|
"scheduling",
|
|
31717
31772
|
"github",
|
|
@@ -31774,6 +31829,7 @@ var SERVER_RESOLVED_MCP_URL_SLUGS2 = /* @__PURE__ */ new Set([
|
|
|
31774
31829
|
"intercom",
|
|
31775
31830
|
"github",
|
|
31776
31831
|
"maersk",
|
|
31832
|
+
"jira",
|
|
31777
31833
|
"dsv",
|
|
31778
31834
|
"infor-nexus"
|
|
31779
31835
|
]);
|
|
@@ -34282,9 +34338,6 @@ var adminOrgAddDomainRequestSchema = z71.object({
|
|
|
34282
34338
|
var adminOrgAddDomainResponseSchema = z71.object({
|
|
34283
34339
|
domain: adminOrgDomainSchema
|
|
34284
34340
|
});
|
|
34285
|
-
var adminOrgAssignTeamRequestSchema = z71.object({
|
|
34286
|
-
teamId: z71.guid()
|
|
34287
|
-
});
|
|
34288
34341
|
var adminOrgAddMemberRequestSchema = z71.object({
|
|
34289
34342
|
userId: z71.guid(),
|
|
34290
34343
|
role: z71.enum(ORG_ROLES2.ALL)
|
|
@@ -35561,6 +35614,31 @@ var agentChatMessageMetadataSchema = z81.object({
|
|
|
35561
35614
|
transport: z81.enum(AGENT_CHAT_TRANSPORTS),
|
|
35562
35615
|
mcpServers: z81.array(z81.string().trim().min(1).max(80)).max(32),
|
|
35563
35616
|
fallbackReason: z81.enum(AGENT_CHAT_RUNTIME_FALLBACK_REASONS).optional()
|
|
35617
|
+
}).optional(),
|
|
35618
|
+
/**
|
|
35619
|
+
* What this turn ran under: a digest of the Process grants, or the
|
|
35620
|
+
* `unrestricted` marker when the owner had no Process restriction.
|
|
35621
|
+
*
|
|
35622
|
+
* Written on EVERY dispatched turn, restricted or not, because the next turn
|
|
35623
|
+
* compares itself against it — a turn whose value differs does not resume the
|
|
35624
|
+
* model session the previous one produced. That covers a revoked dashboard, a
|
|
35625
|
+
* reassigned role and a team switch, and equally the unrestricted turn in
|
|
35626
|
+
* between two restricted ones, which would otherwise be invisible.
|
|
35627
|
+
*
|
|
35628
|
+
* Storing the digest rather than the grants keeps the sidecar from becoming a
|
|
35629
|
+
* second copy of the grant table; `queueCount` and `canActOnCases` are for
|
|
35630
|
+
* reading the transcript back in Chat Debugger, not for authorization, and are
|
|
35631
|
+
* written only for a restricted turn.
|
|
35632
|
+
*
|
|
35633
|
+
* Admin transcript only, like `runtime` and `skills` — not in the response
|
|
35634
|
+
* projection below.
|
|
35635
|
+
*/
|
|
35636
|
+
process: z81.object({
|
|
35637
|
+
scopeFingerprint: z81.string().trim().min(1).max(64),
|
|
35638
|
+
queueCount: z81.number().int().min(0).max(1e4).optional(),
|
|
35639
|
+
canActOnCases: z81.boolean().optional(),
|
|
35640
|
+
/** Set when this turn started a fresh session because the grants changed. */
|
|
35641
|
+
sessionResetOnScopeChange: z81.boolean().optional()
|
|
35564
35642
|
}).optional()
|
|
35565
35643
|
});
|
|
35566
35644
|
var agentChatMessageMetadataResponseSchema = z81.object({
|
|
@@ -38440,6 +38518,7 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38440
38518
|
AGENT_BUILDER_ASK_DUVO: {
|
|
38441
38519
|
key: "agent_builder_ask_duvo",
|
|
38442
38520
|
defaultValue: false,
|
|
38521
|
+
implies: ["agent_chat"],
|
|
38443
38522
|
description: "Routes the Agent Builder prompt input through Ask Duvo instead of building the AOP inline: the welcome hero and the config-editor composer hand their prompt to a fresh Ask Duvo chat that continues the conversation, and the builder input hides itself once handed off. When off, both inputs keep generating and editing the AOP in place. Requires AGENT_CHAT \u2014 the handoff needs the chat surface to land in, so with AGENT_CHAT off this flag does nothing. Separate from AGENT_CHAT so the builder handoff can roll out independently of the rest of Ask Duvo. Off by default for staged rollout."
|
|
38444
38523
|
},
|
|
38445
38524
|
BROWSING_RECORDING_SCREENSHOTS: {
|
|
@@ -38452,25 +38531,22 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38452
38531
|
defaultValue: false,
|
|
38453
38532
|
description: "Enables the Duvo help chat dock (bottom-right floating composer + history popover) and its backend routes. When disabled, the dock is hidden and /v1/agent-chats endpoints return 404; cc-server ingestion callback is unaffected."
|
|
38454
38533
|
},
|
|
38455
|
-
AGENT_CHAT_COMPOSER_V3: {
|
|
38456
|
-
key: "agent_chat_composer_v3",
|
|
38457
|
-
defaultValue: false,
|
|
38458
|
-
description: "Swaps the Ask Duvo chat composer (rail, splash, and conversation surfaces) from the plain textarea to the Lexical editor with inline agent-mention pills. Frontend-only: messages serialize to the same <DUVO:AGENT_CONFIG> wire format, no backend behavior changes. Off-by-default for staged rollout; turning it off restores the V2 textarea composer."
|
|
38459
|
-
},
|
|
38460
38534
|
AGENT_CHAT_UI_RESOURCES: {
|
|
38461
38535
|
key: "agent_chat_ui_resources",
|
|
38462
38536
|
defaultValue: false,
|
|
38537
|
+
implies: ["agent_chat"],
|
|
38463
38538
|
description: "Renders interactive UI-resource preview cards (MCP Apps) in the Ask Duvo transcript \u2014 v1: the Pulse dashboard preview on artifact-applied notices, shown in a sandboxed opaque-origin iframe. Frontend render gate only: snapshot capture and persistence (the transport layer) run regardless, so flipping this on needs no backfill. Off-by-default for staged rollout to internal teams first."
|
|
38464
38539
|
},
|
|
38465
38540
|
AGENT_CHAT_V2: {
|
|
38466
38541
|
key: "agent_chat_v2",
|
|
38467
38542
|
defaultValue: false,
|
|
38543
|
+
implies: ["agent_chat"],
|
|
38468
38544
|
description: "Ask Duvo v2 runtime: duvo CLI tool surface via a managed cross-team user-scoped API key, replacing the public-API MCP server \u2014 see specs/ask-duvo-cli-tools/PLAN.md"
|
|
38469
38545
|
},
|
|
38470
38546
|
CASE_SCHEMA: {
|
|
38471
38547
|
key: "case_schema",
|
|
38472
38548
|
defaultValue: false,
|
|
38473
|
-
description: "Per-team opt-in for typed Case payloads (versioned Case schemas on a queue).
|
|
38549
|
+
description: "Per-team opt-in for typed Case payloads (versioned Case schemas on a queue), for STANDALONE queues only \u2014 a queue inside an Automation has typed Case schemas on whatever this flag says, since it is built and versioned as part of that Automation and its producing agent is expected to declare the shape it writes (see `isCaseSchemaEnabledForQueue`). For a standalone queue the flag gates the whole schema-management surface: the Case schema pill and its dialog in the Queue detail are hidden when off; the person-facing schema routes (get/create/replace/attach/detach/settings under /queues/:id/json-schema) and the agent-facing declare/get routes (/v1/case-queue/queues/:id/json-schema) 404 when off, which also disables the get_case_schema/declare_case_schema MCP tools and the `duvo queues schema` CLI commands that call them. It does NOT gate reading or writing cases (add_cases and the agent's case read path are ungated), so a queue that was already typed while the flag was on keeps its stored json_data and its consumers keep working \u2014 the flag governs whether a standalone queue can be typed or its schema managed, not the execution of cases that already are. Off by default for staged rollout."
|
|
38474
38550
|
},
|
|
38475
38551
|
CODE_STEPS: {
|
|
38476
38552
|
key: "code_steps",
|
|
@@ -38495,6 +38571,7 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38495
38571
|
AUTOMATION_VERSIONING: {
|
|
38496
38572
|
key: "automation_versioning",
|
|
38497
38573
|
defaultValue: false,
|
|
38574
|
+
implies: ["automations"],
|
|
38498
38575
|
description: "Makes the Automations migration convert straight to revision semantics instead of the lite workspace. When off (the default), POST /automations/migrate writes automation containers only and stamps team.automations_migrated_at; when on, it also snapshots each automation's current live builds, queue routing, trigger configs and recurring schedules as revision 1 and stamps team.automation_revisions_migrated_at. Only applies to a team that is still standalone \u2014 it is not the lite-to-versioned cutover, which resolves its groups from existing automation membership rather than by closure discovery. Resolved by team/org (user-level overrides are ignored by the migration gate), and only consulted for a team that also has AUTOMATIONS on."
|
|
38499
38576
|
},
|
|
38500
38577
|
AGENT_QUEUE_DETAIL_REDESIGN: {
|
|
@@ -38557,6 +38634,11 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38557
38634
|
defaultValue: false,
|
|
38558
38635
|
description: "Read only while clarity_wss_first_transport is off (the INC-150 kill-switch path): superseded by clarity_sdp_proxy_wss_fallback, still honoured on its own so teams already enabled keep working. Routes interview WebRTC signaling through the Duvo backend. Retirement staged in #10298 once the kill switch itself retires."
|
|
38559
38636
|
},
|
|
38637
|
+
CLARITY_INTERVIEW_UPLOAD_PROXY_FALLBACK: {
|
|
38638
|
+
key: "clarity_interview_upload_proxy_fallback",
|
|
38639
|
+
defaultValue: false,
|
|
38640
|
+
description: "Lets a Clarity interview finish on networks that block storage.googleapis.com. The browser still PUTs the recording straight to the GCS signed URL first; when that fails at the network level (the fetch rejects with no HTTP status) and this flag is on, the recording is uploaded through backend-node in 8 MiB parts that the backend composes into the same GCS object. Off by default: the fallback routes answer 404 and the client keeps today's direct-upload behaviour. Enable per team for customers whose interviewees sit behind corporate egress filters (DUVO-11549)."
|
|
38641
|
+
},
|
|
38560
38642
|
CLARITY_INTERVIEW_WS_FALLBACK: {
|
|
38561
38643
|
key: "clarity_interview_ws_fallback",
|
|
38562
38644
|
defaultValue: false,
|
|
@@ -38622,6 +38704,11 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38622
38704
|
defaultValue: true,
|
|
38623
38705
|
description: "Allows staff to impersonate users who belong to the targeted tenant. Default ON. Turn off as a team or organization override to refuse execute for any target who is a member of that tenant \u2014 impersonation is user-level, so one disabled tenant among the target's memberships blocks the session. User-level overrides are ignored (this is a tenant policy, not a per-person toggle). Creating and ending a session are not gated. An already-live session is not revoked; it expires on its existing deadline. The Impersonate control stays visible; execute returns 403."
|
|
38624
38706
|
},
|
|
38707
|
+
JIRA_CONNECTION: {
|
|
38708
|
+
key: "jira_connection",
|
|
38709
|
+
defaultValue: false,
|
|
38710
|
+
description: "Enables Jira connection setup through Atlassian MCP v2. Turning this off hides Jira and blocks setup and attachment to agents. Existing agents can continue to use saved connections and refresh their credentials."
|
|
38711
|
+
},
|
|
38625
38712
|
MAERSK_CONNECTION: {
|
|
38626
38713
|
key: "maersk_connection",
|
|
38627
38714
|
defaultValue: false,
|
|
@@ -38660,6 +38747,7 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38660
38747
|
META_AGENT_ARTIFACTS: {
|
|
38661
38748
|
key: "meta_agent_artifacts",
|
|
38662
38749
|
defaultValue: false,
|
|
38750
|
+
implies: ["agent_chat"],
|
|
38663
38751
|
description: "Enables Ask Duvo Artifacts \u2014 Ask Duvo binds to the artifact on the current page and can create/edit it (Pulse first). When disabled, chat sends carry no structured page context, the duvoChat Pulse tools refuse, and the artifact endpoints return 404. The `meta_agent_artifacts` key is the legacy name kept deliberately: renaming a flag key orphans its per-team overrides."
|
|
38664
38752
|
},
|
|
38665
38753
|
MINUTE_SCHEDULING: {
|
|
@@ -38710,6 +38798,7 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38710
38798
|
PULSE_EDIT_IN_ASK_DUVO: {
|
|
38711
38799
|
key: "pulse_edit_in_ask_duvo",
|
|
38712
38800
|
defaultValue: false,
|
|
38801
|
+
implies: ["agent_chat", "meta_agent_artifacts"],
|
|
38713
38802
|
description: "Routes Pulse through Ask Duvo instead of the native Pulse chat panel. Covers both halves of a dashboard's life. Editing: clicking 'Edit in chat' opens the Ask Duvo rail bound to the dashboard (so the agent can edit it and prior Pulse chat messages surface in-rail); with the flag off the button toggles the native in-page Pulse chat panel as before. Creating: submitting a prompt on the New Pulse page opens an Ask Duvo conversation whose first message is that prompt and whose hidden companion turn makes the agent build the dashboard immediately, so the build narrates in the conversation instead of in silence; with the flag off New Pulse creates the dashboard directly and lands on its canvas. Text-only submissions take the Ask Duvo path \u2014 a submission carrying file attachments always creates directly, since the in-chat create tool cannot carry them. Requires META_AGENT_ARTIFACTS (which registers the in-chat create/edit tools; without it the agent falls back to the public createPulseDashboard tool and produces a dashboard with no binding and no in-chat progress) and AGENT_CHAT (the surface the conversation lands in). Off-by-default for staged rollout."
|
|
38714
38803
|
},
|
|
38715
38804
|
PULSE_OPENUI: {
|
|
@@ -38725,8 +38814,24 @@ var FEATURE_FLAG_CATALOGUE = {
|
|
|
38725
38814
|
FREIGHT_MODULE: {
|
|
38726
38815
|
key: "freight_module",
|
|
38727
38816
|
defaultValue: false,
|
|
38817
|
+
// The hard gate on the surface is `team.automations_migrated_at`, and
|
|
38818
|
+
// AUTOMATIONS is the flag that exposes the migration producing that
|
|
38819
|
+
// stamp: a team without it has no workspace for a Module to install
|
|
38820
|
+
// into, so turning this on alone leaves the surface unreachable.
|
|
38821
|
+
implies: ["automations"],
|
|
38728
38822
|
description: "Per-team opt-in for the Freight Audit Module. Gates the Automation Modules surface: the 'Modules' entry at the top of the Process Automation sidebar section, the /teams/:teamId/modules page (which lists the Freight Audit module), and the module surfaces on the Automation detail page \u2014 an automation whose name matches a catalog module (currently 'Freight Audit') gets a 'Setup' tab with the static module overview, a 'Modules / {name}' breadcrumb, a 'Demo' badge, and a setup CTA in place of the revision switcher. When off, the nav entry is hidden, the page returns 404, and the detail page renders as a plain automation (a ?tab=setup deep link falls back to General). The surface additionally requires the team to be on the Automations workspace (`automations_migrated_at` stamped) \u2014 `lite` or `versioned`, since a Module installs into an automation and the installer writes the owning automation in whichever shape the team's model holds; for a standalone team the nav entry is hidden and the page redirects to Agents even with the flag on. Also gates the Ask Duvo card on Pulse dashboards: the generator may render a `[data-duvo-ask]` card whose submitted question opens Ask Duvo in the side panel on a fresh chat. When OFF, the frame strips any such card out of the dashboard before writing it in and the parent bridge is inert, so a dashboard built with a card renders without one rather than showing a control that does nothing. The card additionally requires AGENT_CHAT, since a question has nowhere to go without Ask Duvo. Also switches the Ask Duvo transcript to its business-clean reading experience: every consecutive tool call in a turn \u2014 including a subagent delegation and the subagent's own calls \u2014 folds into a single collapsed 'Duvo took N steps' row that expands on click into the individual tool cards, in place of the per-tool rows (and the nested delegation card) shown otherwise. Frontend-only and purely presentational: the running tool still surfaces as the activity-line verb, and turning the flag off restores the per-tool transcript with no data change. Off by default for staged rollout."
|
|
38729
38823
|
},
|
|
38824
|
+
AUTOMATIONS_TO_MODULES: {
|
|
38825
|
+
key: "automations_to_modules",
|
|
38826
|
+
defaultValue: false,
|
|
38827
|
+
description: "Per-team opt-in for the Automations-to-Modules programme \u2014 the umbrella flag every step of that work is guarded by, so the whole programme can be shown to a team or pulled back in one switch. Step one is the frontend rebrand: the Automations entity reads as 'Module' / 'Modules' wherever a user meets it (sidebar entry, list and detail pages, breadcrumbs, side nav, dialogs, toasts, the Past Runs and Requests columns) and 'Create Automation' becomes 'Add Module'; Clarity's generated proposal reads as a 'Module proposal' to match. The 'Process Automation' sidebar section keeps its name \u2014 it names the product area, not the entity. Labels only: routes stay /teams/:teamId/automations/*, and no API, payload, or database naming changes, so the flag is a pure copy switch. When off (default), every one of those surfaces reads exactly as it does today. Off by default for staged rollout."
|
|
38828
|
+
},
|
|
38829
|
+
MODULE_SOLUTIONS_GALLERY: {
|
|
38830
|
+
key: "module_solutions_gallery",
|
|
38831
|
+
defaultValue: false,
|
|
38832
|
+
implies: ["freight_module"],
|
|
38833
|
+
description: "Per-team opt-in for the Module Solutions gallery \u2014 the Explore section's 'Module Solutions' entry and the /teams/:teamId/solutions page, which lays the module catalog out as the supply-chain value chain. Exists for demoing our modules vision: the catalog is mostly placeholder modules mapping out the chain rather than wired surfaces, so it is shown to the teams a demo is being given to and nobody else. When off (default), the Explore section is hidden in the sidebar, the entry drops out of the command palette, and the page returns 404; a module's own /teams/:teamId/modules/:slug workspace is unaffected and keeps answering to FREIGHT_MODULE. Requires FREIGHT_MODULE and the team being on the Automations workspace (`automations_migrated_at` stamped) for the same reason the modules surface does \u2014 a Module installs into an automation, so a team with no workspace has nowhere to put one."
|
|
38834
|
+
},
|
|
38730
38835
|
AUTOMATION_RUN_TOASTS: {
|
|
38731
38836
|
key: "automation_run_toasts",
|
|
38732
38837
|
defaultValue: false,
|
|
@@ -38771,6 +38876,104 @@ var FEATURE_FLAG_DESCRIPTIONS = Object.fromEntries(
|
|
|
38771
38876
|
entry.description
|
|
38772
38877
|
])
|
|
38773
38878
|
);
|
|
38879
|
+
var FEATURE_FLAG_IMPLICATIONS = (() => {
|
|
38880
|
+
const implications = {};
|
|
38881
|
+
for (const entry of Object.values(FEATURE_FLAG_CATALOGUE)) {
|
|
38882
|
+
implications[entry.key] = "implies" in entry ? [...entry.implies] : [];
|
|
38883
|
+
}
|
|
38884
|
+
return implications;
|
|
38885
|
+
})();
|
|
38886
|
+
var FEATURE_FLAG_IMPLIED_BY = (() => {
|
|
38887
|
+
const impliedBy = {};
|
|
38888
|
+
for (const flagKey of Object.keys(
|
|
38889
|
+
FEATURE_FLAG_IMPLICATIONS
|
|
38890
|
+
)) {
|
|
38891
|
+
impliedBy[flagKey] = [];
|
|
38892
|
+
}
|
|
38893
|
+
for (const [flagKey, implied] of Object.entries(
|
|
38894
|
+
FEATURE_FLAG_IMPLICATIONS
|
|
38895
|
+
)) {
|
|
38896
|
+
for (const impliedKey of implied) {
|
|
38897
|
+
impliedBy[impliedKey].push(flagKey);
|
|
38898
|
+
}
|
|
38899
|
+
}
|
|
38900
|
+
return impliedBy;
|
|
38901
|
+
})();
|
|
38902
|
+
function collectFlagClosure(startKey, edges) {
|
|
38903
|
+
const seen = /* @__PURE__ */ new Set([startKey]);
|
|
38904
|
+
const ordered = [];
|
|
38905
|
+
const visit = /* @__PURE__ */ __name3((flagKey) => {
|
|
38906
|
+
for (const next of edges[flagKey] ?? []) {
|
|
38907
|
+
if (seen.has(next)) {
|
|
38908
|
+
continue;
|
|
38909
|
+
}
|
|
38910
|
+
seen.add(next);
|
|
38911
|
+
visit(next);
|
|
38912
|
+
ordered.push(next);
|
|
38913
|
+
}
|
|
38914
|
+
}, "visit");
|
|
38915
|
+
visit(startKey);
|
|
38916
|
+
return ordered;
|
|
38917
|
+
}
|
|
38918
|
+
__name(collectFlagClosure, "collectFlagClosure");
|
|
38919
|
+
__name3(collectFlagClosure, "collectFlagClosure");
|
|
38920
|
+
function getImpliedFeatureFlags(flagKey) {
|
|
38921
|
+
return collectFlagClosure(flagKey, FEATURE_FLAG_IMPLICATIONS);
|
|
38922
|
+
}
|
|
38923
|
+
__name(getImpliedFeatureFlags, "getImpliedFeatureFlags");
|
|
38924
|
+
__name3(getImpliedFeatureFlags, "getImpliedFeatureFlags");
|
|
38925
|
+
function getImplyingFeatureFlags(flagKey) {
|
|
38926
|
+
return collectFlagClosure(flagKey, FEATURE_FLAG_IMPLIED_BY);
|
|
38927
|
+
}
|
|
38928
|
+
__name(getImplyingFeatureFlags, "getImplyingFeatureFlags");
|
|
38929
|
+
__name3(getImplyingFeatureFlags, "getImplyingFeatureFlags");
|
|
38930
|
+
function findFeatureFlagImplicationCycle() {
|
|
38931
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
38932
|
+
const settled = /* @__PURE__ */ new Set();
|
|
38933
|
+
const path = [];
|
|
38934
|
+
const walk = /* @__PURE__ */ __name3((flagKey) => {
|
|
38935
|
+
if (visiting.has(flagKey)) {
|
|
38936
|
+
return [...path.slice(path.indexOf(flagKey)), flagKey];
|
|
38937
|
+
}
|
|
38938
|
+
if (settled.has(flagKey)) {
|
|
38939
|
+
return null;
|
|
38940
|
+
}
|
|
38941
|
+
visiting.add(flagKey);
|
|
38942
|
+
path.push(flagKey);
|
|
38943
|
+
for (const implied of FEATURE_FLAG_IMPLICATIONS[flagKey] ?? []) {
|
|
38944
|
+
const cycle = walk(implied);
|
|
38945
|
+
if (cycle) {
|
|
38946
|
+
return cycle;
|
|
38947
|
+
}
|
|
38948
|
+
}
|
|
38949
|
+
path.pop();
|
|
38950
|
+
visiting.delete(flagKey);
|
|
38951
|
+
settled.add(flagKey);
|
|
38952
|
+
return null;
|
|
38953
|
+
}, "walk");
|
|
38954
|
+
for (const flagKey of Object.keys(
|
|
38955
|
+
FEATURE_FLAG_IMPLICATIONS
|
|
38956
|
+
)) {
|
|
38957
|
+
const cycle = walk(flagKey);
|
|
38958
|
+
if (cycle) {
|
|
38959
|
+
return cycle;
|
|
38960
|
+
}
|
|
38961
|
+
}
|
|
38962
|
+
return null;
|
|
38963
|
+
}
|
|
38964
|
+
__name(findFeatureFlagImplicationCycle, "findFeatureFlagImplicationCycle");
|
|
38965
|
+
__name3(findFeatureFlagImplicationCycle, "findFeatureFlagImplicationCycle");
|
|
38966
|
+
function resolveFeatureFlagWithImplications(flagKey, resolveOwnValue) {
|
|
38967
|
+
const impliedBy = getImplyingFeatureFlags(flagKey).filter(
|
|
38968
|
+
(implyingKey) => resolveOwnValue(implyingKey) === true
|
|
38969
|
+
);
|
|
38970
|
+
if (impliedBy.length > 0) {
|
|
38971
|
+
return { value: true, impliedBy };
|
|
38972
|
+
}
|
|
38973
|
+
return { value: resolveOwnValue(flagKey), impliedBy };
|
|
38974
|
+
}
|
|
38975
|
+
__name(resolveFeatureFlagWithImplications, "resolveFeatureFlagWithImplications");
|
|
38976
|
+
__name3(resolveFeatureFlagWithImplications, "resolveFeatureFlagWithImplications");
|
|
38774
38977
|
function coerceFlagValue(value) {
|
|
38775
38978
|
if (value === void 0) {
|
|
38776
38979
|
return void 0;
|
|
@@ -49689,7 +49892,8 @@ var IMAGE_CONTENT_TYPES = {
|
|
|
49689
49892
|
".png": "image/png",
|
|
49690
49893
|
".jpg": "image/jpeg",
|
|
49691
49894
|
".jpeg": "image/jpeg",
|
|
49692
|
-
".webp": "image/webp"
|
|
49895
|
+
".webp": "image/webp",
|
|
49896
|
+
".svg": "image/svg+xml"
|
|
49693
49897
|
};
|
|
49694
49898
|
function resolveContentType(kind, extension, allowSpreadsheets) {
|
|
49695
49899
|
if (kind === "document") {
|
|
@@ -49718,7 +49922,7 @@ function unsupportedFormatMessage(kind, allowSpreadsheets) {
|
|
|
49718
49922
|
if (kind === "video") {
|
|
49719
49923
|
return "Video must be MP4, MOV, WEBM, MPEG, MPG, AVI, FLV, WMV, 3GP, or 3GPP.";
|
|
49720
49924
|
}
|
|
49721
|
-
return "Image must be a PNG, JPEG, or
|
|
49925
|
+
return "Image must be a PNG, JPEG, WebP, or SVG file.";
|
|
49722
49926
|
}
|
|
49723
49927
|
__name(unsupportedFormatMessage, "unsupportedFormatMessage");
|
|
49724
49928
|
function maximumSizeFor(kind) {
|
|
@@ -63417,10 +63621,10 @@ var TABLE_COLUMNS40 = [
|
|
|
63417
63621
|
{ header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.status, "cell") },
|
|
63418
63622
|
{ header: "UPDATED", cell: /* @__PURE__ */ __name((row) => row.updated_at, "cell") }
|
|
63419
63623
|
];
|
|
63420
|
-
var SCOPE_FLAGS = ["--
|
|
63624
|
+
var SCOPE_FLAGS = ["--published", "--shared", "--automation"];
|
|
63421
63625
|
function resolveScope(options) {
|
|
63422
63626
|
const selected = [
|
|
63423
|
-
options.
|
|
63627
|
+
options.published && "--published",
|
|
63424
63628
|
options.shared && "--shared",
|
|
63425
63629
|
options.automation && "--automation"
|
|
63426
63630
|
].filter((flag) => typeof flag === "string");
|
|
@@ -63429,7 +63633,7 @@ function resolveScope(options) {
|
|
|
63429
63633
|
`${SCOPE_FLAGS.join(", ")} are different scopes \u2014 pass at most one. You passed ${selected.join(" and ")}.`
|
|
63430
63634
|
);
|
|
63431
63635
|
}
|
|
63432
|
-
if (options.
|
|
63636
|
+
if (options.published) {
|
|
63433
63637
|
return "team";
|
|
63434
63638
|
}
|
|
63435
63639
|
if (options.shared) {
|
|
@@ -63442,9 +63646,11 @@ function resolveScope(options) {
|
|
|
63442
63646
|
}
|
|
63443
63647
|
__name(resolveScope, "resolveScope");
|
|
63444
63648
|
function registerPulseList(pulse) {
|
|
63445
|
-
pulse.command("list", { isDefault: true }).description(
|
|
63446
|
-
"--team"
|
|
63447
|
-
|
|
63649
|
+
pulse.command("list", { isDefault: true }).description(
|
|
63650
|
+
"List your Pulse dashboards in the selected team (--team <id>, DUVO_TEAM_ID, or the profile default)"
|
|
63651
|
+
).option(
|
|
63652
|
+
"--published",
|
|
63653
|
+
"list dashboards a teammate published to the whole team instead of your own"
|
|
63448
63654
|
).option("--shared", "deprecated: always returns no dashboards").option(
|
|
63449
63655
|
"--automation",
|
|
63450
63656
|
"list the dashboards owned by your team's automations, each prefixed with its automation's name"
|
|
@@ -63455,7 +63661,11 @@ function registerPulseList(pulse) {
|
|
|
63455
63661
|
max: MAX_LIMIT15
|
|
63456
63662
|
});
|
|
63457
63663
|
const offset = parseOffset(options.offset);
|
|
63458
|
-
const
|
|
63664
|
+
const config = await requireAuthenticatedConfig(this);
|
|
63665
|
+
const { apiKey, apiBaseUrl } = config;
|
|
63666
|
+
const teamId = await resolveRequiredTeamId(config, {
|
|
63667
|
+
override: getTeamFlag(this)
|
|
63668
|
+
});
|
|
63459
63669
|
const searchParams = new URLSearchParams();
|
|
63460
63670
|
const scope = resolveScope(options);
|
|
63461
63671
|
searchParams.append("scope", scope);
|
|
@@ -63463,7 +63673,7 @@ function registerPulseList(pulse) {
|
|
|
63463
63673
|
searchParams.append("offset", String(offset));
|
|
63464
63674
|
const raw = await httpRequest({
|
|
63465
63675
|
method: "GET",
|
|
63466
|
-
path: "/
|
|
63676
|
+
path: buildTeamPath(teamId, "/artifacts"),
|
|
63467
63677
|
apiKey,
|
|
63468
63678
|
apiBaseUrl,
|
|
63469
63679
|
searchParams
|
|
@@ -70531,7 +70741,7 @@ __name(isStandaloneBinary, "isStandaloneBinary");
|
|
|
70531
70741
|
import { createRequire } from "node:module";
|
|
70532
70742
|
function getPackageMeta() {
|
|
70533
70743
|
if (true) {
|
|
70534
|
-
return { name: "@duvoai/cli", version: "1.
|
|
70744
|
+
return { name: "@duvoai/cli", version: "1.78.0" };
|
|
70535
70745
|
}
|
|
70536
70746
|
const require2 = createRequire(import.meta.url);
|
|
70537
70747
|
const raw = require2("../../package.json");
|