@duvoai/cli 1.30.0 → 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 +710 -161
- 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") }),
|
|
@@ -9706,12 +9774,19 @@ var humanRequestContextSchema = z59.discriminatedUnion("kind", [
|
|
|
9706
9774
|
caseTitle: z59.string()
|
|
9707
9775
|
})
|
|
9708
9776
|
]);
|
|
9777
|
+
var casePrioritySchema = z60.enum([
|
|
9778
|
+
CASE_PRIORITY.NONE,
|
|
9779
|
+
CASE_PRIORITY.MEDIUM,
|
|
9780
|
+
CASE_PRIORITY.HIGH
|
|
9781
|
+
]);
|
|
9709
9782
|
var caseQueueItemSchema = z60.object({
|
|
9710
9783
|
id: z60.guid(),
|
|
9711
9784
|
queue_id: z60.guid(),
|
|
9712
9785
|
title: z60.string(),
|
|
9713
9786
|
data: z60.string(),
|
|
9714
9787
|
status: z60.enum(["pending", "completed", "failed"]),
|
|
9788
|
+
/** Case priority level. `none` = default (no priority). */
|
|
9789
|
+
priority: casePrioritySchema,
|
|
9715
9790
|
/**
|
|
9716
9791
|
* Derived display bucket combining the settlement status with ownership,
|
|
9717
9792
|
* open HITL tokens, and scheduling. See CASE_DISPLAY_STATUS in
|
|
@@ -9806,6 +9881,9 @@ var caseCreateInputSchema = z60.object({
|
|
|
9806
9881
|
})
|
|
9807
9882
|
).max(50).optional().describe(
|
|
9808
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."
|
|
9809
9887
|
)
|
|
9810
9888
|
});
|
|
9811
9889
|
var caseCreateRequestSchema = z60.object({
|
|
@@ -9929,6 +10007,10 @@ var caseBulkStatusUpdateResponseSchema = z60.object({
|
|
|
9929
10007
|
skippedCount: z60.number(),
|
|
9930
10008
|
interruptedRunIds: z60.array(z60.guid())
|
|
9931
10009
|
});
|
|
10010
|
+
var caseBulkPriorityUpdateResponseSchema = z60.object({
|
|
10011
|
+
updatedCount: z60.number(),
|
|
10012
|
+
skippedCount: z60.number()
|
|
10013
|
+
});
|
|
9932
10014
|
var deleteQueueResponseSchema = z60.object({
|
|
9933
10015
|
success: z60.boolean(),
|
|
9934
10016
|
deleted_case_count: z60.number(),
|
|
@@ -10017,7 +10099,9 @@ var exportCasesResponseSchema = z60.object({
|
|
|
10017
10099
|
cases: z60.array(
|
|
10018
10100
|
z60.object({
|
|
10019
10101
|
title: z60.string(),
|
|
10020
|
-
data: z60.string().optional()
|
|
10102
|
+
data: z60.string().optional(),
|
|
10103
|
+
/** Priority level; omitted for default (`none`) priority cases. */
|
|
10104
|
+
priority: casePrioritySchema.optional()
|
|
10021
10105
|
})
|
|
10022
10106
|
)
|
|
10023
10107
|
});
|
|
@@ -11409,6 +11493,7 @@ function canonicalizeSopInput(config) {
|
|
|
11409
11493
|
}
|
|
11410
11494
|
__name(canonicalizeSopInput, "canonicalizeSopInput");
|
|
11411
11495
|
__name2(canonicalizeSopInput, "canonicalizeSopInput");
|
|
11496
|
+
var casePriorityFilterSchema = casePrioritySchema;
|
|
11412
11497
|
var caseFilterStatusSchema = z81.enum([
|
|
11413
11498
|
"pending",
|
|
11414
11499
|
"claimed",
|
|
@@ -11419,6 +11504,7 @@ var caseFilterStatusSchema = z81.enum([
|
|
|
11419
11504
|
]);
|
|
11420
11505
|
var casesFiltersSchema = z81.object({
|
|
11421
11506
|
status: z81.array(caseFilterStatusSchema).optional(),
|
|
11507
|
+
priority: z81.array(casePriorityFilterSchema).optional(),
|
|
11422
11508
|
created_at_from: z81.string().optional(),
|
|
11423
11509
|
updated_at_from: z81.string().optional(),
|
|
11424
11510
|
labels: z81.record(z81.string(), z81.array(z81.string())).optional()
|
|
@@ -11504,6 +11590,9 @@ function getFilterValuesByCategoryKey(filters, categoryKey) {
|
|
|
11504
11590
|
if (categoryKey === "status") {
|
|
11505
11591
|
return filters.status ?? [];
|
|
11506
11592
|
}
|
|
11593
|
+
if (categoryKey === "priority") {
|
|
11594
|
+
return filters.priority ?? [];
|
|
11595
|
+
}
|
|
11507
11596
|
if (categoryKey === "created_at_from") {
|
|
11508
11597
|
return filters.created_at_from ? [filters.created_at_from] : [];
|
|
11509
11598
|
}
|
|
@@ -11530,6 +11619,17 @@ function setFilterValuesByCategoryKey(filters, categoryKey, values) {
|
|
|
11530
11619
|
}
|
|
11531
11620
|
return { ...filters, status: parsed.data };
|
|
11532
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
|
+
}
|
|
11533
11633
|
if (categoryKey === "created_at_from") {
|
|
11534
11634
|
if (values.length === 0 || !values[0]) {
|
|
11535
11635
|
const { created_at_from: _, ...rest } = filters;
|
|
@@ -11568,7 +11668,7 @@ function removeFilterByCategoryKey(filters, categoryKey) {
|
|
|
11568
11668
|
__name(removeFilterByCategoryKey, "removeFilterByCategoryKey");
|
|
11569
11669
|
__name2(removeFilterByCategoryKey, "removeFilterByCategoryKey");
|
|
11570
11670
|
function isCasesFiltersEmpty(filters) {
|
|
11571
|
-
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);
|
|
11572
11672
|
}
|
|
11573
11673
|
__name(isCasesFiltersEmpty, "isCasesFiltersEmpty");
|
|
11574
11674
|
__name2(isCasesFiltersEmpty, "isCasesFiltersEmpty");
|
|
@@ -11577,6 +11677,9 @@ function countCasesFilters(filters) {
|
|
|
11577
11677
|
if (filters.status?.length) {
|
|
11578
11678
|
count += 1;
|
|
11579
11679
|
}
|
|
11680
|
+
if (filters.priority?.length) {
|
|
11681
|
+
count += 1;
|
|
11682
|
+
}
|
|
11580
11683
|
if (filters.created_at_from) {
|
|
11581
11684
|
count += 1;
|
|
11582
11685
|
}
|
|
@@ -12288,6 +12391,7 @@ var green = /* @__PURE__ */ __name((text3) => wrap(ANSI.green, text3), "green");
|
|
|
12288
12391
|
var red = /* @__PURE__ */ __name((text3) => wrap(ANSI.red, text3), "red");
|
|
12289
12392
|
var cyan = /* @__PURE__ */ __name((text3) => wrap(ANSI.cyan, text3), "cyan");
|
|
12290
12393
|
var bold = /* @__PURE__ */ __name((text3) => wrap(ANSI.bold, text3), "bold");
|
|
12394
|
+
var dim = /* @__PURE__ */ __name((text3) => wrap(ANSI.dim, text3), "dim");
|
|
12291
12395
|
var yellow = /* @__PURE__ */ __name((text3) => wrap(ANSI.yellow, text3), "yellow");
|
|
12292
12396
|
|
|
12293
12397
|
// src/output/deprecation-notice.ts
|
|
@@ -17353,6 +17457,62 @@ function registerCasesBulkReprocess(cases) {
|
|
|
17353
17457
|
}
|
|
17354
17458
|
__name(registerCasesBulkReprocess, "registerCasesBulkReprocess");
|
|
17355
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
|
+
|
|
17356
17516
|
// src/commands/cases/bulk-update-status.ts
|
|
17357
17517
|
var CASE_TERMINAL_STATUSES = ["completed", "failed"];
|
|
17358
17518
|
function registerCasesBulkUpdateStatus(cases) {
|
|
@@ -17511,6 +17671,9 @@ function registerCasesCreate(cases) {
|
|
|
17511
17671
|
cases.command("create").description(
|
|
17512
17672
|
"Create one or more cases in a queue. Provide --title for one case or --from-file with a JSON array for many."
|
|
17513
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(
|
|
17514
17677
|
"--label <key=value>",
|
|
17515
17678
|
"label to assign to the case (omit key for a simple tag, repeat for multiple)",
|
|
17516
17679
|
collectLabel,
|
|
@@ -17555,9 +17718,9 @@ function collectLabel(value, previous) {
|
|
|
17555
17718
|
__name(collectLabel, "collectLabel");
|
|
17556
17719
|
async function buildRequestBody(options) {
|
|
17557
17720
|
if (options.fromFile !== void 0) {
|
|
17558
|
-
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) {
|
|
17559
17722
|
throw new CliError(
|
|
17560
|
-
"--from-file cannot be combined with --title, --data, or --label."
|
|
17723
|
+
"--from-file cannot be combined with --title, --data, --priority, or --label."
|
|
17561
17724
|
);
|
|
17562
17725
|
}
|
|
17563
17726
|
return readCasesFromFile(options.fromFile);
|
|
@@ -17573,9 +17736,22 @@ async function buildRequestBody(options) {
|
|
|
17573
17736
|
if (labels) {
|
|
17574
17737
|
single.labels = labels;
|
|
17575
17738
|
}
|
|
17739
|
+
if (options.priority !== void 0) {
|
|
17740
|
+
single.priority = parsePriority2(options.priority, "--priority");
|
|
17741
|
+
}
|
|
17576
17742
|
return { case: single };
|
|
17577
17743
|
}
|
|
17578
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");
|
|
17579
17755
|
async function readCasesFromFile(path) {
|
|
17580
17756
|
let raw;
|
|
17581
17757
|
try {
|
|
@@ -17635,6 +17811,12 @@ function coerceCase(value, location) {
|
|
|
17635
17811
|
(l, i) => coerceLabel(l, `${location}.labels[${i}]`)
|
|
17636
17812
|
);
|
|
17637
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
|
+
}
|
|
17638
17820
|
return out;
|
|
17639
17821
|
}
|
|
17640
17822
|
__name(coerceCase, "coerceCase");
|
|
@@ -17972,12 +18154,16 @@ var TABLE_COLUMNS18 = [
|
|
|
17972
18154
|
{ header: "ID", cell: /* @__PURE__ */ __name((row) => row.id, "cell") },
|
|
17973
18155
|
{ header: "TITLE", cell: /* @__PURE__ */ __name((row) => row.title, "cell"), maxWidth: 50 },
|
|
17974
18156
|
{ header: "STATUS", cell: /* @__PURE__ */ __name((row) => row.display_status, "cell") },
|
|
18157
|
+
{ header: "PRIORITY", cell: /* @__PURE__ */ __name((row) => row.priority, "cell") },
|
|
17975
18158
|
{ header: "CREATED", cell: /* @__PURE__ */ __name((row) => row.created_at ?? "", "cell") }
|
|
17976
18159
|
];
|
|
17977
18160
|
function registerCasesList(cases) {
|
|
17978
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(
|
|
17979
18162
|
"--status <statuses>",
|
|
17980
18163
|
`comma-separated case statuses (${caseFilterStatusSchema.options.join(", ")})`
|
|
18164
|
+
).option(
|
|
18165
|
+
"--priority <levels>",
|
|
18166
|
+
`comma-separated priority levels (${casePriorityFilterSchema.options.join(", ")})`
|
|
17981
18167
|
).option("--search <text>", "full-text search across title and data").option(
|
|
17982
18168
|
"--created-at-from <iso>",
|
|
17983
18169
|
"include cases created on or after this ISO-8601 timestamp"
|
|
@@ -17995,6 +18181,7 @@ function registerCasesList(cases) {
|
|
|
17995
18181
|
});
|
|
17996
18182
|
const offset = parseOffset(options.offset);
|
|
17997
18183
|
const statuses = parseStatuses(options.status);
|
|
18184
|
+
const priorities = parsePriorities(options.priority);
|
|
17998
18185
|
const sortBy = parseSortBy(options.sortBy);
|
|
17999
18186
|
const sortOrder = parseSortOrder(options.sortOrder);
|
|
18000
18187
|
const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
|
|
@@ -18004,6 +18191,9 @@ function registerCasesList(cases) {
|
|
|
18004
18191
|
if (statuses) {
|
|
18005
18192
|
searchParams.append("status", statuses.join(","));
|
|
18006
18193
|
}
|
|
18194
|
+
if (priorities) {
|
|
18195
|
+
searchParams.append("priority", priorities.join(","));
|
|
18196
|
+
}
|
|
18007
18197
|
if (options.search !== void 0) {
|
|
18008
18198
|
searchParams.append("search", options.search);
|
|
18009
18199
|
}
|
|
@@ -18069,6 +18259,26 @@ function parseStatuses(raw) {
|
|
|
18069
18259
|
return parts;
|
|
18070
18260
|
}
|
|
18071
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");
|
|
18072
18282
|
function parseSortBy(raw) {
|
|
18073
18283
|
if (raw === void 0) {
|
|
18074
18284
|
return void 0;
|
|
@@ -18246,6 +18456,7 @@ function registerCases(program) {
|
|
|
18246
18456
|
registerCasesBulkDelete(cases);
|
|
18247
18457
|
registerCasesBulkReprocess(cases);
|
|
18248
18458
|
registerCasesBulkUpdateStatus(cases);
|
|
18459
|
+
registerCasesBulkUpdatePriority(cases);
|
|
18249
18460
|
registerCasesRuns(cases);
|
|
18250
18461
|
registerCasesLabels(cases);
|
|
18251
18462
|
}
|
|
@@ -31710,6 +31921,357 @@ function registerTeams(program) {
|
|
|
31710
31921
|
}
|
|
31711
31922
|
__name(registerTeams, "registerTeams");
|
|
31712
31923
|
|
|
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;
|
|
31939
|
+
}
|
|
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" }
|
|
31950
|
+
}
|
|
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");
|
|
31958
|
+
}
|
|
31959
|
+
return body.latest;
|
|
31960
|
+
}
|
|
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)) {
|
|
31983
|
+
return null;
|
|
31984
|
+
}
|
|
31985
|
+
return {
|
|
31986
|
+
core: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
31987
|
+
prerelease
|
|
31988
|
+
};
|
|
31989
|
+
}
|
|
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));
|
|
31996
|
+
}
|
|
31997
|
+
if (aIsNumeric !== bIsNumeric) {
|
|
31998
|
+
return aIsNumeric ? -1 : 1;
|
|
31999
|
+
}
|
|
32000
|
+
if (a === b) {
|
|
32001
|
+
return 0;
|
|
32002
|
+
}
|
|
32003
|
+
return a < b ? -1 : 1;
|
|
32004
|
+
}
|
|
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"}`
|
|
32229
|
+
);
|
|
32230
|
+
console.log(
|
|
32231
|
+
updateAvailable ? "Update available \u2014 run `duvo update` to install it." : "Already up to date."
|
|
32232
|
+
);
|
|
32233
|
+
}
|
|
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
|
+
|
|
31713
32275
|
// src/commands/whoami.ts
|
|
31714
32276
|
function registerWhoami(program) {
|
|
31715
32277
|
program.command("whoami").description(
|
|
@@ -31759,20 +32321,137 @@ async function resolveActiveTeamId(config, override) {
|
|
|
31759
32321
|
}
|
|
31760
32322
|
__name(resolveActiveTeamId, "resolveActiveTeamId");
|
|
31761
32323
|
|
|
31762
|
-
// src/
|
|
31763
|
-
|
|
31764
|
-
|
|
31765
|
-
|
|
31766
|
-
|
|
32324
|
+
// src/update-check.ts
|
|
32325
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
32326
|
+
import { mkdir as mkdir2, readFile as readFile10, writeFile as writeFile5 } from "node:fs/promises";
|
|
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
|
|
32356
|
+
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
32357
|
+
var REGISTRY_TIMEOUT_MS2 = 2e3;
|
|
32358
|
+
var DIR_MODE2 = 448;
|
|
32359
|
+
function checkForUpdate() {
|
|
32360
|
+
if (isUpdateCheckDisabled()) {
|
|
32361
|
+
return Promise.resolve();
|
|
31767
32362
|
}
|
|
31768
|
-
|
|
31769
|
-
|
|
31770
|
-
|
|
31771
|
-
|
|
31772
|
-
|
|
31773
|
-
|
|
32363
|
+
return runUpdateCheck().catch(() => {
|
|
32364
|
+
});
|
|
32365
|
+
}
|
|
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");
|
|
32379
|
+
function isUpdateCheckDisabled() {
|
|
32380
|
+
const ci = process.env.CI;
|
|
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");
|
|
32382
|
+
}
|
|
32383
|
+
__name(isUpdateCheckDisabled, "isUpdateCheckDisabled");
|
|
32384
|
+
async function runUpdateCheck() {
|
|
32385
|
+
const pkg = getPackageMeta();
|
|
32386
|
+
const cache = await readCache();
|
|
32387
|
+
if (cache && isNewerVersion(cache.latestVersion, pkg.version)) {
|
|
32388
|
+
console.error(`
|
|
32389
|
+
${renderUpdateNotice(pkg, cache.latestVersion)}
|
|
32390
|
+
`);
|
|
32391
|
+
}
|
|
32392
|
+
const isFresh = cache && Date.now() - cache.lastCheckedAtMs < ONE_DAY_MS;
|
|
32393
|
+
if (isFresh) {
|
|
32394
|
+
return;
|
|
32395
|
+
}
|
|
32396
|
+
await refreshCache(pkg, cache);
|
|
32397
|
+
}
|
|
32398
|
+
__name(runUpdateCheck, "runUpdateCheck");
|
|
32399
|
+
async function refreshCache(pkg, previous) {
|
|
32400
|
+
try {
|
|
32401
|
+
const latestVersion = await fetchLatestNpmVersion(
|
|
32402
|
+
pkg.name,
|
|
32403
|
+
REGISTRY_TIMEOUT_MS2
|
|
32404
|
+
);
|
|
32405
|
+
await writeCache({ lastCheckedAtMs: Date.now(), latestVersion });
|
|
32406
|
+
} catch {
|
|
32407
|
+
await writeCache({
|
|
32408
|
+
lastCheckedAtMs: Date.now(),
|
|
32409
|
+
latestVersion: previous?.latestVersion ?? pkg.version
|
|
32410
|
+
});
|
|
32411
|
+
}
|
|
32412
|
+
}
|
|
32413
|
+
__name(refreshCache, "refreshCache");
|
|
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
|
+
]);
|
|
32420
|
+
}
|
|
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;
|
|
32426
|
+
}
|
|
32427
|
+
return parsed;
|
|
32428
|
+
}
|
|
32429
|
+
__name(parseCache, "parseCache");
|
|
32430
|
+
async function readCache() {
|
|
32431
|
+
try {
|
|
32432
|
+
return parseCache(await readFile10(getUpdateCheckCachePath(), "utf8"));
|
|
32433
|
+
} catch {
|
|
32434
|
+
return null;
|
|
32435
|
+
}
|
|
32436
|
+
}
|
|
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");
|
|
32446
|
+
async function writeCache(cache) {
|
|
32447
|
+
const path = getUpdateCheckCachePath();
|
|
32448
|
+
await mkdir2(dirname4(path), { recursive: true, mode: DIR_MODE2 });
|
|
32449
|
+
await writeFile5(path, JSON.stringify(cache), "utf8");
|
|
31774
32450
|
}
|
|
31775
|
-
__name(
|
|
32451
|
+
__name(writeCache, "writeCache");
|
|
32452
|
+
|
|
32453
|
+
// src/bin/create-program.ts
|
|
32454
|
+
var { version } = getPackageMeta();
|
|
31776
32455
|
function createProgram() {
|
|
31777
32456
|
const program = new Command();
|
|
31778
32457
|
program.name("duvo").description("Command-line interface for the Duvo public API").version(version).option(
|
|
@@ -31799,6 +32478,11 @@ function createProgram() {
|
|
|
31799
32478
|
""
|
|
31800
32479
|
].join("\n")
|
|
31801
32480
|
);
|
|
32481
|
+
program.addHelpText("afterAll", () => {
|
|
32482
|
+
const notice = getPendingUpdateNotice();
|
|
32483
|
+
return notice ? `
|
|
32484
|
+
${notice}` : "";
|
|
32485
|
+
});
|
|
31802
32486
|
registerLogin(program);
|
|
31803
32487
|
registerLogout(program);
|
|
31804
32488
|
registerWhoami(program);
|
|
@@ -31829,146 +32513,11 @@ function createProgram() {
|
|
|
31829
32513
|
registerRevisionLogins(program);
|
|
31830
32514
|
registerClarity(program);
|
|
31831
32515
|
registerPulse(program);
|
|
32516
|
+
registerUpdate3(program);
|
|
31832
32517
|
return program;
|
|
31833
32518
|
}
|
|
31834
32519
|
__name(createProgram, "createProgram");
|
|
31835
32520
|
|
|
31836
|
-
// src/update-check.ts
|
|
31837
|
-
import { mkdir as mkdir2, readFile as readFile10, writeFile as writeFile4 } from "node:fs/promises";
|
|
31838
|
-
import { createRequire } from "node:module";
|
|
31839
|
-
import { dirname as dirname4 } from "node:path";
|
|
31840
|
-
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
31841
|
-
var REGISTRY_TIMEOUT_MS = 2e3;
|
|
31842
|
-
var DIR_MODE2 = 448;
|
|
31843
|
-
function checkForUpdate() {
|
|
31844
|
-
if (isUpdateCheckDisabled()) {
|
|
31845
|
-
return Promise.resolve();
|
|
31846
|
-
}
|
|
31847
|
-
return runUpdateCheck().catch(() => {
|
|
31848
|
-
});
|
|
31849
|
-
}
|
|
31850
|
-
__name(checkForUpdate, "checkForUpdate");
|
|
31851
|
-
function isUpdateCheckDisabled() {
|
|
31852
|
-
const ci = process.env.CI;
|
|
31853
|
-
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");
|
|
31854
|
-
}
|
|
31855
|
-
__name(isUpdateCheckDisabled, "isUpdateCheckDisabled");
|
|
31856
|
-
async function runUpdateCheck() {
|
|
31857
|
-
const pkg = loadPackageMeta();
|
|
31858
|
-
const cache = await readCache();
|
|
31859
|
-
if (cache && isNewerVersion(cache.latestVersion, pkg.version)) {
|
|
31860
|
-
printUpdateNotice(pkg, cache.latestVersion);
|
|
31861
|
-
}
|
|
31862
|
-
const isFresh = cache && Date.now() - cache.lastCheckedAtMs < ONE_DAY_MS;
|
|
31863
|
-
if (isFresh) {
|
|
31864
|
-
return;
|
|
31865
|
-
}
|
|
31866
|
-
await refreshCache(pkg, cache);
|
|
31867
|
-
}
|
|
31868
|
-
__name(runUpdateCheck, "runUpdateCheck");
|
|
31869
|
-
async function refreshCache(pkg, previous) {
|
|
31870
|
-
try {
|
|
31871
|
-
const latestVersion = await fetchLatestVersion(pkg.name);
|
|
31872
|
-
await writeCache({ lastCheckedAtMs: Date.now(), latestVersion });
|
|
31873
|
-
} catch {
|
|
31874
|
-
await writeCache({
|
|
31875
|
-
lastCheckedAtMs: Date.now(),
|
|
31876
|
-
latestVersion: previous?.latestVersion ?? pkg.version
|
|
31877
|
-
});
|
|
31878
|
-
}
|
|
31879
|
-
}
|
|
31880
|
-
__name(refreshCache, "refreshCache");
|
|
31881
|
-
function printUpdateNotice(pkg, latestVersion) {
|
|
31882
|
-
const updateCommand = resolveUpdateCommand(pkg.name, isStandaloneBinary());
|
|
31883
|
-
console.error(
|
|
31884
|
-
`
|
|
31885
|
-
Update available for ${pkg.name}: ${pkg.version} \u2192 ${latestVersion}
|
|
31886
|
-
Run \`${updateCommand}\` to update.
|
|
31887
|
-
`
|
|
31888
|
-
);
|
|
31889
|
-
}
|
|
31890
|
-
__name(printUpdateNotice, "printUpdateNotice");
|
|
31891
|
-
function resolveUpdateCommand(packageName, isStandalone) {
|
|
31892
|
-
return isStandalone ? "curl -fsSL https://duvo.ai/install-cli.sh | sh" : `npm install -g ${packageName}`;
|
|
31893
|
-
}
|
|
31894
|
-
__name(resolveUpdateCommand, "resolveUpdateCommand");
|
|
31895
|
-
function isStandaloneBinary() {
|
|
31896
|
-
return import.meta.url.includes("$bunfs") || import.meta.url.includes("~BUN");
|
|
31897
|
-
}
|
|
31898
|
-
__name(isStandaloneBinary, "isStandaloneBinary");
|
|
31899
|
-
async function fetchLatestVersion(packageName) {
|
|
31900
|
-
const response = await fetch(
|
|
31901
|
-
`https://registry.npmjs.org/-/package/${packageName}/dist-tags`,
|
|
31902
|
-
{
|
|
31903
|
-
signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),
|
|
31904
|
-
headers: { accept: "application/json" }
|
|
31905
|
-
}
|
|
31906
|
-
);
|
|
31907
|
-
if (!response.ok) {
|
|
31908
|
-
throw new Error(`npm registry responded with ${response.status}`);
|
|
31909
|
-
}
|
|
31910
|
-
const body = await response.json();
|
|
31911
|
-
if (body === null || typeof body !== "object" || typeof body.latest !== "string") {
|
|
31912
|
-
throw new Error("npm registry response is missing the latest dist-tag");
|
|
31913
|
-
}
|
|
31914
|
-
return body.latest;
|
|
31915
|
-
}
|
|
31916
|
-
__name(fetchLatestVersion, "fetchLatestVersion");
|
|
31917
|
-
async function readCache() {
|
|
31918
|
-
try {
|
|
31919
|
-
const raw = await readFile10(getUpdateCheckCachePath(), "utf8");
|
|
31920
|
-
const parsed = JSON.parse(raw);
|
|
31921
|
-
if (parsed === null || typeof parsed !== "object" || typeof parsed.lastCheckedAtMs !== "number" || typeof parsed.latestVersion !== "string") {
|
|
31922
|
-
return null;
|
|
31923
|
-
}
|
|
31924
|
-
return parsed;
|
|
31925
|
-
} catch {
|
|
31926
|
-
return null;
|
|
31927
|
-
}
|
|
31928
|
-
}
|
|
31929
|
-
__name(readCache, "readCache");
|
|
31930
|
-
async function writeCache(cache) {
|
|
31931
|
-
const path = getUpdateCheckCachePath();
|
|
31932
|
-
await mkdir2(dirname4(path), { recursive: true, mode: DIR_MODE2 });
|
|
31933
|
-
await writeFile4(path, JSON.stringify(cache), "utf8");
|
|
31934
|
-
}
|
|
31935
|
-
__name(writeCache, "writeCache");
|
|
31936
|
-
function parseVersion(version2) {
|
|
31937
|
-
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(version2.trim());
|
|
31938
|
-
if (!match) {
|
|
31939
|
-
return null;
|
|
31940
|
-
}
|
|
31941
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
31942
|
-
}
|
|
31943
|
-
__name(parseVersion, "parseVersion");
|
|
31944
|
-
function isNewerVersion(candidate, current) {
|
|
31945
|
-
const parsedCandidate = parseVersion(candidate);
|
|
31946
|
-
const parsedCurrent = parseVersion(current);
|
|
31947
|
-
if (!parsedCandidate || !parsedCurrent) {
|
|
31948
|
-
return false;
|
|
31949
|
-
}
|
|
31950
|
-
for (let index = 0; index < 3; index += 1) {
|
|
31951
|
-
if (parsedCandidate[index] !== parsedCurrent[index]) {
|
|
31952
|
-
return parsedCandidate[index] > parsedCurrent[index];
|
|
31953
|
-
}
|
|
31954
|
-
}
|
|
31955
|
-
return false;
|
|
31956
|
-
}
|
|
31957
|
-
__name(isNewerVersion, "isNewerVersion");
|
|
31958
|
-
function loadPackageMeta() {
|
|
31959
|
-
if (true) {
|
|
31960
|
-
return { name: "@duvoai/cli", version: "1.30.0" };
|
|
31961
|
-
}
|
|
31962
|
-
const require2 = createRequire(import.meta.url);
|
|
31963
|
-
const raw = require2("../package.json");
|
|
31964
|
-
if (typeof raw !== "object" || raw === null || !("name" in raw) || !("version" in raw) || typeof raw.name !== "string" || typeof raw.version !== "string") {
|
|
31965
|
-
throw new Error("package.json is missing name or version");
|
|
31966
|
-
}
|
|
31967
|
-
const typed = raw;
|
|
31968
|
-
return { name: typed.name, version: typed.version };
|
|
31969
|
-
}
|
|
31970
|
-
__name(loadPackageMeta, "loadPackageMeta");
|
|
31971
|
-
|
|
31972
32521
|
// src/bin/duvo.ts
|
|
31973
32522
|
void checkForUpdate();
|
|
31974
32523
|
createProgram().parseAsync(process.argv).catch((error) => {
|