@builder.io/ai-utils 0.84.0-dev.202607212345.137e4170f → 0.85.0-dev.202607231533.14c8ab346
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/package.json +1 -1
- package/src/events.d.ts +2 -0
- package/src/projects.d.ts +70 -2
- package/src/projects.js +84 -2
- package/src/perf-report.d.ts +0 -116
- package/src/perf-report.js +0 -122
package/package.json
CHANGED
package/src/events.d.ts
CHANGED
|
@@ -598,6 +598,8 @@ export type BotMentionGitHubInternalPrV1 = FusionEventVariant<"bot.mention.githu
|
|
|
598
598
|
/** Numeric GitHub comment ID (for reaction / reply threading) */
|
|
599
599
|
commentNumericId?: number;
|
|
600
600
|
commentType: "issue" | "pr";
|
|
601
|
+
/** Whether the normal bot-mention pipeline should post successful agent text. */
|
|
602
|
+
postSuccessResultComment?: boolean;
|
|
601
603
|
/** GitHub Enterprise hostname, if applicable */
|
|
602
604
|
hostname?: string;
|
|
603
605
|
/** For review comments: the comment being replied to */
|
package/src/projects.d.ts
CHANGED
|
@@ -1491,6 +1491,14 @@ export declare const ProjectHostingSchema: z.ZodObject<{
|
|
|
1491
1491
|
}>>;
|
|
1492
1492
|
publishedCommit: z.ZodOptional<z.ZodString>;
|
|
1493
1493
|
autoDeploy: z.ZodOptional<z.ZodBoolean>;
|
|
1494
|
+
unpublishTrigger: z.ZodOptional<z.ZodEnum<{
|
|
1495
|
+
system: "system";
|
|
1496
|
+
user: "user";
|
|
1497
|
+
}>>;
|
|
1498
|
+
systemUnpublishReason: z.ZodOptional<z.ZodEnum<{
|
|
1499
|
+
"bandwidth-cap": "bandwidth-cap";
|
|
1500
|
+
"web-request-cap": "web-request-cap";
|
|
1501
|
+
}>>;
|
|
1494
1502
|
domainIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
1495
1503
|
}, z.core.$strip>;
|
|
1496
1504
|
export type ProjectHosting = z.infer<typeof ProjectHostingSchema>;
|
|
@@ -1549,6 +1557,36 @@ export declare const HostingSlugSchema: z.ZodObject<{
|
|
|
1549
1557
|
createdBy: z.ZodString;
|
|
1550
1558
|
}, z.core.$strip>;
|
|
1551
1559
|
export type HostingSlug = z.infer<typeof HostingSlugSchema>;
|
|
1560
|
+
/**
|
|
1561
|
+
* Per-Neon-project charged-through watermarks inside a space's hosting usage
|
|
1562
|
+
* snapshot. Storage folds root + child branch bytes-month into one field.
|
|
1563
|
+
*/
|
|
1564
|
+
export declare const HostingNeonProjectUsageSchema: z.ZodObject<{
|
|
1565
|
+
computeUnitSecondsChargedThrough: z.ZodNumber;
|
|
1566
|
+
storageBytesMonthChargedThrough: z.ZodNumber;
|
|
1567
|
+
transferBytesChargedThrough: z.ZodNumber;
|
|
1568
|
+
}, z.core.$strip>;
|
|
1569
|
+
export type HostingNeonProjectUsage = z.infer<typeof HostingNeonProjectUsageSchema>;
|
|
1570
|
+
/**
|
|
1571
|
+
* Reconciler idempotency watermark for a space's Netlify + Neon hosting costs,
|
|
1572
|
+
* stored at `hostingUsageSnapshots/{spaceId}`. Netlify is one account-level
|
|
1573
|
+
* scalar; Neon is a per-project map. `freeDeployCount` gates the free 5/mo
|
|
1574
|
+
* deploy cap (cost itself is inside Netlify's partner_account_usage total).
|
|
1575
|
+
*/
|
|
1576
|
+
export declare const HostingUsageSnapshotSchema: z.ZodObject<{
|
|
1577
|
+
ownerId: z.ZodString;
|
|
1578
|
+
periodKey: z.ZodString;
|
|
1579
|
+
netlifyConsumptionCycleStart: z.ZodString;
|
|
1580
|
+
netlifyCreditsChargedThrough: z.ZodNumber;
|
|
1581
|
+
neonByProject: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1582
|
+
computeUnitSecondsChargedThrough: z.ZodNumber;
|
|
1583
|
+
storageBytesMonthChargedThrough: z.ZodNumber;
|
|
1584
|
+
transferBytesChargedThrough: z.ZodNumber;
|
|
1585
|
+
}, z.core.$strip>>;
|
|
1586
|
+
freeDeployCount: z.ZodNumber;
|
|
1587
|
+
updatedAt: z.ZodNumber;
|
|
1588
|
+
}, z.core.$strip>;
|
|
1589
|
+
export type HostingUsageSnapshot = z.infer<typeof HostingUsageSnapshotSchema>;
|
|
1552
1590
|
/**
|
|
1553
1591
|
* Deploy lease lock with fencing token, stored at
|
|
1554
1592
|
* `hosting-locks/{projectId}__{checkoutBranch}` (the key uses the resolved ref
|
|
@@ -1724,9 +1762,21 @@ export declare const HostingDomainKindSchema: z.ZodEnum<{
|
|
|
1724
1762
|
}>;
|
|
1725
1763
|
export type HostingDomainKind = z.infer<typeof HostingDomainKindSchema>;
|
|
1726
1764
|
/**
|
|
1727
|
-
* Custom domain record
|
|
1765
|
+
* Custom domain record. The same shape backs two Firestore collections:
|
|
1766
|
+
*
|
|
1767
|
+
* - Lock doc `hosting-domains/{domain}` is the single exclusive owner. It
|
|
1768
|
+
* exists only once a project reaches `provisioning`/`active` (cert + route
|
|
1769
|
+
* created, DNS ownership proven) and is the cross-project serialization
|
|
1770
|
+
* point serving/deploy/unpublish read to answer "is this verified?".
|
|
1771
|
+
* `certId`/`certMapEntryName`/`httpRouteName`/`verifiedAt` are only ever
|
|
1772
|
+
* populated here.
|
|
1773
|
+
* - Claim subdoc `hosting-domains/{domain}/claims/{projectId}` is a
|
|
1774
|
+
* non-exclusive, per-project verification attempt (`pending`/`verifying`/
|
|
1775
|
+
* `failed`). Multiple projects can hold a claim on the same domain at once;
|
|
1776
|
+
* whoever proves DNS ownership first wins the lock and the losers are swept
|
|
1777
|
+
* to `failed`.
|
|
1778
|
+
*
|
|
1728
1779
|
* The normalized domain is the doc key — global uniqueness comes for free.
|
|
1729
|
-
* This doc is both the record AND the claim for the domain.
|
|
1730
1780
|
*/
|
|
1731
1781
|
export declare const HostingDomainSchema: z.ZodObject<{
|
|
1732
1782
|
domain: z.ZodString;
|
|
@@ -1759,6 +1809,8 @@ export declare const HostingDomainSchema: z.ZodObject<{
|
|
|
1759
1809
|
dns: "dns";
|
|
1760
1810
|
https: "https";
|
|
1761
1811
|
}>>;
|
|
1812
|
+
routeError: z.ZodOptional<z.ZodString>;
|
|
1813
|
+
routeErrorAt: z.ZodOptional<z.ZodNumber>;
|
|
1762
1814
|
createdBy: z.ZodString;
|
|
1763
1815
|
}, z.core.$strip>;
|
|
1764
1816
|
export type HostingDomain = z.infer<typeof HostingDomainSchema>;
|
|
@@ -1817,6 +1869,22 @@ export declare const RemoveDomainResponseSchema: z.ZodObject<{
|
|
|
1817
1869
|
success: z.ZodLiteral<true>;
|
|
1818
1870
|
}, z.core.$strip>;
|
|
1819
1871
|
export type RemoveDomainResponse = z.infer<typeof RemoveDomainResponseSchema>;
|
|
1872
|
+
export declare const RepairDomainRequestSchema: z.ZodObject<{
|
|
1873
|
+
projectId: z.ZodString;
|
|
1874
|
+
domain: z.ZodString;
|
|
1875
|
+
}, z.core.$strip>;
|
|
1876
|
+
export type RepairDomainRequest = z.infer<typeof RepairDomainRequestSchema>;
|
|
1877
|
+
export declare const RepairDomainResponseSchema: z.ZodObject<{
|
|
1878
|
+
status: z.ZodEnum<{
|
|
1879
|
+
active: "active";
|
|
1880
|
+
failed: "failed";
|
|
1881
|
+
pending: "pending";
|
|
1882
|
+
provisioning: "provisioning";
|
|
1883
|
+
verifying: "verifying";
|
|
1884
|
+
}>;
|
|
1885
|
+
routeError: z.ZodOptional<z.ZodString>;
|
|
1886
|
+
}, z.core.$strip>;
|
|
1887
|
+
export type RepairDomainResponse = z.infer<typeof RepairDomainResponseSchema>;
|
|
1820
1888
|
export declare const CloneProjectOptionsSchema: z.ZodObject<{
|
|
1821
1889
|
sourceProjectId: z.ZodString;
|
|
1822
1890
|
sourceBranchName: z.ZodDefault<z.ZodString>;
|
package/src/projects.js
CHANGED
|
@@ -328,6 +328,26 @@ export const ProjectHostingSchema = z.object({
|
|
|
328
328
|
.boolean()
|
|
329
329
|
.optional()
|
|
330
330
|
.meta({ description: "auto-deploy on push/merge" }),
|
|
331
|
+
/**
|
|
332
|
+
* Who last drove the site into `publishStatus: "unpublished"`. Absent is
|
|
333
|
+
* treated as `"user"`. `"system"` means free-tier usage-cap enforcement took
|
|
334
|
+
* the site down (deleted the HTTPRoute, kept the Netlify site) and the
|
|
335
|
+
* reconciler **may** auto-restore it — routing-only, no rebuild — once the cap
|
|
336
|
+
* clears. `"user"` (or absent) means the user unpublished, so the reconciler
|
|
337
|
+
* must leave it down. The publish/unpublish hosting lock keeps this honest:
|
|
338
|
+
* whichever operation wins the lock is the one that writes `publishStatus`
|
|
339
|
+
* and this field, so they never disagree.
|
|
340
|
+
*/
|
|
341
|
+
unpublishTrigger: z.enum(["system", "user"]).optional().meta({
|
|
342
|
+
description: "Who last unpublished the site. Absent === user. 'system' lets the reconciler auto-restore a usage-cap takedown; 'user' does not.",
|
|
343
|
+
}),
|
|
344
|
+
/**
|
|
345
|
+
* Why the system unpublished the site. Set iff `unpublishTrigger === "system"`;
|
|
346
|
+
* drives the projects-grid "suspended" card and takedown observability.
|
|
347
|
+
*/
|
|
348
|
+
systemUnpublishReason: z
|
|
349
|
+
.enum(["bandwidth-cap", "web-request-cap"])
|
|
350
|
+
.optional(),
|
|
331
351
|
domainIds: z.array(z.string()).optional().meta({
|
|
332
352
|
description: "Doc keys (normalized domains) in `hosting-domains` attached to this project. The domain docs are the source of truth; this is only the back-pointer.",
|
|
333
353
|
}),
|
|
@@ -411,6 +431,42 @@ export const HostingSlugSchema = z.object({
|
|
|
411
431
|
description: "user ID of the user who first clicked Publish on the project",
|
|
412
432
|
}),
|
|
413
433
|
});
|
|
434
|
+
/**
|
|
435
|
+
* Per-Neon-project charged-through watermarks inside a space's hosting usage
|
|
436
|
+
* snapshot. Storage folds root + child branch bytes-month into one field.
|
|
437
|
+
*/
|
|
438
|
+
export const HostingNeonProjectUsageSchema = z.object({
|
|
439
|
+
computeUnitSecondsChargedThrough: z.number(),
|
|
440
|
+
storageBytesMonthChargedThrough: z.number().meta({
|
|
441
|
+
description: "root + child branch bytes-month already billed",
|
|
442
|
+
}),
|
|
443
|
+
transferBytesChargedThrough: z.number().meta({
|
|
444
|
+
description: "public network transfer bytes already billed",
|
|
445
|
+
}),
|
|
446
|
+
});
|
|
447
|
+
/**
|
|
448
|
+
* Reconciler idempotency watermark for a space's Netlify + Neon hosting costs,
|
|
449
|
+
* stored at `hostingUsageSnapshots/{spaceId}`. Netlify is one account-level
|
|
450
|
+
* scalar; Neon is a per-project map. `freeDeployCount` gates the free 5/mo
|
|
451
|
+
* deploy cap (cost itself is inside Netlify's partner_account_usage total).
|
|
452
|
+
*/
|
|
453
|
+
export const HostingUsageSnapshotSchema = z.object({
|
|
454
|
+
ownerId: z.string(),
|
|
455
|
+
periodKey: z.string().meta({
|
|
456
|
+
description: "Builder billing cycle; resets the Neon watermarks",
|
|
457
|
+
}),
|
|
458
|
+
netlifyConsumptionCycleStart: z.string().meta({
|
|
459
|
+
description: "Netlify consumption_cycle_start_date; watermark resets when this advances",
|
|
460
|
+
}),
|
|
461
|
+
netlifyCreditsChargedThrough: z.number().meta({
|
|
462
|
+
description: "Netlify credits already billed this Netlify cycle",
|
|
463
|
+
}),
|
|
464
|
+
neonByProject: z.record(z.string(), HostingNeonProjectUsageSchema),
|
|
465
|
+
freeDeployCount: z.number().meta({
|
|
466
|
+
description: "Deploys this Builder cycle, for the free 5/mo cap",
|
|
467
|
+
}),
|
|
468
|
+
updatedAt: z.number(),
|
|
469
|
+
});
|
|
414
470
|
/**
|
|
415
471
|
* Deploy lease lock with fencing token, stored at
|
|
416
472
|
* `hosting-locks/{projectId}__{checkoutBranch}` (the key uses the resolved ref
|
|
@@ -625,9 +681,21 @@ export const HostingDomainStatusSchema = z.enum([
|
|
|
625
681
|
]);
|
|
626
682
|
export const HostingDomainKindSchema = z.enum(["apex", "subdomain"]);
|
|
627
683
|
/**
|
|
628
|
-
* Custom domain record
|
|
684
|
+
* Custom domain record. The same shape backs two Firestore collections:
|
|
685
|
+
*
|
|
686
|
+
* - Lock doc `hosting-domains/{domain}` is the single exclusive owner. It
|
|
687
|
+
* exists only once a project reaches `provisioning`/`active` (cert + route
|
|
688
|
+
* created, DNS ownership proven) and is the cross-project serialization
|
|
689
|
+
* point serving/deploy/unpublish read to answer "is this verified?".
|
|
690
|
+
* `certId`/`certMapEntryName`/`httpRouteName`/`verifiedAt` are only ever
|
|
691
|
+
* populated here.
|
|
692
|
+
* - Claim subdoc `hosting-domains/{domain}/claims/{projectId}` is a
|
|
693
|
+
* non-exclusive, per-project verification attempt (`pending`/`verifying`/
|
|
694
|
+
* `failed`). Multiple projects can hold a claim on the same domain at once;
|
|
695
|
+
* whoever proves DNS ownership first wins the lock and the losers are swept
|
|
696
|
+
* to `failed`.
|
|
697
|
+
*
|
|
629
698
|
* The normalized domain is the doc key — global uniqueness comes for free.
|
|
630
|
-
* This doc is both the record AND the claim for the domain.
|
|
631
699
|
*/
|
|
632
700
|
export const HostingDomainSchema = z.object({
|
|
633
701
|
domain: z
|
|
@@ -667,6 +735,12 @@ export const HostingDomainSchema = z.object({
|
|
|
667
735
|
failedStep: z.enum(["dns", "https"]).optional().meta({
|
|
668
736
|
description: "Which setup step failed, set alongside `status: failed` so the UI can attribute the failure. `dns` = delegation verification, `https` = cert/route provisioning.",
|
|
669
737
|
}),
|
|
738
|
+
routeError: z.string().optional().meta({
|
|
739
|
+
description: "Non-fatal health signal on an otherwise verified (`provisioning`/`active`) domain: set when re-creating the Envoy HTTPRoute failed on republish, so the site's cert is valid but the custom domain has no live route (bare 404). `status` stays `active`; this drives a degraded banner + Fix action. Cleared once the route is recreated.",
|
|
740
|
+
}),
|
|
741
|
+
routeErrorAt: z.number().optional().meta({
|
|
742
|
+
description: "When `routeError` was last set.",
|
|
743
|
+
}),
|
|
670
744
|
createdBy: z.string(),
|
|
671
745
|
});
|
|
672
746
|
export const AddDomainRequestSchema = z.object({
|
|
@@ -700,6 +774,14 @@ export const RemoveDomainRequestSchema = z.object({
|
|
|
700
774
|
export const RemoveDomainResponseSchema = z.object({
|
|
701
775
|
success: z.literal(true),
|
|
702
776
|
});
|
|
777
|
+
export const RepairDomainRequestSchema = z.object({
|
|
778
|
+
projectId: z.string(),
|
|
779
|
+
domain: z.string(),
|
|
780
|
+
});
|
|
781
|
+
export const RepairDomainResponseSchema = z.object({
|
|
782
|
+
status: HostingDomainStatusSchema,
|
|
783
|
+
routeError: z.string().optional(),
|
|
784
|
+
});
|
|
703
785
|
export const CloneProjectOptionsSchema = z.object({
|
|
704
786
|
sourceProjectId: z.string().min(1).meta({
|
|
705
787
|
description: "Project to clone from.",
|
package/src/perf-report.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
export declare const CURRENT_PERF_REPORT_SCHEMA_VERSION = 1;
|
|
3
|
-
export declare const PerfIncidentTypeSchema: z.ZodEnum<{
|
|
4
|
-
hang: "hang";
|
|
5
|
-
"memory-pressure": "memory-pressure";
|
|
6
|
-
"recovered-hang": "recovered-hang";
|
|
7
|
-
"recovered-unclean-exit": "recovered-unclean-exit";
|
|
8
|
-
"renderer-crash": "renderer-crash";
|
|
9
|
-
}>;
|
|
10
|
-
export type PerfIncidentType = z.infer<typeof PerfIncidentTypeSchema>;
|
|
11
|
-
export declare const PerfProcessSchema: z.ZodObject<{
|
|
12
|
-
kind: z.ZodEnum<{
|
|
13
|
-
browser: "browser";
|
|
14
|
-
child: "child";
|
|
15
|
-
gpu: "gpu";
|
|
16
|
-
renderer: "renderer";
|
|
17
|
-
utility: "utility";
|
|
18
|
-
}>;
|
|
19
|
-
pid: z.ZodNumber;
|
|
20
|
-
memoryKb: z.ZodNumber;
|
|
21
|
-
cpuPercent: z.ZodNumber;
|
|
22
|
-
tabId: z.ZodOptional<z.ZodString>;
|
|
23
|
-
}, z.core.$strip>;
|
|
24
|
-
export type PerfProcess = z.infer<typeof PerfProcessSchema>;
|
|
25
|
-
export declare const PerfTabSchema: z.ZodObject<{
|
|
26
|
-
tabId: z.ZodString;
|
|
27
|
-
route: z.ZodOptional<z.ZodString>;
|
|
28
|
-
feature: z.ZodOptional<z.ZodString>;
|
|
29
|
-
jsHeapUsedKb: z.ZodOptional<z.ZodNumber>;
|
|
30
|
-
jsHeapLimitKb: z.ZodOptional<z.ZodNumber>;
|
|
31
|
-
subsystems: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
32
|
-
livenessLatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
33
|
-
}, z.core.$strip>;
|
|
34
|
-
export type PerfTab = z.infer<typeof PerfTabSchema>;
|
|
35
|
-
export declare const PerfSampleSchema: z.ZodObject<{
|
|
36
|
-
t: z.ZodNumber;
|
|
37
|
-
desktopFootprintKb: z.ZodNumber;
|
|
38
|
-
freeMemoryKb: z.ZodNumber;
|
|
39
|
-
perTabHeapKb: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
40
|
-
}, z.core.$strip>;
|
|
41
|
-
export type PerfSample = z.infer<typeof PerfSampleSchema>;
|
|
42
|
-
export declare const PerfReportSchema: z.ZodObject<{
|
|
43
|
-
schemaVersion: z.ZodNumber;
|
|
44
|
-
incidentType: z.ZodEnum<{
|
|
45
|
-
hang: "hang";
|
|
46
|
-
"memory-pressure": "memory-pressure";
|
|
47
|
-
"recovered-hang": "recovered-hang";
|
|
48
|
-
"recovered-unclean-exit": "recovered-unclean-exit";
|
|
49
|
-
"renderer-crash": "renderer-crash";
|
|
50
|
-
}>;
|
|
51
|
-
sessionId: z.ZodString;
|
|
52
|
-
deviceId: z.ZodString;
|
|
53
|
-
appVersion: z.ZodString;
|
|
54
|
-
platform: z.ZodEnum<{
|
|
55
|
-
darwin: "darwin";
|
|
56
|
-
linux: "linux";
|
|
57
|
-
win32: "win32";
|
|
58
|
-
}>;
|
|
59
|
-
channel: z.ZodEnum<{
|
|
60
|
-
alpha: "alpha";
|
|
61
|
-
stable: "stable";
|
|
62
|
-
}>;
|
|
63
|
-
timestamp: z.ZodNumber;
|
|
64
|
-
machine: z.ZodObject<{
|
|
65
|
-
totalMemoryKb: z.ZodNumber;
|
|
66
|
-
freeMemoryKb: z.ZodNumber;
|
|
67
|
-
desktopFootprintKb: z.ZodNumber;
|
|
68
|
-
}, z.core.$strip>;
|
|
69
|
-
processes: z.ZodArray<z.ZodObject<{
|
|
70
|
-
kind: z.ZodEnum<{
|
|
71
|
-
browser: "browser";
|
|
72
|
-
child: "child";
|
|
73
|
-
gpu: "gpu";
|
|
74
|
-
renderer: "renderer";
|
|
75
|
-
utility: "utility";
|
|
76
|
-
}>;
|
|
77
|
-
pid: z.ZodNumber;
|
|
78
|
-
memoryKb: z.ZodNumber;
|
|
79
|
-
cpuPercent: z.ZodNumber;
|
|
80
|
-
tabId: z.ZodOptional<z.ZodString>;
|
|
81
|
-
}, z.core.$strip>>;
|
|
82
|
-
tabs: z.ZodArray<z.ZodObject<{
|
|
83
|
-
tabId: z.ZodString;
|
|
84
|
-
route: z.ZodOptional<z.ZodString>;
|
|
85
|
-
feature: z.ZodOptional<z.ZodString>;
|
|
86
|
-
jsHeapUsedKb: z.ZodOptional<z.ZodNumber>;
|
|
87
|
-
jsHeapLimitKb: z.ZodOptional<z.ZodNumber>;
|
|
88
|
-
subsystems: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
89
|
-
livenessLatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
90
|
-
}, z.core.$strip>>;
|
|
91
|
-
crash: z.ZodOptional<z.ZodObject<{
|
|
92
|
-
reason: z.ZodString;
|
|
93
|
-
exitCode: z.ZodOptional<z.ZodNumber>;
|
|
94
|
-
oom: z.ZodOptional<z.ZodBoolean>;
|
|
95
|
-
}, z.core.$strip>>;
|
|
96
|
-
hang: z.ZodOptional<z.ZodObject<{
|
|
97
|
-
startedAt: z.ZodNumber;
|
|
98
|
-
durationMs: z.ZodNumber;
|
|
99
|
-
recovered: z.ZodBoolean;
|
|
100
|
-
surface: z.ZodString;
|
|
101
|
-
}, z.core.$strip>>;
|
|
102
|
-
samples: z.ZodArray<z.ZodObject<{
|
|
103
|
-
t: z.ZodNumber;
|
|
104
|
-
desktopFootprintKb: z.ZodNumber;
|
|
105
|
-
freeMemoryKb: z.ZodNumber;
|
|
106
|
-
perTabHeapKb: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
107
|
-
}, z.core.$strip>>;
|
|
108
|
-
}, z.core.$strip>;
|
|
109
|
-
export type PerfReport = z.infer<typeof PerfReportSchema>;
|
|
110
|
-
/**
|
|
111
|
-
* Collapses opaque identifiers out of a route/URL so a report can't carry a
|
|
112
|
-
* project/space id. Keeps the structural shape (which screen was open) while
|
|
113
|
-
* masking the specific resource.
|
|
114
|
-
*/
|
|
115
|
-
export declare function redactPerfRoute(route: string | undefined): string | undefined;
|
|
116
|
-
export declare function redactPerfReport(report: PerfReport): PerfReport;
|
package/src/perf-report.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
// ============================================================================
|
|
3
|
-
// Desktop performance & crash monitoring wire contract.
|
|
4
|
-
//
|
|
5
|
-
// Canonical schema. The Electron desktop app lives in a separate workspace and
|
|
6
|
-
// cannot import this file, so it keeps a hand-mirrored TypeScript type in
|
|
7
|
-
// code/packages/electron-app/src/perf-report.types.ts. Keep the two in sync and
|
|
8
|
-
// bump CURRENT_PERF_REPORT_SCHEMA_VERSION on any breaking shape change.
|
|
9
|
-
// ============================================================================
|
|
10
|
-
export const CURRENT_PERF_REPORT_SCHEMA_VERSION = 1;
|
|
11
|
-
export const PerfIncidentTypeSchema = z.enum([
|
|
12
|
-
"renderer-crash",
|
|
13
|
-
"hang",
|
|
14
|
-
"recovered-hang",
|
|
15
|
-
"memory-pressure",
|
|
16
|
-
"recovered-unclean-exit",
|
|
17
|
-
]);
|
|
18
|
-
export const PerfProcessSchema = z.object({
|
|
19
|
-
kind: z.enum(["browser", "renderer", "gpu", "utility", "child"]),
|
|
20
|
-
pid: z.number(),
|
|
21
|
-
memoryKb: z.number(),
|
|
22
|
-
cpuPercent: z.number(),
|
|
23
|
-
tabId: z.string().optional(),
|
|
24
|
-
});
|
|
25
|
-
export const PerfTabSchema = z.object({
|
|
26
|
-
tabId: z.string(),
|
|
27
|
-
route: z.string().optional(),
|
|
28
|
-
feature: z.string().optional(),
|
|
29
|
-
jsHeapUsedKb: z.number().optional(),
|
|
30
|
-
jsHeapLimitKb: z.number().optional(),
|
|
31
|
-
subsystems: z.record(z.string(), z.number()),
|
|
32
|
-
livenessLatencyMs: z.number().optional(),
|
|
33
|
-
});
|
|
34
|
-
export const PerfSampleSchema = z.object({
|
|
35
|
-
t: z.number(),
|
|
36
|
-
desktopFootprintKb: z.number(),
|
|
37
|
-
freeMemoryKb: z.number(),
|
|
38
|
-
perTabHeapKb: z.record(z.string(), z.number()),
|
|
39
|
-
});
|
|
40
|
-
export const PerfReportSchema = z.object({
|
|
41
|
-
schemaVersion: z.number(),
|
|
42
|
-
incidentType: PerfIncidentTypeSchema,
|
|
43
|
-
sessionId: z.string(),
|
|
44
|
-
deviceId: z.string(),
|
|
45
|
-
appVersion: z.string(),
|
|
46
|
-
platform: z.enum(["darwin", "win32", "linux"]),
|
|
47
|
-
channel: z.enum(["stable", "alpha"]),
|
|
48
|
-
timestamp: z.number(),
|
|
49
|
-
machine: z.object({
|
|
50
|
-
totalMemoryKb: z.number(),
|
|
51
|
-
freeMemoryKb: z.number(),
|
|
52
|
-
desktopFootprintKb: z.number(),
|
|
53
|
-
}),
|
|
54
|
-
processes: z.array(PerfProcessSchema),
|
|
55
|
-
tabs: z.array(PerfTabSchema),
|
|
56
|
-
crash: z
|
|
57
|
-
.object({
|
|
58
|
-
reason: z.string(),
|
|
59
|
-
exitCode: z.number().optional(),
|
|
60
|
-
oom: z.boolean().optional(),
|
|
61
|
-
})
|
|
62
|
-
.optional(),
|
|
63
|
-
hang: z
|
|
64
|
-
.object({
|
|
65
|
-
startedAt: z.number(),
|
|
66
|
-
durationMs: z.number(),
|
|
67
|
-
recovered: z.boolean(),
|
|
68
|
-
surface: z.string(),
|
|
69
|
-
})
|
|
70
|
-
.optional(),
|
|
71
|
-
samples: z.array(PerfSampleSchema),
|
|
72
|
-
});
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// Route/URL redaction. The desktop client redacts before sending; this runs
|
|
75
|
-
// again at ingest (defense in depth) because the service cannot import the
|
|
76
|
-
// renderer's redactSnapshot helper across the workspace boundary.
|
|
77
|
-
// ---------------------------------------------------------------------------
|
|
78
|
-
const PROJECT_ID_SEGMENTS = new Set([
|
|
79
|
-
"projects",
|
|
80
|
-
"content",
|
|
81
|
-
"fusion",
|
|
82
|
-
"space",
|
|
83
|
-
"org",
|
|
84
|
-
"organization",
|
|
85
|
-
]);
|
|
86
|
-
/**
|
|
87
|
-
* Collapses opaque identifiers out of a route/URL so a report can't carry a
|
|
88
|
-
* project/space id. Keeps the structural shape (which screen was open) while
|
|
89
|
-
* masking the specific resource.
|
|
90
|
-
*/
|
|
91
|
-
export function redactPerfRoute(route) {
|
|
92
|
-
if (!route) {
|
|
93
|
-
return route;
|
|
94
|
-
}
|
|
95
|
-
const [pathPart] = route.split("?");
|
|
96
|
-
const segments = pathPart.split("/");
|
|
97
|
-
const redacted = segments.map((segment, index) => {
|
|
98
|
-
var _a;
|
|
99
|
-
if (!segment) {
|
|
100
|
-
return segment;
|
|
101
|
-
}
|
|
102
|
-
const previous = (_a = segments[index - 1]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
103
|
-
if (previous && PROJECT_ID_SEGMENTS.has(previous)) {
|
|
104
|
-
return ":id";
|
|
105
|
-
}
|
|
106
|
-
// Bare id-looking segments (uuids, long hex/base62 tokens).
|
|
107
|
-
if (/^[0-9a-f]{16,}$/i.test(segment) || /^[0-9a-z]{20,}$/i.test(segment)) {
|
|
108
|
-
return ":id";
|
|
109
|
-
}
|
|
110
|
-
return segment;
|
|
111
|
-
});
|
|
112
|
-
return redacted.join("/");
|
|
113
|
-
}
|
|
114
|
-
export function redactPerfReport(report) {
|
|
115
|
-
return {
|
|
116
|
-
...report,
|
|
117
|
-
tabs: report.tabs.map((tab) => ({
|
|
118
|
-
...tab,
|
|
119
|
-
route: redactPerfRoute(tab.route),
|
|
120
|
-
})),
|
|
121
|
-
};
|
|
122
|
-
}
|