@duvoai/cli 1.28.1 → 1.31.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/README.md +19 -0
- package/dist/bin/duvo.js +949 -277
- package/dist/bin/duvo.js.map +4 -4
- package/package.json +1 -1
package/dist/bin/duvo.js
CHANGED
|
@@ -3,9 +3,6 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
4
|
|
|
5
5
|
// src/bin/create-program.ts
|
|
6
|
-
import { readFileSync as readFileSync8 } from "node:fs";
|
|
7
|
-
import { dirname as dirname3, join as join3 } from "node:path";
|
|
8
|
-
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
9
6
|
import { Command, Option as Option2 } from "commander";
|
|
10
7
|
|
|
11
8
|
// src/api/agent-folder-schemas.ts
|
|
@@ -2676,6 +2673,34 @@ var BUILD_STATUS = {
|
|
|
2676
2673
|
LIVE: "live",
|
|
2677
2674
|
HISTORIC: "historic"
|
|
2678
2675
|
};
|
|
2676
|
+
var CASE_PRIORITY = {
|
|
2677
|
+
NONE: "none",
|
|
2678
|
+
MEDIUM: "medium",
|
|
2679
|
+
HIGH: "high"
|
|
2680
|
+
};
|
|
2681
|
+
var CASE_PRIORITY_VALUES = {
|
|
2682
|
+
none: 0,
|
|
2683
|
+
medium: 10,
|
|
2684
|
+
high: 50
|
|
2685
|
+
};
|
|
2686
|
+
var DEFAULT_CASE_PRIORITY = CASE_PRIORITY.NONE;
|
|
2687
|
+
var DEFAULT_CASE_PRIORITY_VALUE = CASE_PRIORITY_VALUES.none;
|
|
2688
|
+
function casePriorityToValue(priority) {
|
|
2689
|
+
return CASE_PRIORITY_VALUES[priority];
|
|
2690
|
+
}
|
|
2691
|
+
__name(casePriorityToValue, "casePriorityToValue");
|
|
2692
|
+
__name2(casePriorityToValue, "casePriorityToValue");
|
|
2693
|
+
function casePriorityFromValue(value) {
|
|
2694
|
+
if (value >= CASE_PRIORITY_VALUES.high) {
|
|
2695
|
+
return CASE_PRIORITY.HIGH;
|
|
2696
|
+
}
|
|
2697
|
+
if (value >= CASE_PRIORITY_VALUES.medium) {
|
|
2698
|
+
return CASE_PRIORITY.MEDIUM;
|
|
2699
|
+
}
|
|
2700
|
+
return CASE_PRIORITY.NONE;
|
|
2701
|
+
}
|
|
2702
|
+
__name(casePriorityFromValue, "casePriorityFromValue");
|
|
2703
|
+
__name2(casePriorityFromValue, "casePriorityFromValue");
|
|
2679
2704
|
var INGESTION_BODY_LIMIT_BYTES = 5 * 1024 * 1024;
|
|
2680
2705
|
var CLARITY_WEBHOOK_BODY_LIMIT_BYTES = 25 * 1024 * 1024;
|
|
2681
2706
|
var SENSITIVE_FIELD_KEYWORDS = [
|
|
@@ -3672,12 +3697,27 @@ var portfolioIntelligenceStatusSchema = z15.enum(
|
|
|
3672
3697
|
PORTFOLIO_INTELLIGENCE_STATUSES
|
|
3673
3698
|
);
|
|
3674
3699
|
var EXECUTION_MODES = ["human-led", "hybrid", "agent-led"];
|
|
3700
|
+
var BENEFIT_BASES = ["evidenced", "estimate"];
|
|
3701
|
+
var operatingModelBenefitSchema = z15.object({
|
|
3702
|
+
statement: z15.string().min(1),
|
|
3703
|
+
basis: z15.enum(BENEFIT_BASES),
|
|
3704
|
+
assumption: z15.string().nullable(),
|
|
3705
|
+
dataToFirmUp: z15.string().nullable()
|
|
3706
|
+
}).refine(
|
|
3707
|
+
(benefit) => benefit.basis !== "estimate" || Boolean(benefit.assumption && benefit.assumption.trim().length > 0),
|
|
3708
|
+
{
|
|
3709
|
+
message: "Estimate benefits require a stated assumption",
|
|
3710
|
+
path: ["assumption"]
|
|
3711
|
+
}
|
|
3712
|
+
);
|
|
3675
3713
|
var operatingModelValueStreamSchema = z15.object({
|
|
3676
3714
|
name: z15.string().min(1),
|
|
3677
3715
|
description: z15.string().min(1),
|
|
3678
3716
|
currentPainPoints: z15.array(z15.string()),
|
|
3679
3717
|
targetOutcome: z15.string().min(1),
|
|
3680
|
-
kpis: z15.array(z15.string())
|
|
3718
|
+
kpis: z15.array(z15.string()),
|
|
3719
|
+
gap: z15.string().nullable().default(null),
|
|
3720
|
+
benefits: z15.array(operatingModelBenefitSchema).min(1).nullable().default(null)
|
|
3681
3721
|
});
|
|
3682
3722
|
var operatingModelOrgElementSchema = z15.object({
|
|
3683
3723
|
element: z15.string().min(1),
|
|
@@ -3717,8 +3757,11 @@ var operatingModelTransformationPrioritySchema = z15.object({
|
|
|
3717
3757
|
impact: z15.enum(PRIORITY_RATING_LEVELS),
|
|
3718
3758
|
effort: z15.enum(PRIORITY_RATING_LEVELS),
|
|
3719
3759
|
readiness: z15.enum(PRIORITY_RATING_LEVELS),
|
|
3760
|
+
// Displayed as "Evidence" in the UI; JSON key kept for stored-analysis
|
|
3761
|
+
// back-compat.
|
|
3720
3762
|
confidence: z15.enum(PRIORITY_RATING_LEVELS),
|
|
3721
|
-
quickWin: z15.boolean()
|
|
3763
|
+
quickWin: z15.boolean(),
|
|
3764
|
+
whyThisApproach: z15.string().nullable().default(null)
|
|
3722
3765
|
});
|
|
3723
3766
|
var ERP_GAP_DIMENSIONS = [
|
|
3724
3767
|
"processes",
|
|
@@ -3793,6 +3836,11 @@ var operatingModelAnalysisSchema = z15.object({
|
|
|
3793
3836
|
erpTransformationInsights: operatingModelErpInsightsSchema.nullable().default(null),
|
|
3794
3837
|
objectionsAndChangeManagement: operatingModelObjectionsSchema.nullable().default(null),
|
|
3795
3838
|
businessCase: z15.string().nullable(),
|
|
3839
|
+
transformationGoal: z15.object({
|
|
3840
|
+
objective: z15.string().min(1),
|
|
3841
|
+
targetEndState: z15.string().min(1),
|
|
3842
|
+
expectedBenefits: z15.array(operatingModelBenefitSchema).min(1)
|
|
3843
|
+
}).nullable().default(null),
|
|
3796
3844
|
generatedAt: z15.string()
|
|
3797
3845
|
});
|
|
3798
3846
|
var portfolioProcessLinkSchema = z15.object({
|
|
@@ -6601,7 +6649,7 @@ var backgroundJobNotificationSchema = z25.object({
|
|
|
6601
6649
|
jobType: backgroundJobTypeSchema,
|
|
6602
6650
|
outcome: z25.enum(BACKGROUND_JOB_OUTCOMES),
|
|
6603
6651
|
sourceId: z25.guid(),
|
|
6604
|
-
processId: z25.string().nullable()
|
|
6652
|
+
processId: z25.string().nullable().default(null)
|
|
6605
6653
|
});
|
|
6606
6654
|
var RECONNECT_BROKEN_REASONS = [
|
|
6607
6655
|
"oauth_grant_revoked",
|
|
@@ -6632,6 +6680,20 @@ var notificationSchema = z25.discriminatedUnion("type", [
|
|
|
6632
6680
|
connectionBrokenNotificationSchema,
|
|
6633
6681
|
scheduleIssueNotificationSchema
|
|
6634
6682
|
]);
|
|
6683
|
+
var fallbackNotificationSchema = z25.object({
|
|
6684
|
+
...notificationBaseShape,
|
|
6685
|
+
type: z25.string(),
|
|
6686
|
+
fallback: z25.literal(true)
|
|
6687
|
+
});
|
|
6688
|
+
var notificationWireSchema = z25.union([
|
|
6689
|
+
notificationSchema,
|
|
6690
|
+
fallbackNotificationSchema
|
|
6691
|
+
]);
|
|
6692
|
+
function isFallbackNotification(n) {
|
|
6693
|
+
return "fallback" in n && n.fallback === true;
|
|
6694
|
+
}
|
|
6695
|
+
__name(isFallbackNotification, "isFallbackNotification");
|
|
6696
|
+
__name2(isFallbackNotification, "isFallbackNotification");
|
|
6635
6697
|
var NOTIFICATION_LIST_DEFAULT_LIMIT = 30;
|
|
6636
6698
|
var NOTIFICATION_LIST_MAX_LIMIT = 100;
|
|
6637
6699
|
var notificationListQuerySchema = z25.object({
|
|
@@ -6642,7 +6704,7 @@ var notificationListQuerySchema = z25.object({
|
|
|
6642
6704
|
cursor: z25.string().optional()
|
|
6643
6705
|
});
|
|
6644
6706
|
var notificationListResponseSchema = z25.object({
|
|
6645
|
-
items: z25.array(
|
|
6707
|
+
items: z25.array(notificationWireSchema),
|
|
6646
6708
|
nextCursor: z25.string().nullable()
|
|
6647
6709
|
});
|
|
6648
6710
|
var notificationUnreadCountResponseSchema = z25.object({
|
|
@@ -6669,8 +6731,14 @@ var agentNotificationSettingsResponseSchema = z25.object({
|
|
|
6669
6731
|
});
|
|
6670
6732
|
var notificationsRoomPayloadSchema = z26.object({ userId: z26.guid() });
|
|
6671
6733
|
var notificationsEventPayloadSchema = z26.discriminatedUnion("type", [
|
|
6672
|
-
z26.object({
|
|
6673
|
-
|
|
6734
|
+
z26.object({
|
|
6735
|
+
type: z26.literal("created"),
|
|
6736
|
+
notification: notificationWireSchema
|
|
6737
|
+
}),
|
|
6738
|
+
z26.object({
|
|
6739
|
+
type: z26.literal("updated"),
|
|
6740
|
+
notification: notificationWireSchema
|
|
6741
|
+
}),
|
|
6674
6742
|
z26.object({ type: z26.literal("deleted"), notificationId: z26.guid() }),
|
|
6675
6743
|
z26.object({ type: z26.literal("bulk_read") }),
|
|
6676
6744
|
z26.object({ type: z26.literal("bulk_deleted") }),
|
|
@@ -8120,10 +8188,18 @@ var adminDreamEditReferenceSchema = z38.object({
|
|
|
8120
8188
|
source_refs: z38.array(memorySourceRefSchema),
|
|
8121
8189
|
created_at: z38.string()
|
|
8122
8190
|
});
|
|
8191
|
+
var adminDreamTraceEntrySchema = z38.object({
|
|
8192
|
+
type: z38.string().max(128),
|
|
8193
|
+
role: z38.string().max(64).optional(),
|
|
8194
|
+
toolName: z38.string().max(512).optional(),
|
|
8195
|
+
contentPreview: z38.string().max(2e3).optional(),
|
|
8196
|
+
ts: z38.string()
|
|
8197
|
+
});
|
|
8123
8198
|
var adminDreamingRunDetailSchema = adminDreamingRunSummarySchema.extend({
|
|
8124
8199
|
input: z38.record(z38.string(), z38.unknown()),
|
|
8125
8200
|
resolvedInputs: z38.array(adminDreamResolvedInputSchema),
|
|
8126
|
-
editReferences: z38.array(adminDreamEditReferenceSchema)
|
|
8201
|
+
editReferences: z38.array(adminDreamEditReferenceSchema),
|
|
8202
|
+
sessionTrace: z38.array(adminDreamTraceEntrySchema)
|
|
8127
8203
|
});
|
|
8128
8204
|
var adminDreamingRunDetailResponseSchema = z38.object({
|
|
8129
8205
|
dream: adminDreamingRunDetailSchema
|
|
@@ -9698,12 +9774,19 @@ var humanRequestContextSchema = z59.discriminatedUnion("kind", [
|
|
|
9698
9774
|
caseTitle: z59.string()
|
|
9699
9775
|
})
|
|
9700
9776
|
]);
|
|
9777
|
+
var casePrioritySchema = z60.enum([
|
|
9778
|
+
CASE_PRIORITY.NONE,
|
|
9779
|
+
CASE_PRIORITY.MEDIUM,
|
|
9780
|
+
CASE_PRIORITY.HIGH
|
|
9781
|
+
]);
|
|
9701
9782
|
var caseQueueItemSchema = z60.object({
|
|
9702
9783
|
id: z60.guid(),
|
|
9703
9784
|
queue_id: z60.guid(),
|
|
9704
9785
|
title: z60.string(),
|
|
9705
9786
|
data: z60.string(),
|
|
9706
9787
|
status: z60.enum(["pending", "completed", "failed"]),
|
|
9788
|
+
/** Case priority level. `none` = default (no priority). */
|
|
9789
|
+
priority: casePrioritySchema,
|
|
9707
9790
|
/**
|
|
9708
9791
|
* Derived display bucket combining the settlement status with ownership,
|
|
9709
9792
|
* open HITL tokens, and scheduling. See CASE_DISPLAY_STATUS in
|
|
@@ -9798,6 +9881,9 @@ var caseCreateInputSchema = z60.object({
|
|
|
9798
9881
|
})
|
|
9799
9882
|
).max(50).optional().describe(
|
|
9800
9883
|
"Optional labels to assign to the case at creation. Labels are created on the queue if they don't already exist."
|
|
9884
|
+
),
|
|
9885
|
+
priority: casePrioritySchema.optional().describe(
|
|
9886
|
+
"Case priority. `medium` or `high` raise the case above the default in the queue; omit (or `none`) for normal priority. Only set this when the AOP or the user explicitly instructs prioritization \u2014 do not infer it on your own."
|
|
9801
9887
|
)
|
|
9802
9888
|
});
|
|
9803
9889
|
var caseCreateRequestSchema = z60.object({
|
|
@@ -9921,6 +10007,10 @@ var caseBulkStatusUpdateResponseSchema = z60.object({
|
|
|
9921
10007
|
skippedCount: z60.number(),
|
|
9922
10008
|
interruptedRunIds: z60.array(z60.guid())
|
|
9923
10009
|
});
|
|
10010
|
+
var caseBulkPriorityUpdateResponseSchema = z60.object({
|
|
10011
|
+
updatedCount: z60.number(),
|
|
10012
|
+
skippedCount: z60.number()
|
|
10013
|
+
});
|
|
9924
10014
|
var deleteQueueResponseSchema = z60.object({
|
|
9925
10015
|
success: z60.boolean(),
|
|
9926
10016
|
deleted_case_count: z60.number(),
|
|
@@ -10009,7 +10099,9 @@ var exportCasesResponseSchema = z60.object({
|
|
|
10009
10099
|
cases: z60.array(
|
|
10010
10100
|
z60.object({
|
|
10011
10101
|
title: z60.string(),
|
|
10012
|
-
data: z60.string().optional()
|
|
10102
|
+
data: z60.string().optional(),
|
|
10103
|
+
/** Priority level; omitted for default (`none`) priority cases. */
|
|
10104
|
+
priority: casePrioritySchema.optional()
|
|
10013
10105
|
})
|
|
10014
10106
|
)
|
|
10015
10107
|
});
|
|
@@ -11401,6 +11493,7 @@ function canonicalizeSopInput(config) {
|
|
|
11401
11493
|
}
|
|
11402
11494
|
__name(canonicalizeSopInput, "canonicalizeSopInput");
|
|
11403
11495
|
__name2(canonicalizeSopInput, "canonicalizeSopInput");
|
|
11496
|
+
var casePriorityFilterSchema = casePrioritySchema;
|
|
11404
11497
|
var caseFilterStatusSchema = z81.enum([
|
|
11405
11498
|
"pending",
|
|
11406
11499
|
"claimed",
|
|
@@ -11411,6 +11504,7 @@ var caseFilterStatusSchema = z81.enum([
|
|
|
11411
11504
|
]);
|
|
11412
11505
|
var casesFiltersSchema = z81.object({
|
|
11413
11506
|
status: z81.array(caseFilterStatusSchema).optional(),
|
|
11507
|
+
priority: z81.array(casePriorityFilterSchema).optional(),
|
|
11414
11508
|
created_at_from: z81.string().optional(),
|
|
11415
11509
|
updated_at_from: z81.string().optional(),
|
|
11416
11510
|
labels: z81.record(z81.string(), z81.array(z81.string())).optional()
|
|
@@ -11496,6 +11590,9 @@ function getFilterValuesByCategoryKey(filters, categoryKey) {
|
|
|
11496
11590
|
if (categoryKey === "status") {
|
|
11497
11591
|
return filters.status ?? [];
|
|
11498
11592
|
}
|
|
11593
|
+
if (categoryKey === "priority") {
|
|
11594
|
+
return filters.priority ?? [];
|
|
11595
|
+
}
|
|
11499
11596
|
if (categoryKey === "created_at_from") {
|
|
11500
11597
|
return filters.created_at_from ? [filters.created_at_from] : [];
|
|
11501
11598
|
}
|
|
@@ -11522,6 +11619,17 @@ function setFilterValuesByCategoryKey(filters, categoryKey, values) {
|
|
|
11522
11619
|
}
|
|
11523
11620
|
return { ...filters, status: parsed.data };
|
|
11524
11621
|
}
|
|
11622
|
+
if (categoryKey === "priority") {
|
|
11623
|
+
if (values.length === 0) {
|
|
11624
|
+
const { priority: _, ...rest } = filters;
|
|
11625
|
+
return rest;
|
|
11626
|
+
}
|
|
11627
|
+
const parsed = z81.array(casePriorityFilterSchema).safeParse(values);
|
|
11628
|
+
if (!parsed.success) {
|
|
11629
|
+
return filters;
|
|
11630
|
+
}
|
|
11631
|
+
return { ...filters, priority: parsed.data };
|
|
11632
|
+
}
|
|
11525
11633
|
if (categoryKey === "created_at_from") {
|
|
11526
11634
|
if (values.length === 0 || !values[0]) {
|
|
11527
11635
|
const { created_at_from: _, ...rest } = filters;
|
|
@@ -11560,7 +11668,7 @@ function removeFilterByCategoryKey(filters, categoryKey) {
|
|
|
11560
11668
|
__name(removeFilterByCategoryKey, "removeFilterByCategoryKey");
|
|
11561
11669
|
__name2(removeFilterByCategoryKey, "removeFilterByCategoryKey");
|
|
11562
11670
|
function isCasesFiltersEmpty(filters) {
|
|
11563
|
-
return !filters.status?.length && !filters.created_at_from && !filters.updated_at_from && (!filters.labels || Object.keys(filters.labels).length === 0);
|
|
11671
|
+
return !filters.status?.length && !filters.priority?.length && !filters.created_at_from && !filters.updated_at_from && (!filters.labels || Object.keys(filters.labels).length === 0);
|
|
11564
11672
|
}
|
|
11565
11673
|
__name(isCasesFiltersEmpty, "isCasesFiltersEmpty");
|
|
11566
11674
|
__name2(isCasesFiltersEmpty, "isCasesFiltersEmpty");
|
|
@@ -11569,6 +11677,9 @@ function countCasesFilters(filters) {
|
|
|
11569
11677
|
if (filters.status?.length) {
|
|
11570
11678
|
count += 1;
|
|
11571
11679
|
}
|
|
11680
|
+
if (filters.priority?.length) {
|
|
11681
|
+
count += 1;
|
|
11682
|
+
}
|
|
11572
11683
|
if (filters.created_at_from) {
|
|
11573
11684
|
count += 1;
|
|
11574
11685
|
}
|
|
@@ -12280,6 +12391,7 @@ var green = /* @__PURE__ */ __name((text3) => wrap(ANSI.green, text3), "green");
|
|
|
12280
12391
|
var red = /* @__PURE__ */ __name((text3) => wrap(ANSI.red, text3), "red");
|
|
12281
12392
|
var cyan = /* @__PURE__ */ __name((text3) => wrap(ANSI.cyan, text3), "cyan");
|
|
12282
12393
|
var bold = /* @__PURE__ */ __name((text3) => wrap(ANSI.bold, text3), "bold");
|
|
12394
|
+
var dim = /* @__PURE__ */ __name((text3) => wrap(ANSI.dim, text3), "dim");
|
|
12283
12395
|
var yellow = /* @__PURE__ */ __name((text3) => wrap(ANSI.yellow, text3), "yellow");
|
|
12284
12396
|
|
|
12285
12397
|
// src/output/deprecation-notice.ts
|
|
@@ -17345,6 +17457,62 @@ function registerCasesBulkReprocess(cases) {
|
|
|
17345
17457
|
}
|
|
17346
17458
|
__name(registerCasesBulkReprocess, "registerCasesBulkReprocess");
|
|
17347
17459
|
|
|
17460
|
+
// src/commands/cases/bulk-update-priority.ts
|
|
17461
|
+
function registerCasesBulkUpdatePriority(cases) {
|
|
17462
|
+
cases.command("bulk-update-priority").description(
|
|
17463
|
+
"Set the priority of multiple cases (1-100). Due postponed cases are picked up first; otherwise higher priority is picked up first. Use 'none' to clear."
|
|
17464
|
+
).requiredOption("--queue <id>", "ID of the queue the cases belong to").requiredOption("--ids <list>", "comma-separated case IDs (1-100)").requiredOption(
|
|
17465
|
+
"--priority <level>",
|
|
17466
|
+
`priority level (${casePrioritySchema.options.join(", ")})`
|
|
17467
|
+
).option("-y, --yes", "skip confirmation prompt").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function bulkUpdatePriorityAction(options) {
|
|
17468
|
+
const caseIds = parseCaseIds(options.ids);
|
|
17469
|
+
const priority = parsePriority(options.priority);
|
|
17470
|
+
const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
|
|
17471
|
+
await confirmDestructive({
|
|
17472
|
+
message: `Set the priority of ${caseIds.length} case(s) in queue "${options.queue}" to "${priority}"?`,
|
|
17473
|
+
skip: Boolean(options.yes)
|
|
17474
|
+
});
|
|
17475
|
+
const raw = await httpRequest({
|
|
17476
|
+
method: "POST",
|
|
17477
|
+
path: `/v2/queues/${encodeURIComponent(options.queue)}/cases/bulk-update-priority`,
|
|
17478
|
+
apiKey,
|
|
17479
|
+
apiBaseUrl,
|
|
17480
|
+
body: { case_ids: caseIds, priority }
|
|
17481
|
+
});
|
|
17482
|
+
if (options.json) {
|
|
17483
|
+
printJson(raw);
|
|
17484
|
+
return;
|
|
17485
|
+
}
|
|
17486
|
+
const parsed = caseBulkPriorityUpdateResponseSchema.safeParse(raw);
|
|
17487
|
+
if (!parsed.success) {
|
|
17488
|
+
throw new CliError(
|
|
17489
|
+
`Unexpected response from the API: ${parsed.error.message}`
|
|
17490
|
+
);
|
|
17491
|
+
}
|
|
17492
|
+
const result = parsed.data;
|
|
17493
|
+
console.log(green("Bulk priority update complete."));
|
|
17494
|
+
console.log();
|
|
17495
|
+
console.log(
|
|
17496
|
+
renderKeyValue([
|
|
17497
|
+
{ label: "Updated", value: String(result.updatedCount) },
|
|
17498
|
+
{ label: "Skipped", value: String(result.skippedCount) }
|
|
17499
|
+
])
|
|
17500
|
+
);
|
|
17501
|
+
}, "bulkUpdatePriorityAction"));
|
|
17502
|
+
}
|
|
17503
|
+
__name(registerCasesBulkUpdatePriority, "registerCasesBulkUpdatePriority");
|
|
17504
|
+
function parsePriority(raw) {
|
|
17505
|
+
if (!casePrioritySchema.options.includes(
|
|
17506
|
+
raw
|
|
17507
|
+
)) {
|
|
17508
|
+
throw new CliError(
|
|
17509
|
+
`Invalid --priority value "${raw}". Allowed: ${casePrioritySchema.options.join(", ")}.`
|
|
17510
|
+
);
|
|
17511
|
+
}
|
|
17512
|
+
return raw;
|
|
17513
|
+
}
|
|
17514
|
+
__name(parsePriority, "parsePriority");
|
|
17515
|
+
|
|
17348
17516
|
// src/commands/cases/bulk-update-status.ts
|
|
17349
17517
|
var CASE_TERMINAL_STATUSES = ["completed", "failed"];
|
|
17350
17518
|
function registerCasesBulkUpdateStatus(cases) {
|
|
@@ -17503,6 +17671,9 @@ function registerCasesCreate(cases) {
|
|
|
17503
17671
|
cases.command("create").description(
|
|
17504
17672
|
"Create one or more cases in a queue. Provide --title for one case or --from-file with a JSON array for many."
|
|
17505
17673
|
).requiredOption("--queue <id>", "ID of the queue to create cases in").option("--title <text>", "case title (max 500 chars)").option("--data <text>", "free-form data passed to the assignment on claim").option(
|
|
17674
|
+
"--priority <level>",
|
|
17675
|
+
`case priority (${casePrioritySchema.options.join(", ")}); only set when instructed`
|
|
17676
|
+
).option(
|
|
17506
17677
|
"--label <key=value>",
|
|
17507
17678
|
"label to assign to the case (omit key for a simple tag, repeat for multiple)",
|
|
17508
17679
|
collectLabel,
|
|
@@ -17547,9 +17718,9 @@ function collectLabel(value, previous) {
|
|
|
17547
17718
|
__name(collectLabel, "collectLabel");
|
|
17548
17719
|
async function buildRequestBody(options) {
|
|
17549
17720
|
if (options.fromFile !== void 0) {
|
|
17550
|
-
if (options.title !== void 0 || options.data !== void 0 || (options.label?.length ?? 0) > 0) {
|
|
17721
|
+
if (options.title !== void 0 || options.data !== void 0 || options.priority !== void 0 || (options.label?.length ?? 0) > 0) {
|
|
17551
17722
|
throw new CliError(
|
|
17552
|
-
"--from-file cannot be combined with --title, --data, or --label."
|
|
17723
|
+
"--from-file cannot be combined with --title, --data, --priority, or --label."
|
|
17553
17724
|
);
|
|
17554
17725
|
}
|
|
17555
17726
|
return readCasesFromFile(options.fromFile);
|
|
@@ -17565,9 +17736,22 @@ async function buildRequestBody(options) {
|
|
|
17565
17736
|
if (labels) {
|
|
17566
17737
|
single.labels = labels;
|
|
17567
17738
|
}
|
|
17739
|
+
if (options.priority !== void 0) {
|
|
17740
|
+
single.priority = parsePriority2(options.priority, "--priority");
|
|
17741
|
+
}
|
|
17568
17742
|
return { case: single };
|
|
17569
17743
|
}
|
|
17570
17744
|
__name(buildRequestBody, "buildRequestBody");
|
|
17745
|
+
function parsePriority2(raw, location) {
|
|
17746
|
+
const parsed = casePrioritySchema.safeParse(raw);
|
|
17747
|
+
if (!parsed.success) {
|
|
17748
|
+
throw new CliError(
|
|
17749
|
+
`Invalid ${location} value "${raw}". Allowed: ${casePrioritySchema.options.join(", ")}.`
|
|
17750
|
+
);
|
|
17751
|
+
}
|
|
17752
|
+
return parsed.data;
|
|
17753
|
+
}
|
|
17754
|
+
__name(parsePriority2, "parsePriority");
|
|
17571
17755
|
async function readCasesFromFile(path) {
|
|
17572
17756
|
let raw;
|
|
17573
17757
|
try {
|
|
@@ -17627,6 +17811,12 @@ function coerceCase(value, location) {
|
|
|
17627
17811
|
(l, i) => coerceLabel(l, `${location}.labels[${i}]`)
|
|
17628
17812
|
);
|
|
17629
17813
|
}
|
|
17814
|
+
if (obj.priority !== void 0) {
|
|
17815
|
+
if (typeof obj.priority !== "string") {
|
|
17816
|
+
throw new CliError(`${location}.priority must be a string when present.`);
|
|
17817
|
+
}
|
|
17818
|
+
out.priority = parsePriority2(obj.priority, `${location}.priority`);
|
|
17819
|
+
}
|
|
17630
17820
|
return out;
|
|
17631
17821
|
}
|
|
17632
17822
|
__name(coerceCase, "coerceCase");
|
|
@@ -17964,12 +18154,16 @@ var TABLE_COLUMNS18 = [
|
|
|
17964
18154
|
{ header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
|
|
17965
18155
|
{ header: "TITLE", cell: /* @__PURE__ */ __name((row) => row.title, "cell"), maxWidth: 50 },
|
|
17966
18156
|
{ header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.display_status, "cell") },
|
|
18157
|
+
{ header: "PRIORITY", cell: /* @__PURE__ */ __name((row) => row.priority, "cell") },
|
|
17967
18158
|
{ header: "CREATED", cell: /* @__PURE__ */ __name((row) => row.created_at ?? "", "cell") }
|
|
17968
18159
|
];
|
|
17969
18160
|
function registerCasesList(cases) {
|
|
17970
18161
|
cases.command("list", { isDefault: true }).description("List cases in a queue").requiredOption("--queue <id>", "ID of the queue to list cases for").option("--limit <n>", `page size (${MIN_LIMIT3}-${MAX_LIMIT3})`).option("--offset <n>", "number of cases to skip").option(
|
|
17971
18162
|
"--status <statuses>",
|
|
17972
18163
|
`comma-separated case statuses (${caseFilterStatusSchema.options.join(", ")})`
|
|
18164
|
+
).option(
|
|
18165
|
+
"--priority <levels>",
|
|
18166
|
+
`comma-separated priority levels (${casePriorityFilterSchema.options.join(", ")})`
|
|
17973
18167
|
).option("--search <text>", "full-text search across title and data").option(
|
|
17974
18168
|
"--created-at-from <iso>",
|
|
17975
18169
|
"include cases created on or after this ISO-8601 timestamp"
|
|
@@ -17987,6 +18181,7 @@ function registerCasesList(cases) {
|
|
|
17987
18181
|
});
|
|
17988
18182
|
const offset = parseOffset(options.offset);
|
|
17989
18183
|
const statuses = parseStatuses(options.status);
|
|
18184
|
+
const priorities = parsePriorities(options.priority);
|
|
17990
18185
|
const sortBy = parseSortBy(options.sortBy);
|
|
17991
18186
|
const sortOrder = parseSortOrder(options.sortOrder);
|
|
17992
18187
|
const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
|
|
@@ -17996,6 +18191,9 @@ function registerCasesList(cases) {
|
|
|
17996
18191
|
if (statuses) {
|
|
17997
18192
|
searchParams.append("status", statuses.join(","));
|
|
17998
18193
|
}
|
|
18194
|
+
if (priorities) {
|
|
18195
|
+
searchParams.append("priority", priorities.join(","));
|
|
18196
|
+
}
|
|
17999
18197
|
if (options.search !== void 0) {
|
|
18000
18198
|
searchParams.append("search", options.search);
|
|
18001
18199
|
}
|
|
@@ -18061,6 +18259,26 @@ function parseStatuses(raw) {
|
|
|
18061
18259
|
return parts;
|
|
18062
18260
|
}
|
|
18063
18261
|
__name(parseStatuses, "parseStatuses");
|
|
18262
|
+
function parsePriorities(raw) {
|
|
18263
|
+
if (raw === void 0) {
|
|
18264
|
+
return void 0;
|
|
18265
|
+
}
|
|
18266
|
+
const parts = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
18267
|
+
if (parts.length === 0) {
|
|
18268
|
+
throw new CliError(
|
|
18269
|
+
`Invalid --priority value "${raw}". Allowed: ${casePriorityFilterSchema.options.join(", ")}.`
|
|
18270
|
+
);
|
|
18271
|
+
}
|
|
18272
|
+
const allowed = new Set(casePriorityFilterSchema.options);
|
|
18273
|
+
const invalid = parts.filter((p) => !allowed.has(p));
|
|
18274
|
+
if (invalid.length > 0) {
|
|
18275
|
+
throw new CliError(
|
|
18276
|
+
`Invalid --priority value(s): ${invalid.join(", ")}. Allowed: ${casePriorityFilterSchema.options.join(", ")}.`
|
|
18277
|
+
);
|
|
18278
|
+
}
|
|
18279
|
+
return parts;
|
|
18280
|
+
}
|
|
18281
|
+
__name(parsePriorities, "parsePriorities");
|
|
18064
18282
|
function parseSortBy(raw) {
|
|
18065
18283
|
if (raw === void 0) {
|
|
18066
18284
|
return void 0;
|
|
@@ -18238,6 +18456,7 @@ function registerCases(program) {
|
|
|
18238
18456
|
registerCasesBulkDelete(cases);
|
|
18239
18457
|
registerCasesBulkReprocess(cases);
|
|
18240
18458
|
registerCasesBulkUpdateStatus(cases);
|
|
18459
|
+
registerCasesBulkUpdatePriority(cases);
|
|
18241
18460
|
registerCasesRuns(cases);
|
|
18242
18461
|
registerCasesLabels(cases);
|
|
18243
18462
|
}
|
|
@@ -31186,15 +31405,128 @@ function registerTeam(program) {
|
|
|
31186
31405
|
}
|
|
31187
31406
|
__name(registerTeam, "registerTeam");
|
|
31188
31407
|
|
|
31189
|
-
// src/commands/teams/
|
|
31408
|
+
// src/commands/teams/create-org-team.ts
|
|
31190
31409
|
import { z as z113 } from "zod";
|
|
31191
|
-
var
|
|
31192
|
-
id: z113.
|
|
31193
|
-
name: z113.string()
|
|
31194
|
-
|
|
31410
|
+
var createOrgTeamResponseSchema = z113.object({
|
|
31411
|
+
id: z113.guid(),
|
|
31412
|
+
name: z113.string()
|
|
31413
|
+
});
|
|
31414
|
+
function registerTeamsCreateOrgTeam(teams) {
|
|
31415
|
+
teams.command("create-org-team <org-id>").description("Create a new team inside an organization you administer").requiredOption("--name <name>", "team name").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function createOrgTeamAction(orgId, options) {
|
|
31416
|
+
if (options.name === void 0 || options.name.trim().length === 0) {
|
|
31417
|
+
throw new CliError("--name must not be empty");
|
|
31418
|
+
}
|
|
31419
|
+
const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
|
|
31420
|
+
const raw = await httpRequest({
|
|
31421
|
+
method: "POST",
|
|
31422
|
+
path: `/v2/organizations/${encodeURIComponent(orgId)}/teams`,
|
|
31423
|
+
apiKey,
|
|
31424
|
+
apiBaseUrl,
|
|
31425
|
+
body: { name: options.name.trim() }
|
|
31426
|
+
});
|
|
31427
|
+
if (options.json) {
|
|
31428
|
+
printJson(raw);
|
|
31429
|
+
return;
|
|
31430
|
+
}
|
|
31431
|
+
const parsed = createOrgTeamResponseSchema.safeParse(raw);
|
|
31432
|
+
if (!parsed.success) {
|
|
31433
|
+
throw new CliError(
|
|
31434
|
+
`Unexpected response from POST /v2/organizations/:orgId/teams: ${parsed.error.message}`
|
|
31435
|
+
);
|
|
31436
|
+
}
|
|
31437
|
+
console.log(green("Team created!"));
|
|
31438
|
+
console.log();
|
|
31439
|
+
console.log(
|
|
31440
|
+
renderKeyValue([
|
|
31441
|
+
{ label: "ID", value: parsed.data.id },
|
|
31442
|
+
{ label: "Name", value: parsed.data.name }
|
|
31443
|
+
])
|
|
31444
|
+
);
|
|
31445
|
+
}, "createOrgTeamAction"));
|
|
31446
|
+
}
|
|
31447
|
+
__name(registerTeamsCreateOrgTeam, "registerTeamsCreateOrgTeam");
|
|
31448
|
+
|
|
31449
|
+
// src/commands/teams/invite-org-member.ts
|
|
31450
|
+
var ORG_ROLES2 = Object.values(ORG_ROLE);
|
|
31451
|
+
var DEFAULT_ROLE = ORG_ROLE.MEMBER;
|
|
31452
|
+
function registerTeamsInviteOrgMember(teams) {
|
|
31453
|
+
teams.command("invite-org-member <org-id>").description(
|
|
31454
|
+
"Invite a person to an organization, optionally onto one of its teams"
|
|
31455
|
+
).requiredOption("--email <email>", "email address of the person to invite").option(
|
|
31456
|
+
"--role <role>",
|
|
31457
|
+
`organization role to grant: ${ORG_ROLES2.join(", ")} (default ${DEFAULT_ROLE})`,
|
|
31458
|
+
DEFAULT_ROLE
|
|
31459
|
+
).option("--team-id <id>", "assign the invitee to this team in the org").option(
|
|
31460
|
+
"--frontend-url <url>",
|
|
31461
|
+
"base URL used to build the invitation email link (email is skipped if omitted)"
|
|
31462
|
+
).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function inviteOrgMemberAction(orgId, options) {
|
|
31463
|
+
const email = options.email?.trim();
|
|
31464
|
+
if (email === void 0 || email.length === 0) {
|
|
31465
|
+
throw new CliError("--email must not be empty");
|
|
31466
|
+
}
|
|
31467
|
+
const role = options.role ?? DEFAULT_ROLE;
|
|
31468
|
+
if (!ORG_ROLES2.includes(role)) {
|
|
31469
|
+
throw new CliError(
|
|
31470
|
+
`Invalid --role "${role}"; expected one of: ${ORG_ROLES2.join(", ")}`
|
|
31471
|
+
);
|
|
31472
|
+
}
|
|
31473
|
+
const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
|
|
31474
|
+
const body = { email, role };
|
|
31475
|
+
if (options.teamId !== void 0) {
|
|
31476
|
+
const teamId = options.teamId.trim();
|
|
31477
|
+
if (teamId.length === 0) {
|
|
31478
|
+
throw new CliError("--team-id must not be empty");
|
|
31479
|
+
}
|
|
31480
|
+
body.teamId = teamId;
|
|
31481
|
+
}
|
|
31482
|
+
if (options.frontendUrl !== void 0) {
|
|
31483
|
+
const frontendUrl = options.frontendUrl.trim();
|
|
31484
|
+
if (frontendUrl.length === 0) {
|
|
31485
|
+
throw new CliError("--frontend-url must not be empty");
|
|
31486
|
+
}
|
|
31487
|
+
body.frontendUrl = frontendUrl;
|
|
31488
|
+
}
|
|
31489
|
+
const raw = await httpRequest({
|
|
31490
|
+
method: "POST",
|
|
31491
|
+
path: `/v2/organizations/${encodeURIComponent(orgId)}/members`,
|
|
31492
|
+
apiKey,
|
|
31493
|
+
apiBaseUrl,
|
|
31494
|
+
body
|
|
31495
|
+
});
|
|
31496
|
+
if (options.json) {
|
|
31497
|
+
printJson(raw);
|
|
31498
|
+
return;
|
|
31499
|
+
}
|
|
31500
|
+
const parsed = inviteOrgMemberResponseSchema.safeParse(raw);
|
|
31501
|
+
if (!parsed.success) {
|
|
31502
|
+
throw new CliError(
|
|
31503
|
+
`Unexpected response from POST /v2/organizations/:orgId/members: ${parsed.error.message}`
|
|
31504
|
+
);
|
|
31505
|
+
}
|
|
31506
|
+
console.log(green("Invitation created!"));
|
|
31507
|
+
console.log();
|
|
31508
|
+
console.log(
|
|
31509
|
+
renderKeyValue([
|
|
31510
|
+
{ label: "Invitation ID", value: parsed.data.invitationId },
|
|
31511
|
+
{ label: "Email", value: email },
|
|
31512
|
+
{ label: "Role", value: role },
|
|
31513
|
+
{ label: "Team", value: body.teamId ?? "\u2014" },
|
|
31514
|
+
{ label: "Email sent", value: parsed.data.emailSent ? "yes" : "no" }
|
|
31515
|
+
])
|
|
31516
|
+
);
|
|
31517
|
+
}, "inviteOrgMemberAction"));
|
|
31518
|
+
}
|
|
31519
|
+
__name(registerTeamsInviteOrgMember, "registerTeamsInviteOrgMember");
|
|
31520
|
+
|
|
31521
|
+
// src/commands/teams/list.ts
|
|
31522
|
+
import { z as z114 } from "zod";
|
|
31523
|
+
var teamApiSchema2 = z114.object({
|
|
31524
|
+
id: z114.string(),
|
|
31525
|
+
name: z114.string(),
|
|
31526
|
+
organization_id: z114.string().nullable()
|
|
31195
31527
|
});
|
|
31196
|
-
var listMyTeamsResponseSchema3 =
|
|
31197
|
-
teams:
|
|
31528
|
+
var listMyTeamsResponseSchema3 = z114.object({
|
|
31529
|
+
teams: z114.array(teamApiSchema2)
|
|
31198
31530
|
});
|
|
31199
31531
|
function registerTeamsList(teams) {
|
|
31200
31532
|
teams.command("list", { isDefault: true }).description("List every team you can act on").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function listAction(options) {
|
|
@@ -31237,21 +31569,21 @@ function registerTeamsList(teams) {
|
|
|
31237
31569
|
__name(registerTeamsList, "registerTeamsList");
|
|
31238
31570
|
|
|
31239
31571
|
// src/commands/teams/org-insights.ts
|
|
31240
|
-
import { z as
|
|
31241
|
-
var headlineSchema =
|
|
31242
|
-
total_runs:
|
|
31243
|
-
completed_runs:
|
|
31244
|
-
failed_runs:
|
|
31245
|
-
success_rate:
|
|
31246
|
-
active_agents:
|
|
31247
|
-
active_users:
|
|
31248
|
-
start_date:
|
|
31249
|
-
end_date:
|
|
31250
|
-
truncated:
|
|
31251
|
-
aggregated_teams:
|
|
31252
|
-
total_teams:
|
|
31253
|
-
});
|
|
31254
|
-
var orgInsightsHeadlineResponseSchema =
|
|
31572
|
+
import { z as z115 } from "zod";
|
|
31573
|
+
var headlineSchema = z115.object({
|
|
31574
|
+
total_runs: z115.number(),
|
|
31575
|
+
completed_runs: z115.number(),
|
|
31576
|
+
failed_runs: z115.number(),
|
|
31577
|
+
success_rate: z115.number().nullable(),
|
|
31578
|
+
active_agents: z115.number(),
|
|
31579
|
+
active_users: z115.number(),
|
|
31580
|
+
start_date: z115.string(),
|
|
31581
|
+
end_date: z115.string(),
|
|
31582
|
+
truncated: z115.boolean(),
|
|
31583
|
+
aggregated_teams: z115.number(),
|
|
31584
|
+
total_teams: z115.number()
|
|
31585
|
+
});
|
|
31586
|
+
var orgInsightsHeadlineResponseSchema = z115.object({
|
|
31255
31587
|
headline: headlineSchema
|
|
31256
31588
|
});
|
|
31257
31589
|
function formatRate(rate) {
|
|
@@ -31319,26 +31651,26 @@ function registerTeamsOrgInsights(teams) {
|
|
|
31319
31651
|
__name(registerTeamsOrgInsights, "registerTeamsOrgInsights");
|
|
31320
31652
|
|
|
31321
31653
|
// src/commands/teams/org-metrics.ts
|
|
31322
|
-
import { z as
|
|
31323
|
-
var teamMetricSchema =
|
|
31324
|
-
team_id:
|
|
31325
|
-
team_name:
|
|
31326
|
-
is_deleted:
|
|
31327
|
-
member_count:
|
|
31328
|
-
assignment_count:
|
|
31329
|
-
scheduled_job_count:
|
|
31330
|
-
total_jobs:
|
|
31331
|
-
completed_jobs:
|
|
31332
|
-
failed_jobs:
|
|
31333
|
-
total_runs:
|
|
31334
|
-
});
|
|
31335
|
-
var orgInsightsMetricsResponseSchema =
|
|
31336
|
-
teams:
|
|
31337
|
-
start_date:
|
|
31338
|
-
end_date:
|
|
31339
|
-
truncated:
|
|
31340
|
-
total_teams:
|
|
31341
|
-
org_member_count:
|
|
31654
|
+
import { z as z116 } from "zod";
|
|
31655
|
+
var teamMetricSchema = z116.object({
|
|
31656
|
+
team_id: z116.string(),
|
|
31657
|
+
team_name: z116.string(),
|
|
31658
|
+
is_deleted: z116.boolean(),
|
|
31659
|
+
member_count: z116.number(),
|
|
31660
|
+
assignment_count: z116.number(),
|
|
31661
|
+
scheduled_job_count: z116.number(),
|
|
31662
|
+
total_jobs: z116.number(),
|
|
31663
|
+
completed_jobs: z116.number(),
|
|
31664
|
+
failed_jobs: z116.number(),
|
|
31665
|
+
total_runs: z116.number()
|
|
31666
|
+
});
|
|
31667
|
+
var orgInsightsMetricsResponseSchema = z116.object({
|
|
31668
|
+
teams: z116.array(teamMetricSchema),
|
|
31669
|
+
start_date: z116.string(),
|
|
31670
|
+
end_date: z116.string(),
|
|
31671
|
+
truncated: z116.boolean(),
|
|
31672
|
+
total_teams: z116.number(),
|
|
31673
|
+
org_member_count: z116.number()
|
|
31342
31674
|
});
|
|
31343
31675
|
function registerTeamsOrgMetrics(teams) {
|
|
31344
31676
|
teams.command("org-metrics <org-id>").description("Show per-team run metrics across an organization").option("--start-date <date>", "window start (ISO 8601, default 7d ago)").option("--end-date <date>", "window end (ISO 8601, default now)").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function orgMetricsAction(orgId, options) {
|
|
@@ -31401,20 +31733,20 @@ ${total_teams} teams${suffix} \xB7 ${org_member_count} org members`
|
|
|
31401
31733
|
__name(registerTeamsOrgMetrics, "registerTeamsOrgMetrics");
|
|
31402
31734
|
|
|
31403
31735
|
// src/commands/teams/org-usage.ts
|
|
31404
|
-
import { z as
|
|
31736
|
+
import { z as z117 } from "zod";
|
|
31405
31737
|
var GRANULARITIES = ["day", "week", "month"];
|
|
31406
31738
|
var DEFAULT_LOOKBACK_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
31407
|
-
var bucketSchema =
|
|
31408
|
-
period:
|
|
31409
|
-
total_runs:
|
|
31410
|
-
scheduled_runs:
|
|
31411
|
-
on_demand_runs:
|
|
31412
|
-
});
|
|
31413
|
-
var usageChartResponseSchema =
|
|
31414
|
-
buckets:
|
|
31415
|
-
granularity:
|
|
31416
|
-
truncated:
|
|
31417
|
-
total_teams:
|
|
31739
|
+
var bucketSchema = z117.object({
|
|
31740
|
+
period: z117.string(),
|
|
31741
|
+
total_runs: z117.number(),
|
|
31742
|
+
scheduled_runs: z117.number(),
|
|
31743
|
+
on_demand_runs: z117.number()
|
|
31744
|
+
});
|
|
31745
|
+
var usageChartResponseSchema = z117.object({
|
|
31746
|
+
buckets: z117.array(bucketSchema),
|
|
31747
|
+
granularity: z117.enum(GRANULARITIES),
|
|
31748
|
+
truncated: z117.boolean(),
|
|
31749
|
+
total_teams: z117.number()
|
|
31418
31750
|
});
|
|
31419
31751
|
function registerTeamsOrgUsage(teams) {
|
|
31420
31752
|
teams.command("org-usage <org-id>").description("Show org-wide run volume over time (scheduled vs on-demand)").option("--start-date <date>", "window start (ISO 8601, default 30d ago)").option("--end-date <date>", "window end (ISO 8601, default now)").option(
|
|
@@ -31473,17 +31805,17 @@ function registerTeamsOrgUsage(teams) {
|
|
|
31473
31805
|
__name(registerTeamsOrgUsage, "registerTeamsOrgUsage");
|
|
31474
31806
|
|
|
31475
31807
|
// src/commands/teams/org.ts
|
|
31476
|
-
import { z as
|
|
31477
|
-
var orgTeamSchema =
|
|
31478
|
-
id:
|
|
31479
|
-
name:
|
|
31480
|
-
userIsMember:
|
|
31481
|
-
userRole:
|
|
31482
|
-
memberCount:
|
|
31808
|
+
import { z as z118 } from "zod";
|
|
31809
|
+
var orgTeamSchema = z118.object({
|
|
31810
|
+
id: z118.string(),
|
|
31811
|
+
name: z118.string(),
|
|
31812
|
+
userIsMember: z118.boolean(),
|
|
31813
|
+
userRole: z118.string().nullable(),
|
|
31814
|
+
memberCount: z118.number()
|
|
31483
31815
|
});
|
|
31484
|
-
var listOrgTeamsResponseSchema =
|
|
31485
|
-
teams:
|
|
31486
|
-
total:
|
|
31816
|
+
var listOrgTeamsResponseSchema = z118.object({
|
|
31817
|
+
teams: z118.array(orgTeamSchema),
|
|
31818
|
+
total: z118.number()
|
|
31487
31819
|
});
|
|
31488
31820
|
function registerTeamsOrg(teams) {
|
|
31489
31821
|
teams.command("org <org-id>").description("List all teams in an organization you belong to").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function orgAction(orgId, options) {
|
|
@@ -31525,17 +31857,17 @@ function registerTeamsOrg(teams) {
|
|
|
31525
31857
|
__name(registerTeamsOrg, "registerTeamsOrg");
|
|
31526
31858
|
|
|
31527
31859
|
// src/commands/teams/orgs.ts
|
|
31528
|
-
import { z as
|
|
31529
|
-
var orgMembershipSchema =
|
|
31530
|
-
organization:
|
|
31531
|
-
id:
|
|
31532
|
-
name:
|
|
31860
|
+
import { z as z119 } from "zod";
|
|
31861
|
+
var orgMembershipSchema = z119.object({
|
|
31862
|
+
organization: z119.object({
|
|
31863
|
+
id: z119.string(),
|
|
31864
|
+
name: z119.string()
|
|
31533
31865
|
}),
|
|
31534
|
-
role:
|
|
31535
|
-
memberCount:
|
|
31866
|
+
role: z119.string(),
|
|
31867
|
+
memberCount: z119.number()
|
|
31536
31868
|
});
|
|
31537
|
-
var listMyOrganizationsResponseSchema =
|
|
31538
|
-
memberships:
|
|
31869
|
+
var listMyOrganizationsResponseSchema = z119.object({
|
|
31870
|
+
memberships: z119.array(orgMembershipSchema)
|
|
31539
31871
|
});
|
|
31540
31872
|
function registerTeamsOrgs(teams) {
|
|
31541
31873
|
teams.command("orgs").description("List the organizations you belong to and your role in each").option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function orgsAction(options) {
|
|
@@ -31581,141 +31913,448 @@ function registerTeams(program) {
|
|
|
31581
31913
|
registerTeamsList(teams);
|
|
31582
31914
|
registerTeamsOrg(teams);
|
|
31583
31915
|
registerTeamsOrgs(teams);
|
|
31916
|
+
registerTeamsCreateOrgTeam(teams);
|
|
31917
|
+
registerTeamsInviteOrgMember(teams);
|
|
31584
31918
|
registerTeamsOrgInsights(teams);
|
|
31585
31919
|
registerTeamsOrgMetrics(teams);
|
|
31586
31920
|
registerTeamsOrgUsage(teams);
|
|
31587
31921
|
}
|
|
31588
31922
|
__name(registerTeams, "registerTeams");
|
|
31589
31923
|
|
|
31590
|
-
// src/
|
|
31591
|
-
|
|
31592
|
-
|
|
31593
|
-
|
|
31594
|
-
|
|
31595
|
-
|
|
31596
|
-
|
|
31597
|
-
|
|
31598
|
-
|
|
31599
|
-
|
|
31600
|
-
|
|
31601
|
-
|
|
31602
|
-
|
|
31603
|
-
|
|
31604
|
-
|
|
31605
|
-
}
|
|
31606
|
-
const authTypeLabel = resolved.authType === "oauth" ? "OAuth" : "API key";
|
|
31607
|
-
console.log(`Auth type ${authTypeLabel}`);
|
|
31608
|
-
}, "whoamiAction"));
|
|
31924
|
+
// src/version/fetch-latest-binary-version.ts
|
|
31925
|
+
var CLI_RELEASES_BASE_URL = "https://storage.googleapis.com/duvo-cli-releases";
|
|
31926
|
+
var LATEST_POINTER_TIMEOUT_MS = 5e3;
|
|
31927
|
+
async function fetchLatestBinaryVersion() {
|
|
31928
|
+
const response = await fetch(`${CLI_RELEASES_BASE_URL}/latest`, {
|
|
31929
|
+
signal: AbortSignal.timeout(LATEST_POINTER_TIMEOUT_MS)
|
|
31930
|
+
});
|
|
31931
|
+
if (!response.ok) {
|
|
31932
|
+
throw new Error(`releases bucket responded with ${response.status}`);
|
|
31933
|
+
}
|
|
31934
|
+
const version2 = (await response.text()).trim().replace(/^v/, "");
|
|
31935
|
+
if (!/^\d+\.\d+\.\d+$/.test(version2)) {
|
|
31936
|
+
throw new Error(`releases bucket returned an invalid version: ${version2}`);
|
|
31937
|
+
}
|
|
31938
|
+
return version2;
|
|
31609
31939
|
}
|
|
31610
|
-
__name(
|
|
31611
|
-
|
|
31612
|
-
|
|
31613
|
-
|
|
31614
|
-
|
|
31615
|
-
|
|
31616
|
-
|
|
31617
|
-
|
|
31618
|
-
|
|
31619
|
-
|
|
31620
|
-
if (!parsed.success) {
|
|
31621
|
-
return null;
|
|
31940
|
+
__name(fetchLatestBinaryVersion, "fetchLatestBinaryVersion");
|
|
31941
|
+
|
|
31942
|
+
// src/version/fetch-latest-npm-version.ts
|
|
31943
|
+
var REGISTRY_TIMEOUT_MS = 5e3;
|
|
31944
|
+
async function fetchLatestNpmVersion(packageName, timeoutMs = REGISTRY_TIMEOUT_MS) {
|
|
31945
|
+
const response = await fetch(
|
|
31946
|
+
`https://registry.npmjs.org/-/package/${packageName}/dist-tags`,
|
|
31947
|
+
{
|
|
31948
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
31949
|
+
headers: { accept: "application/json" }
|
|
31622
31950
|
}
|
|
31623
|
-
|
|
31624
|
-
|
|
31625
|
-
|
|
31626
|
-
|
|
31951
|
+
);
|
|
31952
|
+
if (!response.ok) {
|
|
31953
|
+
throw new Error(`npm registry responded with ${response.status}`);
|
|
31954
|
+
}
|
|
31955
|
+
const body = await response.json();
|
|
31956
|
+
if (body === null || typeof body !== "object" || typeof body.latest !== "string") {
|
|
31957
|
+
throw new Error("npm registry response is missing the latest dist-tag");
|
|
31627
31958
|
}
|
|
31959
|
+
return body.latest;
|
|
31628
31960
|
}
|
|
31629
|
-
__name(
|
|
31630
|
-
|
|
31631
|
-
|
|
31632
|
-
|
|
31633
|
-
|
|
31961
|
+
__name(fetchLatestNpmVersion, "fetchLatestNpmVersion");
|
|
31962
|
+
|
|
31963
|
+
// src/version/is-newer-version.ts
|
|
31964
|
+
function isSafeNumericIdentifier(value) {
|
|
31965
|
+
return Number(value) <= Number.MAX_SAFE_INTEGER;
|
|
31966
|
+
}
|
|
31967
|
+
__name(isSafeNumericIdentifier, "isSafeNumericIdentifier");
|
|
31968
|
+
function parseVersion(version2) {
|
|
31969
|
+
const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?$/.exec(
|
|
31970
|
+
version2.trim()
|
|
31971
|
+
);
|
|
31972
|
+
if (!match) {
|
|
31973
|
+
return null;
|
|
31974
|
+
}
|
|
31975
|
+
const prerelease = match[4] ? match[4].split(".") : [];
|
|
31976
|
+
const numericIdentifiers = [
|
|
31977
|
+
match[1],
|
|
31978
|
+
match[2],
|
|
31979
|
+
match[3],
|
|
31980
|
+
...prerelease.filter((identifier) => /^\d+$/.test(identifier))
|
|
31981
|
+
];
|
|
31982
|
+
if (!numericIdentifiers.every(isSafeNumericIdentifier)) {
|
|
31634
31983
|
return null;
|
|
31635
31984
|
}
|
|
31985
|
+
return {
|
|
31986
|
+
core: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
31987
|
+
prerelease
|
|
31988
|
+
};
|
|
31636
31989
|
}
|
|
31637
|
-
__name(
|
|
31638
|
-
|
|
31639
|
-
|
|
31640
|
-
|
|
31641
|
-
|
|
31642
|
-
|
|
31643
|
-
return "1.28.1";
|
|
31990
|
+
__name(parseVersion, "parseVersion");
|
|
31991
|
+
function comparePrereleaseIdentifiers(a, b) {
|
|
31992
|
+
const aIsNumeric = /^\d+$/.test(a);
|
|
31993
|
+
const bIsNumeric = /^\d+$/.test(b);
|
|
31994
|
+
if (aIsNumeric && bIsNumeric) {
|
|
31995
|
+
return Math.sign(Number(a) - Number(b));
|
|
31644
31996
|
}
|
|
31645
|
-
|
|
31646
|
-
|
|
31647
|
-
|
|
31648
|
-
)
|
|
31649
|
-
|
|
31650
|
-
|
|
31997
|
+
if (aIsNumeric !== bIsNumeric) {
|
|
31998
|
+
return aIsNumeric ? -1 : 1;
|
|
31999
|
+
}
|
|
32000
|
+
if (a === b) {
|
|
32001
|
+
return 0;
|
|
32002
|
+
}
|
|
32003
|
+
return a < b ? -1 : 1;
|
|
31651
32004
|
}
|
|
31652
|
-
__name(
|
|
31653
|
-
function
|
|
31654
|
-
|
|
31655
|
-
|
|
31656
|
-
|
|
31657
|
-
|
|
31658
|
-
|
|
31659
|
-
|
|
31660
|
-
|
|
31661
|
-
|
|
31662
|
-
|
|
31663
|
-
|
|
31664
|
-
|
|
31665
|
-
|
|
32005
|
+
__name(comparePrereleaseIdentifiers, "comparePrereleaseIdentifiers");
|
|
32006
|
+
function compareVersions(a, b) {
|
|
32007
|
+
for (let index = 0; index < 3; index += 1) {
|
|
32008
|
+
if (a.core[index] !== b.core[index]) {
|
|
32009
|
+
return Math.sign(a.core[index] - b.core[index]);
|
|
32010
|
+
}
|
|
32011
|
+
}
|
|
32012
|
+
if (a.prerelease.length === 0 || b.prerelease.length === 0) {
|
|
32013
|
+
return Math.sign(b.prerelease.length - a.prerelease.length);
|
|
32014
|
+
}
|
|
32015
|
+
const sharedLength = Math.min(a.prerelease.length, b.prerelease.length);
|
|
32016
|
+
for (let index = 0; index < sharedLength; index += 1) {
|
|
32017
|
+
const result = comparePrereleaseIdentifiers(
|
|
32018
|
+
a.prerelease[index],
|
|
32019
|
+
b.prerelease[index]
|
|
32020
|
+
);
|
|
32021
|
+
if (result !== 0) {
|
|
32022
|
+
return result;
|
|
32023
|
+
}
|
|
32024
|
+
}
|
|
32025
|
+
return Math.sign(a.prerelease.length - b.prerelease.length);
|
|
32026
|
+
}
|
|
32027
|
+
__name(compareVersions, "compareVersions");
|
|
32028
|
+
function isNewerVersion(candidate, current) {
|
|
32029
|
+
const parsedCandidate = parseVersion(candidate);
|
|
32030
|
+
const parsedCurrent = parseVersion(current);
|
|
32031
|
+
if (!parsedCandidate || !parsedCurrent) {
|
|
32032
|
+
return false;
|
|
32033
|
+
}
|
|
32034
|
+
return compareVersions(parsedCandidate, parsedCurrent) > 0;
|
|
32035
|
+
}
|
|
32036
|
+
__name(isNewerVersion, "isNewerVersion");
|
|
32037
|
+
|
|
32038
|
+
// src/version/is-standalone-binary.ts
|
|
32039
|
+
function isStandaloneBinary(moduleUrl = import.meta.url) {
|
|
32040
|
+
return moduleUrl.includes("$bunfs") || moduleUrl.includes("~BUN");
|
|
32041
|
+
}
|
|
32042
|
+
__name(isStandaloneBinary, "isStandaloneBinary");
|
|
32043
|
+
|
|
32044
|
+
// src/version/package-meta.ts
|
|
32045
|
+
import { createRequire } from "node:module";
|
|
32046
|
+
function getPackageMeta() {
|
|
32047
|
+
if (true) {
|
|
32048
|
+
return { name: "@duvoai/cli", version: "1.31.0" };
|
|
32049
|
+
}
|
|
32050
|
+
const require2 = createRequire(import.meta.url);
|
|
32051
|
+
const raw = require2("../../package.json");
|
|
32052
|
+
if (typeof raw !== "object" || raw === null || !("name" in raw) || !("version" in raw) || typeof raw.name !== "string" || typeof raw.version !== "string") {
|
|
32053
|
+
throw new Error("package.json is missing name or version");
|
|
32054
|
+
}
|
|
32055
|
+
const typed = raw;
|
|
32056
|
+
return { name: typed.name, version: typed.version };
|
|
32057
|
+
}
|
|
32058
|
+
__name(getPackageMeta, "getPackageMeta");
|
|
32059
|
+
|
|
32060
|
+
// src/commands/update/self-update-binary.ts
|
|
32061
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
32062
|
+
import { rename, rm as rm2, writeFile as writeFile4 } from "node:fs/promises";
|
|
32063
|
+
import { dirname as dirname3 } from "node:path";
|
|
32064
|
+
var DOWNLOAD_TIMEOUT_MS = 12e4;
|
|
32065
|
+
var EXECUTABLE_MODE = 493;
|
|
32066
|
+
var BINARY_ASSETS = {
|
|
32067
|
+
"linux-x64": "duvo-linux-x64",
|
|
32068
|
+
"linux-arm64": "duvo-linux-arm64",
|
|
32069
|
+
"darwin-x64": "duvo-darwin-x64",
|
|
32070
|
+
"darwin-arm64": "duvo-darwin-arm64"
|
|
32071
|
+
};
|
|
32072
|
+
function resolveBinaryAsset(platform2 = process.platform, arch = process.arch) {
|
|
32073
|
+
const asset = BINARY_ASSETS[`${platform2}-${arch}`];
|
|
32074
|
+
if (!asset) {
|
|
32075
|
+
throw new CliError(
|
|
32076
|
+
`no prebuilt duvo binary for ${platform2}-${arch} (supported: ${Object.keys(BINARY_ASSETS).join(", ")})`
|
|
32077
|
+
);
|
|
32078
|
+
}
|
|
32079
|
+
return asset;
|
|
32080
|
+
}
|
|
32081
|
+
__name(resolveBinaryAsset, "resolveBinaryAsset");
|
|
32082
|
+
async function selfUpdateBinary({
|
|
32083
|
+
version: version2,
|
|
32084
|
+
asset,
|
|
32085
|
+
execPath = process.execPath,
|
|
32086
|
+
fetchImpl = fetch
|
|
32087
|
+
}) {
|
|
32088
|
+
const url = `${CLI_RELEASES_BASE_URL}/v${version2}/${asset}`;
|
|
32089
|
+
const [binaryResponse, checksumResponse] = await Promise.all([
|
|
32090
|
+
fetchImpl(url, { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }),
|
|
32091
|
+
fetchImpl(`${url}.sha256`, {
|
|
32092
|
+
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
|
|
32093
|
+
})
|
|
32094
|
+
]);
|
|
32095
|
+
if (!binaryResponse.ok) {
|
|
32096
|
+
throw new CliError(
|
|
32097
|
+
`failed to download ${url} (HTTP ${binaryResponse.status})`
|
|
32098
|
+
);
|
|
32099
|
+
}
|
|
32100
|
+
if (!checksumResponse.ok) {
|
|
32101
|
+
throw new CliError(
|
|
32102
|
+
`failed to download ${url}.sha256 (HTTP ${checksumResponse.status})`
|
|
32103
|
+
);
|
|
32104
|
+
}
|
|
32105
|
+
const bytes = Buffer.from(await binaryResponse.arrayBuffer());
|
|
32106
|
+
const expected = (await checksumResponse.text()).trim().split(/\s+/)[0];
|
|
32107
|
+
const actual = createHash2("sha256").update(bytes).digest("hex");
|
|
32108
|
+
if (expected !== actual) {
|
|
32109
|
+
throw new CliError(
|
|
32110
|
+
`checksum mismatch for ${asset} (expected ${expected}, got ${actual}) \u2014 not installing`
|
|
32111
|
+
);
|
|
32112
|
+
}
|
|
32113
|
+
const stagedPath = `${execPath}.update-${process.pid}`;
|
|
32114
|
+
try {
|
|
32115
|
+
await writeFile4(stagedPath, bytes, { mode: EXECUTABLE_MODE });
|
|
32116
|
+
await rename(stagedPath, execPath);
|
|
32117
|
+
} catch (error) {
|
|
32118
|
+
await rm2(stagedPath, { force: true });
|
|
32119
|
+
if (isPermissionError(error)) {
|
|
32120
|
+
throw new CliError(
|
|
32121
|
+
`cannot write to ${dirname3(execPath)} \u2014 re-run the installer, which handles sudo:
|
|
32122
|
+
curl -fsSL https://duvo.ai/install-cli.sh | sh`
|
|
32123
|
+
);
|
|
32124
|
+
}
|
|
32125
|
+
throw error;
|
|
32126
|
+
}
|
|
32127
|
+
}
|
|
32128
|
+
__name(selfUpdateBinary, "selfUpdateBinary");
|
|
32129
|
+
function isPermissionError(error) {
|
|
32130
|
+
if (!(error instanceof Error) || !("code" in error)) {
|
|
32131
|
+
return false;
|
|
32132
|
+
}
|
|
32133
|
+
const { code } = error;
|
|
32134
|
+
return code === "EACCES" || code === "EPERM" || code === "EROFS";
|
|
32135
|
+
}
|
|
32136
|
+
__name(isPermissionError, "isPermissionError");
|
|
32137
|
+
|
|
32138
|
+
// src/commands/update/self-update-npm.ts
|
|
32139
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
32140
|
+
function selfUpdateNpm(packageName, { quiet = false, spawnImpl = spawn2 } = {}) {
|
|
32141
|
+
return new Promise((resolve, reject) => {
|
|
32142
|
+
const child = spawnImpl("npm", ["install", "-g", `${packageName}@latest`], {
|
|
32143
|
+
stdio: quiet ? ["ignore", "ignore", "inherit"] : "inherit"
|
|
32144
|
+
});
|
|
32145
|
+
child.on("error", (error) => {
|
|
32146
|
+
reject(
|
|
32147
|
+
new CliError(
|
|
32148
|
+
`failed to run npm: ${error.message} \u2014 is npm on your PATH?`
|
|
32149
|
+
)
|
|
32150
|
+
);
|
|
32151
|
+
});
|
|
32152
|
+
child.on("close", (code) => {
|
|
32153
|
+
if (code === 0) {
|
|
32154
|
+
resolve();
|
|
32155
|
+
} else {
|
|
32156
|
+
reject(
|
|
32157
|
+
new CliError(
|
|
32158
|
+
`\`npm install -g ${packageName}@latest\` exited with code ${String(code)}`
|
|
32159
|
+
)
|
|
32160
|
+
);
|
|
32161
|
+
}
|
|
32162
|
+
});
|
|
32163
|
+
});
|
|
32164
|
+
}
|
|
32165
|
+
__name(selfUpdateNpm, "selfUpdateNpm");
|
|
32166
|
+
|
|
32167
|
+
// src/commands/update/index.ts
|
|
32168
|
+
function registerUpdate3(program) {
|
|
32169
|
+
program.command("update").description(
|
|
32170
|
+
"Update the duvo CLI to the latest version. Auto-detects the install method: npm installs run `npm install -g`, standalone binaries (curl installer) self-replace in place."
|
|
32171
|
+
).option("--check", "check for a newer version without installing it").option("--json", "output raw JSON").action(async (options) => {
|
|
32172
|
+
await runUpdate(options);
|
|
32173
|
+
});
|
|
32174
|
+
}
|
|
32175
|
+
__name(registerUpdate3, "registerUpdate");
|
|
32176
|
+
async function runUpdate(options) {
|
|
32177
|
+
const pkg = getPackageMeta();
|
|
32178
|
+
const installMethod = isStandaloneBinary() ? "binary" : "npm";
|
|
32179
|
+
const latestVersion = await resolveLatestVersion(installMethod, pkg.name);
|
|
32180
|
+
const updateAvailable = isNewerVersion(latestVersion, pkg.version);
|
|
32181
|
+
if (options.check) {
|
|
32182
|
+
printCheckResult(pkg.version, latestVersion, installMethod, options);
|
|
32183
|
+
return;
|
|
32184
|
+
}
|
|
32185
|
+
if (!updateAvailable) {
|
|
32186
|
+
if (options.json) {
|
|
32187
|
+
printJson({
|
|
32188
|
+
currentVersion: pkg.version,
|
|
32189
|
+
latestVersion,
|
|
32190
|
+
installMethod,
|
|
32191
|
+
updated: false
|
|
32192
|
+
});
|
|
32193
|
+
} else {
|
|
32194
|
+
console.log(`Already up to date (v${pkg.version}).`);
|
|
32195
|
+
}
|
|
32196
|
+
return;
|
|
32197
|
+
}
|
|
32198
|
+
if (installMethod === "binary") {
|
|
32199
|
+
await updateStandaloneBinary(pkg.version, latestVersion, options);
|
|
32200
|
+
} else {
|
|
32201
|
+
await updateNpmInstall(pkg.name, pkg.version, latestVersion, options);
|
|
32202
|
+
}
|
|
32203
|
+
}
|
|
32204
|
+
__name(runUpdate, "runUpdate");
|
|
32205
|
+
async function resolveLatestVersion(installMethod, packageName) {
|
|
32206
|
+
try {
|
|
32207
|
+
return installMethod === "binary" ? await fetchLatestBinaryVersion() : await fetchLatestNpmVersion(packageName);
|
|
32208
|
+
} catch (error) {
|
|
32209
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
32210
|
+
throw new CliError(`failed to determine the latest version: ${message}`);
|
|
32211
|
+
}
|
|
32212
|
+
}
|
|
32213
|
+
__name(resolveLatestVersion, "resolveLatestVersion");
|
|
32214
|
+
function printCheckResult(currentVersion, latestVersion, installMethod, options) {
|
|
32215
|
+
const updateAvailable = isNewerVersion(latestVersion, currentVersion);
|
|
32216
|
+
if (options.json) {
|
|
32217
|
+
printJson({
|
|
32218
|
+
currentVersion,
|
|
32219
|
+
latestVersion,
|
|
32220
|
+
installMethod,
|
|
32221
|
+
updateAvailable
|
|
32222
|
+
});
|
|
32223
|
+
return;
|
|
32224
|
+
}
|
|
32225
|
+
console.log(`Current ${currentVersion}`);
|
|
32226
|
+
console.log(`Latest ${latestVersion}`);
|
|
32227
|
+
console.log(
|
|
32228
|
+
`Install ${installMethod === "binary" ? "standalone binary (curl installer)" : "npm"}`
|
|
31666
32229
|
);
|
|
31667
|
-
|
|
31668
|
-
"
|
|
31669
|
-
[
|
|
31670
|
-
"Start here (for AI agents):",
|
|
31671
|
-
" duvo guide get duvo",
|
|
31672
|
-
"",
|
|
31673
|
-
"Guides ship with the CLI (always version-matched) and cover auth,",
|
|
31674
|
-
"workflows, and copy-paste examples. Prefer them over guessing",
|
|
31675
|
-
"commands from flag docs alone. List them with `duvo guide list`.",
|
|
31676
|
-
""
|
|
31677
|
-
].join("\n")
|
|
32230
|
+
console.log(
|
|
32231
|
+
updateAvailable ? "Update available \u2014 run `duvo update` to install it." : "Already up to date."
|
|
31678
32232
|
);
|
|
31679
|
-
registerLogin(program);
|
|
31680
|
-
registerLogout(program);
|
|
31681
|
-
registerWhoami(program);
|
|
31682
|
-
registerProfiles(program);
|
|
31683
|
-
registerApi(program);
|
|
31684
|
-
registerAgents(program);
|
|
31685
|
-
registerAgentFolders(program);
|
|
31686
|
-
registerBuilds(program);
|
|
31687
|
-
registerBuildIntegrations(program);
|
|
31688
|
-
registerIntegrations(program);
|
|
31689
|
-
registerConnections(program);
|
|
31690
|
-
registerOauth(program);
|
|
31691
|
-
registerRuns(program);
|
|
31692
|
-
registerQueues(program);
|
|
31693
|
-
registerQueueLabels(program);
|
|
31694
|
-
registerCases(program);
|
|
31695
|
-
registerSandboxes(program);
|
|
31696
|
-
registerFiles(program);
|
|
31697
|
-
registerPlugins(program);
|
|
31698
|
-
registerSkills(program);
|
|
31699
|
-
registerGuide(program);
|
|
31700
|
-
registerSuggestions(program);
|
|
31701
|
-
registerTeam(program);
|
|
31702
|
-
registerTeams(program);
|
|
31703
|
-
registerSecrets(program);
|
|
31704
|
-
registerCredentials(program);
|
|
31705
|
-
registerRevisionSecrets(program);
|
|
31706
|
-
registerRevisionLogins(program);
|
|
31707
|
-
registerClarity(program);
|
|
31708
|
-
registerPulse(program);
|
|
31709
|
-
return program;
|
|
31710
32233
|
}
|
|
31711
|
-
__name(
|
|
32234
|
+
__name(printCheckResult, "printCheckResult");
|
|
32235
|
+
async function updateStandaloneBinary(currentVersion, latestVersion, options) {
|
|
32236
|
+
const asset = resolveBinaryAsset();
|
|
32237
|
+
if (!options.json) {
|
|
32238
|
+
console.log(
|
|
32239
|
+
`Updating duvo ${currentVersion} \u2192 ${latestVersion} (standalone binary)`
|
|
32240
|
+
);
|
|
32241
|
+
console.log(`Downloading ${asset}\u2026`);
|
|
32242
|
+
}
|
|
32243
|
+
await selfUpdateBinary({ version: latestVersion, asset });
|
|
32244
|
+
if (options.json) {
|
|
32245
|
+
printJson({
|
|
32246
|
+
currentVersion,
|
|
32247
|
+
latestVersion,
|
|
32248
|
+
installMethod: "binary",
|
|
32249
|
+
updated: true
|
|
32250
|
+
});
|
|
32251
|
+
} else {
|
|
32252
|
+
console.log(`Updated ${process.execPath} to v${latestVersion}.`);
|
|
32253
|
+
}
|
|
32254
|
+
}
|
|
32255
|
+
__name(updateStandaloneBinary, "updateStandaloneBinary");
|
|
32256
|
+
async function updateNpmInstall(packageName, currentVersion, latestVersion, options) {
|
|
32257
|
+
if (!options.json) {
|
|
32258
|
+
console.log(`Updating duvo ${currentVersion} \u2192 ${latestVersion} (npm)`);
|
|
32259
|
+
console.log(`Running \`npm install -g ${packageName}@latest\`\u2026`);
|
|
32260
|
+
}
|
|
32261
|
+
await selfUpdateNpm(packageName, { quiet: options.json === true });
|
|
32262
|
+
if (options.json) {
|
|
32263
|
+
printJson({
|
|
32264
|
+
currentVersion,
|
|
32265
|
+
latestVersion,
|
|
32266
|
+
installMethod: "npm",
|
|
32267
|
+
updated: true
|
|
32268
|
+
});
|
|
32269
|
+
} else {
|
|
32270
|
+
console.log(`Updated to v${latestVersion}.`);
|
|
32271
|
+
}
|
|
32272
|
+
}
|
|
32273
|
+
__name(updateNpmInstall, "updateNpmInstall");
|
|
32274
|
+
|
|
32275
|
+
// src/commands/whoami.ts
|
|
32276
|
+
function registerWhoami(program) {
|
|
32277
|
+
program.command("whoami").description(
|
|
32278
|
+
"Print the active profile, the authenticated user's name and email, the team ID that subsequent commands will act on, and the auth type"
|
|
32279
|
+
).action(/* @__PURE__ */ __name(async function whoamiAction() {
|
|
32280
|
+
const resolved = await requireAuthenticatedConfig(this);
|
|
32281
|
+
const profileLabel = resolved.profileName ?? "(env-only, no stored profile)";
|
|
32282
|
+
console.log(`Profile ${profileLabel}`);
|
|
32283
|
+
const userLine = await fetchUserLine(resolved);
|
|
32284
|
+
if (userLine !== null) {
|
|
32285
|
+
console.log(`User ${userLine}`);
|
|
32286
|
+
}
|
|
32287
|
+
const teamId = await resolveActiveTeamId(resolved, getTeamFlag(this));
|
|
32288
|
+
if (teamId !== null) {
|
|
32289
|
+
console.log(`Team ${teamId}`);
|
|
32290
|
+
}
|
|
32291
|
+
const authTypeLabel = resolved.authType === "oauth" ? "OAuth" : "API key";
|
|
32292
|
+
console.log(`Auth type ${authTypeLabel}`);
|
|
32293
|
+
}, "whoamiAction"));
|
|
32294
|
+
}
|
|
32295
|
+
__name(registerWhoami, "registerWhoami");
|
|
32296
|
+
async function fetchUserLine(config) {
|
|
32297
|
+
try {
|
|
32298
|
+
const raw = await httpRequest({
|
|
32299
|
+
method: "GET",
|
|
32300
|
+
path: "/v2/profile",
|
|
32301
|
+
apiKey: config.apiKey,
|
|
32302
|
+
apiBaseUrl: config.apiBaseUrl
|
|
32303
|
+
});
|
|
32304
|
+
const parsed = publicProfileResponseSchema.safeParse(raw);
|
|
32305
|
+
if (!parsed.success) {
|
|
32306
|
+
return null;
|
|
32307
|
+
}
|
|
32308
|
+
const { name, email } = parsed.data.profile;
|
|
32309
|
+
return name ? `${name} <${email}>` : email;
|
|
32310
|
+
} catch {
|
|
32311
|
+
return null;
|
|
32312
|
+
}
|
|
32313
|
+
}
|
|
32314
|
+
__name(fetchUserLine, "fetchUserLine");
|
|
32315
|
+
async function resolveActiveTeamId(config, override) {
|
|
32316
|
+
try {
|
|
32317
|
+
return await resolveRequiredTeamId(config, { override });
|
|
32318
|
+
} catch {
|
|
32319
|
+
return null;
|
|
32320
|
+
}
|
|
32321
|
+
}
|
|
32322
|
+
__name(resolveActiveTeamId, "resolveActiveTeamId");
|
|
31712
32323
|
|
|
31713
32324
|
// src/update-check.ts
|
|
31714
|
-
import {
|
|
31715
|
-
import {
|
|
32325
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
32326
|
+
import { mkdir as mkdir2, readFile as readFile10, writeFile as writeFile5 } from "node:fs/promises";
|
|
31716
32327
|
import { dirname as dirname4 } from "node:path";
|
|
32328
|
+
|
|
32329
|
+
// src/output/notice-box.ts
|
|
32330
|
+
var ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
32331
|
+
var HORIZONTAL_PADDING = 3;
|
|
32332
|
+
function visibleLength(line) {
|
|
32333
|
+
return line.replace(ANSI_PATTERN, "").length;
|
|
32334
|
+
}
|
|
32335
|
+
__name(visibleLength, "visibleLength");
|
|
32336
|
+
function renderNoticeBox(lines) {
|
|
32337
|
+
const contentWidth = Math.max(...lines.map(visibleLength));
|
|
32338
|
+
const innerWidth = contentWidth + HORIZONTAL_PADDING * 2;
|
|
32339
|
+
const pad2 = " ".repeat(HORIZONTAL_PADDING);
|
|
32340
|
+
const emptyRow = `${yellow("\u2502")}${" ".repeat(innerWidth)}${yellow("\u2502")}`;
|
|
32341
|
+
const body = lines.map((line) => {
|
|
32342
|
+
const fill = " ".repeat(contentWidth - visibleLength(line));
|
|
32343
|
+
return `${yellow("\u2502")}${pad2}${line}${fill}${pad2}${yellow("\u2502")}`;
|
|
32344
|
+
});
|
|
32345
|
+
return [
|
|
32346
|
+
yellow(`\u256D${"\u2500".repeat(innerWidth)}\u256E`),
|
|
32347
|
+
emptyRow,
|
|
32348
|
+
...body,
|
|
32349
|
+
emptyRow,
|
|
32350
|
+
yellow(`\u2570${"\u2500".repeat(innerWidth)}\u256F`)
|
|
32351
|
+
].join("\n");
|
|
32352
|
+
}
|
|
32353
|
+
__name(renderNoticeBox, "renderNoticeBox");
|
|
32354
|
+
|
|
32355
|
+
// src/update-check.ts
|
|
31717
32356
|
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
31718
|
-
var
|
|
32357
|
+
var REGISTRY_TIMEOUT_MS2 = 2e3;
|
|
31719
32358
|
var DIR_MODE2 = 448;
|
|
31720
32359
|
function checkForUpdate() {
|
|
31721
32360
|
if (isUpdateCheckDisabled()) {
|
|
@@ -31725,16 +32364,30 @@ function checkForUpdate() {
|
|
|
31725
32364
|
});
|
|
31726
32365
|
}
|
|
31727
32366
|
__name(checkForUpdate, "checkForUpdate");
|
|
32367
|
+
function getPendingUpdateNotice() {
|
|
32368
|
+
if (isUpdateCheckDisabled()) {
|
|
32369
|
+
return null;
|
|
32370
|
+
}
|
|
32371
|
+
const pkg = getPackageMeta();
|
|
32372
|
+
const cache = readCacheSync();
|
|
32373
|
+
if (cache && isNewerVersion(cache.latestVersion, pkg.version)) {
|
|
32374
|
+
return renderUpdateNotice(pkg, cache.latestVersion);
|
|
32375
|
+
}
|
|
32376
|
+
return null;
|
|
32377
|
+
}
|
|
32378
|
+
__name(getPendingUpdateNotice, "getPendingUpdateNotice");
|
|
31728
32379
|
function isUpdateCheckDisabled() {
|
|
31729
32380
|
const ci = process.env.CI;
|
|
31730
32381
|
return process.env.NO_UPDATE_NOTIFIER !== void 0 || process.env.NODE_ENV === "test" || ci !== void 0 && ci !== "" && ci !== "false" && ci !== "0" || process.argv.includes("--no-update-notifier");
|
|
31731
32382
|
}
|
|
31732
32383
|
__name(isUpdateCheckDisabled, "isUpdateCheckDisabled");
|
|
31733
32384
|
async function runUpdateCheck() {
|
|
31734
|
-
const pkg =
|
|
32385
|
+
const pkg = getPackageMeta();
|
|
31735
32386
|
const cache = await readCache();
|
|
31736
32387
|
if (cache && isNewerVersion(cache.latestVersion, pkg.version)) {
|
|
31737
|
-
|
|
32388
|
+
console.error(`
|
|
32389
|
+
${renderUpdateNotice(pkg, cache.latestVersion)}
|
|
32390
|
+
`);
|
|
31738
32391
|
}
|
|
31739
32392
|
const isFresh = cache && Date.now() - cache.lastCheckedAtMs < ONE_DAY_MS;
|
|
31740
32393
|
if (isFresh) {
|
|
@@ -31745,7 +32398,10 @@ async function runUpdateCheck() {
|
|
|
31745
32398
|
__name(runUpdateCheck, "runUpdateCheck");
|
|
31746
32399
|
async function refreshCache(pkg, previous) {
|
|
31747
32400
|
try {
|
|
31748
|
-
const latestVersion = await
|
|
32401
|
+
const latestVersion = await fetchLatestNpmVersion(
|
|
32402
|
+
pkg.name,
|
|
32403
|
+
REGISTRY_TIMEOUT_MS2
|
|
32404
|
+
);
|
|
31749
32405
|
await writeCache({ lastCheckedAtMs: Date.now(), latestVersion });
|
|
31750
32406
|
} catch {
|
|
31751
32407
|
await writeCache({
|
|
@@ -31755,96 +32411,112 @@ async function refreshCache(pkg, previous) {
|
|
|
31755
32411
|
}
|
|
31756
32412
|
}
|
|
31757
32413
|
__name(refreshCache, "refreshCache");
|
|
31758
|
-
function
|
|
31759
|
-
const
|
|
31760
|
-
|
|
31761
|
-
`
|
|
31762
|
-
|
|
31763
|
-
|
|
31764
|
-
`
|
|
31765
|
-
);
|
|
31766
|
-
}
|
|
31767
|
-
__name(printUpdateNotice, "printUpdateNotice");
|
|
31768
|
-
function resolveUpdateCommand(packageName, isStandalone) {
|
|
31769
|
-
return isStandalone ? "curl -fsSL https://duvo.ai/install-cli.sh | sh" : `npm install -g ${packageName}`;
|
|
31770
|
-
}
|
|
31771
|
-
__name(resolveUpdateCommand, "resolveUpdateCommand");
|
|
31772
|
-
function isStandaloneBinary() {
|
|
31773
|
-
return import.meta.url.includes("$bunfs") || import.meta.url.includes("~BUN");
|
|
32414
|
+
function renderUpdateNotice(pkg, latestVersion) {
|
|
32415
|
+
const fallbackCommand = isStandaloneBinary() ? "curl -fsSL https://duvo.ai/install-cli.sh | sh" : `npm install -g ${pkg.name}`;
|
|
32416
|
+
return renderNoticeBox([
|
|
32417
|
+
`Update available for ${bold(pkg.name)}: ${dim(pkg.version)} \u2192 ${green(latestVersion)}`,
|
|
32418
|
+
`Run ${cyan("duvo update")} (or \`${fallbackCommand}\`) to update.`
|
|
32419
|
+
]);
|
|
31774
32420
|
}
|
|
31775
|
-
__name(
|
|
31776
|
-
|
|
31777
|
-
const
|
|
31778
|
-
|
|
31779
|
-
|
|
31780
|
-
signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),
|
|
31781
|
-
headers: { accept: "application/json" }
|
|
31782
|
-
}
|
|
31783
|
-
);
|
|
31784
|
-
if (!response.ok) {
|
|
31785
|
-
throw new Error(`npm registry responded with ${response.status}`);
|
|
31786
|
-
}
|
|
31787
|
-
const body = await response.json();
|
|
31788
|
-
if (body === null || typeof body !== "object" || typeof body.latest !== "string") {
|
|
31789
|
-
throw new Error("npm registry response is missing the latest dist-tag");
|
|
32421
|
+
__name(renderUpdateNotice, "renderUpdateNotice");
|
|
32422
|
+
function parseCache(raw) {
|
|
32423
|
+
const parsed = JSON.parse(raw);
|
|
32424
|
+
if (parsed === null || typeof parsed !== "object" || typeof parsed.lastCheckedAtMs !== "number" || typeof parsed.latestVersion !== "string") {
|
|
32425
|
+
return null;
|
|
31790
32426
|
}
|
|
31791
|
-
return
|
|
32427
|
+
return parsed;
|
|
31792
32428
|
}
|
|
31793
|
-
__name(
|
|
32429
|
+
__name(parseCache, "parseCache");
|
|
31794
32430
|
async function readCache() {
|
|
31795
32431
|
try {
|
|
31796
|
-
|
|
31797
|
-
const parsed = JSON.parse(raw);
|
|
31798
|
-
if (parsed === null || typeof parsed !== "object" || typeof parsed.lastCheckedAtMs !== "number" || typeof parsed.latestVersion !== "string") {
|
|
31799
|
-
return null;
|
|
31800
|
-
}
|
|
31801
|
-
return parsed;
|
|
32432
|
+
return parseCache(await readFile10(getUpdateCheckCachePath(), "utf8"));
|
|
31802
32433
|
} catch {
|
|
31803
32434
|
return null;
|
|
31804
32435
|
}
|
|
31805
32436
|
}
|
|
31806
32437
|
__name(readCache, "readCache");
|
|
32438
|
+
function readCacheSync() {
|
|
32439
|
+
try {
|
|
32440
|
+
return parseCache(readFileSync8(getUpdateCheckCachePath(), "utf8"));
|
|
32441
|
+
} catch {
|
|
32442
|
+
return null;
|
|
32443
|
+
}
|
|
32444
|
+
}
|
|
32445
|
+
__name(readCacheSync, "readCacheSync");
|
|
31807
32446
|
async function writeCache(cache) {
|
|
31808
32447
|
const path = getUpdateCheckCachePath();
|
|
31809
32448
|
await mkdir2(dirname4(path), { recursive: true, mode: DIR_MODE2 });
|
|
31810
|
-
await
|
|
32449
|
+
await writeFile5(path, JSON.stringify(cache), "utf8");
|
|
31811
32450
|
}
|
|
31812
32451
|
__name(writeCache, "writeCache");
|
|
31813
|
-
|
|
31814
|
-
|
|
31815
|
-
|
|
31816
|
-
|
|
31817
|
-
|
|
31818
|
-
|
|
31819
|
-
|
|
31820
|
-
|
|
31821
|
-
|
|
31822
|
-
|
|
31823
|
-
|
|
31824
|
-
|
|
31825
|
-
|
|
31826
|
-
|
|
31827
|
-
|
|
31828
|
-
|
|
31829
|
-
|
|
31830
|
-
|
|
31831
|
-
|
|
31832
|
-
|
|
31833
|
-
|
|
31834
|
-
|
|
31835
|
-
|
|
31836
|
-
|
|
31837
|
-
|
|
31838
|
-
|
|
31839
|
-
|
|
31840
|
-
|
|
31841
|
-
|
|
31842
|
-
|
|
31843
|
-
|
|
31844
|
-
|
|
31845
|
-
|
|
32452
|
+
|
|
32453
|
+
// src/bin/create-program.ts
|
|
32454
|
+
var { version } = getPackageMeta();
|
|
32455
|
+
function createProgram() {
|
|
32456
|
+
const program = new Command();
|
|
32457
|
+
program.name("duvo").description("Command-line interface for the Duvo public API").version(version).option(
|
|
32458
|
+
"--profile <name>",
|
|
32459
|
+
"use a specific profile for this invocation (overrides default profile)"
|
|
32460
|
+
).option(
|
|
32461
|
+
"--team <id>",
|
|
32462
|
+
"use a specific team for this invocation (overrides DUVO_TEAM_ID and profile default; API-key profiles are pinned to the key's team, so a different value is rejected by the server)"
|
|
32463
|
+
).addOption(
|
|
32464
|
+
new Option2(
|
|
32465
|
+
"--no-update-notifier",
|
|
32466
|
+
"skip the update check for this invocation"
|
|
32467
|
+
).hideHelp()
|
|
32468
|
+
);
|
|
32469
|
+
program.addHelpText(
|
|
32470
|
+
"before",
|
|
32471
|
+
[
|
|
32472
|
+
"Start here (for AI agents):",
|
|
32473
|
+
" duvo guide get duvo",
|
|
32474
|
+
"",
|
|
32475
|
+
"Guides ship with the CLI (always version-matched) and cover auth,",
|
|
32476
|
+
"workflows, and copy-paste examples. Prefer them over guessing",
|
|
32477
|
+
"commands from flag docs alone. List them with `duvo guide list`.",
|
|
32478
|
+
""
|
|
32479
|
+
].join("\n")
|
|
32480
|
+
);
|
|
32481
|
+
program.addHelpText("afterAll", () => {
|
|
32482
|
+
const notice = getPendingUpdateNotice();
|
|
32483
|
+
return notice ? `
|
|
32484
|
+
${notice}` : "";
|
|
32485
|
+
});
|
|
32486
|
+
registerLogin(program);
|
|
32487
|
+
registerLogout(program);
|
|
32488
|
+
registerWhoami(program);
|
|
32489
|
+
registerProfiles(program);
|
|
32490
|
+
registerApi(program);
|
|
32491
|
+
registerAgents(program);
|
|
32492
|
+
registerAgentFolders(program);
|
|
32493
|
+
registerBuilds(program);
|
|
32494
|
+
registerBuildIntegrations(program);
|
|
32495
|
+
registerIntegrations(program);
|
|
32496
|
+
registerConnections(program);
|
|
32497
|
+
registerOauth(program);
|
|
32498
|
+
registerRuns(program);
|
|
32499
|
+
registerQueues(program);
|
|
32500
|
+
registerQueueLabels(program);
|
|
32501
|
+
registerCases(program);
|
|
32502
|
+
registerSandboxes(program);
|
|
32503
|
+
registerFiles(program);
|
|
32504
|
+
registerPlugins(program);
|
|
32505
|
+
registerSkills(program);
|
|
32506
|
+
registerGuide(program);
|
|
32507
|
+
registerSuggestions(program);
|
|
32508
|
+
registerTeam(program);
|
|
32509
|
+
registerTeams(program);
|
|
32510
|
+
registerSecrets(program);
|
|
32511
|
+
registerCredentials(program);
|
|
32512
|
+
registerRevisionSecrets(program);
|
|
32513
|
+
registerRevisionLogins(program);
|
|
32514
|
+
registerClarity(program);
|
|
32515
|
+
registerPulse(program);
|
|
32516
|
+
registerUpdate3(program);
|
|
32517
|
+
return program;
|
|
31846
32518
|
}
|
|
31847
|
-
__name(
|
|
32519
|
+
__name(createProgram, "createProgram");
|
|
31848
32520
|
|
|
31849
32521
|
// src/bin/duvo.ts
|
|
31850
32522
|
void checkForUpdate();
|