t3code-cli 0.14.2 → 0.15.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 +36 -1
- package/dist/application.d.ts +2 -2
- package/dist/application.js +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.js +1 -1
- package/dist/bin.js +935 -336
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/client-runtime/authorization.d.ts +1 -1
- package/dist/client-runtime/authorization.js +1 -1
- package/dist/client-runtime/connection.d.ts +1 -1
- package/dist/client-runtime/connection.js +1 -1
- package/dist/client-runtime/environment.d.ts +3 -1
- package/dist/client-runtime/environment.js +1 -1
- package/dist/client-runtime/errors.js +1 -1
- package/dist/client-runtime/operations/projects.d.ts +1 -1
- package/dist/client-runtime/operations.d.ts +1 -1
- package/dist/client-runtime/platform.d.ts +1 -1
- package/dist/client-runtime/platform.js +1 -1
- package/dist/client-runtime/relay.d.ts +9 -2
- package/dist/client-runtime/relay.js +12 -2
- package/dist/client-runtime/rpc.d.ts +2 -2
- package/dist/client-runtime/rpc.js +2 -2
- package/dist/client-runtime/state/assets.d.ts +1 -1
- package/dist/client-runtime/state/assets.js +1 -1
- package/dist/client-runtime/state/auth.d.ts +1 -1
- package/dist/client-runtime/state/auth.js +1 -1
- package/dist/client-runtime/state/connections.js +1 -1
- package/dist/client-runtime/state/entities.d.ts +1 -1
- package/dist/client-runtime/state/filesystem.d.ts +1 -1
- package/dist/client-runtime/state/filesystem.js +1 -1
- package/dist/client-runtime/state/git.d.ts +2 -1
- package/dist/client-runtime/state/git.js +1 -1
- package/dist/client-runtime/state/models.d.ts +1 -1
- package/dist/client-runtime/state/models.js +1 -1
- package/dist/client-runtime/state/orchestration.d.ts +1 -1
- package/dist/client-runtime/state/orchestration.js +1 -1
- package/dist/client-runtime/state/presentation.d.ts +7 -1
- package/dist/client-runtime/state/presentation.js +1 -1
- package/dist/client-runtime/state/preview.d.ts +5 -2
- package/dist/client-runtime/state/preview.js +3 -2
- package/dist/client-runtime/state/project-grouping.d.ts +1 -1
- package/dist/client-runtime/state/project-grouping.js +1 -1
- package/dist/client-runtime/state/projects.d.ts +1 -1
- package/dist/client-runtime/state/pull-requests.d.ts +478 -0
- package/dist/client-runtime/state/pull-requests.js +172 -0
- package/dist/client-runtime/state/relay.d.ts +1 -1
- package/dist/client-runtime/state/relay.js +1 -1
- package/dist/client-runtime/state/review.d.ts +1 -1
- package/dist/client-runtime/state/review.js +1 -1
- package/dist/client-runtime/state/runtime.d.ts +2 -2
- package/dist/client-runtime/state/runtime.js +2 -2
- package/dist/client-runtime/state/server.d.ts +13 -1
- package/dist/client-runtime/state/server.js +1 -1
- package/dist/client-runtime/state/session.d.ts +13 -1
- package/dist/client-runtime/state/session.js +1 -1
- package/dist/client-runtime/state/shell.d.ts +7 -1
- package/dist/client-runtime/state/shell.js +1 -1
- package/dist/client-runtime/state/source-control.d.ts +1 -1
- package/dist/client-runtime/state/source-control.js +1 -1
- package/dist/client-runtime/state/subagentRuntime.d.ts +1 -1
- package/dist/client-runtime/state/terminal.d.ts +1 -1
- package/dist/client-runtime/state/terminal.js +1 -1
- package/dist/client-runtime/state/thread-search.d.ts +1 -1
- package/dist/client-runtime/state/thread-search.js +1 -1
- package/dist/client-runtime/state/thread-settled.d.ts +11 -8
- package/dist/client-runtime/state/thread-settled.js +2 -229
- package/dist/client-runtime/state/thread-sort.d.ts +1 -1
- package/dist/client-runtime/state/thread-sort.js +1 -1
- package/dist/client-runtime/state/threads.d.ts +1 -1
- package/dist/client-runtime/state/threads.js +1 -1
- package/dist/client-runtime/state/vcs.d.ts +1 -1
- package/dist/client-runtime/state/vcs.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/connection.d.ts +1 -1
- package/dist/connection.js +1 -1
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/orchestration.d.ts +12 -6
- package/dist/orchestration.js +2 -2
- package/dist/preview.d.ts +1 -1
- package/dist/rpc.d.ts +4 -9
- package/dist/rpc.js +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/shared/DrainableWorker.js +1 -1
- package/dist/shared/KeyedCoalescingWorker.js +1 -1
- package/dist/shared/Net.d.ts +6 -0
- package/dist/shared/Net.js +2 -1
- package/dist/shared/advertisedEndpoint.d.ts +1 -1
- package/dist/shared/advertisedEndpoint.js +1 -1
- package/dist/shared/agentAwareness.d.ts +1 -1
- package/dist/shared/backgroundActivitySettings.d.ts +1 -1
- package/dist/shared/connectAuth.d.ts +23 -4
- package/dist/shared/connectAuth.js +40 -7
- package/dist/shared/devHome.js +1 -1
- package/dist/shared/dpop.js +1 -1
- package/dist/shared/git.d.ts +1 -1
- package/dist/shared/httpObservability.js +1 -1
- package/dist/shared/httpReadiness.js +1 -1
- package/dist/shared/keybindings.d.ts +1 -1
- package/dist/shared/model.d.ts +1 -1
- package/dist/shared/oauthScope.js +1 -1
- package/dist/shared/observability.js +1 -1
- package/dist/shared/preview.js +1 -1
- package/dist/shared/previewViewport.d.ts +1 -1
- package/dist/shared/previewViewport.js +1 -1
- package/dist/shared/projectScripts.d.ts +1 -1
- package/dist/shared/relayAuth.js +1 -1
- package/dist/shared/relayClient.d.ts +1 -1
- package/dist/shared/relayClient.js +1 -1
- package/dist/shared/relayJwt.js +1 -1
- package/dist/shared/relayTracing.js +1 -1
- package/dist/shared/relayUrl.js +1 -1
- package/dist/shared/remote.js +1 -1
- package/dist/shared/schemaYaml.js +1 -1
- package/dist/shared/serverSettings.d.ts +1 -1
- package/dist/shared/serverSettings.js +1 -1
- package/dist/shared/shell.js +1 -1
- package/dist/shared/sourceControl.d.ts +1 -1
- package/dist/shared/t3ProjectFile.d.ts +1 -1
- package/dist/shared/t3ProjectFile.js +1 -1
- package/dist/shared/terminalLabels.d.ts +1 -1
- package/dist/shared/threadEnvMode.d.ts +1 -1
- package/dist/shared/toolActivity.d.ts +1 -1
- package/dist/shared/usageFormat.d.ts +16 -3
- package/dist/shared/usageFormat.js +92 -6
- package/dist/shared/usageMerge.d.ts +13 -2
- package/dist/shared/usageMerge.js +23 -0
- package/dist/shared.d.ts +3470 -378
- package/dist/shared.js +2434 -617
- package/dist/t3tools.d.ts +2 -2
- package/dist/t3tools.js +2 -2
- package/package.json +2 -2
- package/src/application/error.ts +2 -2
- package/src/application/index.ts +1 -0
- package/src/application/service.ts +38 -4
- package/src/application/thread-commands.ts +78 -0
- package/src/application/threads.ts +113 -16
- package/src/cli/app.ts +2 -0
- package/src/cli/ask-lifecycle.ts +331 -0
- package/src/cli/ask.ts +390 -0
- package/src/cli/error.ts +70 -0
- package/src/cli/format/thread.ts +26 -6
- package/src/cli/thread.ts +12 -0
- package/src/cli/threads/messages.ts +33 -3
- package/src/cli/threads/pin.ts +46 -0
- package/src/cli/threads/send.ts +5 -1
- package/src/cli/threads/settle.ts +46 -0
- package/src/cli/threads/snooze.ts +117 -0
- package/src/cli/threads/start.ts +6 -1
- package/src/cli/threads/unpin.ts +48 -0
- package/src/cli/threads/unsettle.ts +48 -0
- package/src/cli/threads/unsnooze.ts +48 -0
- package/src/connection/prepared.ts +12 -2
- package/src/orchestration/error.ts +10 -0
- package/src/orchestration/index.ts +1 -0
- package/src/orchestration/layer.ts +72 -0
- package/src/orchestration/service.ts +11 -3
- package/src/rpc/ws-group.ts +1 -0
- package/src/runtime/layer.ts +9 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $j as ignore, AN as Service, BM as currentTimeMillis, BN as getOrUndefined, CA as Path, CD as filterStatusOk, GN as none, Gj as flatMap$1, HM as TaggedError, HN as isSome, KN as some, Kj as fn, Lj as catchTag, Mj as as, NM as void_, NN as flatMap, Qj as gen, SM as suspend, Sk as string, TA as FileSystem, Uj as fail, VN as isNone, Vj as ensuring, YM as effect, _A as encodeHex, aA as make$1, bM as sleep, bk as map, dM as orDie, eA as Crypto, fj as make, iM as mapError, sA as ChildProcessSpawner, uM as option$1, vD as HttpClient, vM as scoped, w as HostProcessPlatform, wD as get, xM as succeed, xk as option, y as HostProcessArchitecture, yk as all, zj as catch_ } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/relayClient.ts
|
|
3
3
|
const CLOUDFLARED_VERSION = "2026.5.2";
|
|
4
4
|
const CLOUDFLARED_PATH_ENV_NAME = "T3CODE_CLOUDFLARED_PATH";
|
package/dist/shared/relayJwt.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _o as verifyRelayJwt, co as RELAY_HEALTH_REQUEST_TYP, do as RELAY_MINT_REQUEST_TYP, fo as RELAY_MINT_RESPONSE_TYP, go as signRelayJwt, ho as normalizeRelayIssuer, lo as RELAY_HEALTH_RESPONSE_TYP, mo as decodeRelayJwt, po as RelayJwtError, so as RELAY_ACTIVITY_PUBLISH_TYP, uo as RELAY_LINK_PROOF_TYP } from "../shared.js";
|
|
2
2
|
export { RELAY_ACTIVITY_PUBLISH_TYP, RELAY_HEALTH_REQUEST_TYP, RELAY_HEALTH_RESPONSE_TYP, RELAY_LINK_PROOF_TYP, RELAY_MINT_REQUEST_TYP, RELAY_MINT_RESPONSE_TYP, RelayJwtError, decodeRelayJwt, normalizeRelayIssuer, signRelayJwt, verifyRelayJwt };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { is as withRelayClientTracing, ns as RelayClientTracer, rs as makeRelayClientTracingLayer } from "../shared.js";
|
|
2
2
|
export { RelayClientTracer, makeRelayClientTracingLayer, withRelayClientTracing };
|
package/dist/shared/relayUrl.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ao as isSecureRelayUrl, oo as normalizeSecureRelayUrl } from "../shared.js";
|
|
2
2
|
export { isSecureRelayUrl, normalizeSecureRelayUrl };
|
package/dist/shared/remote.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Aa as
|
|
1
|
+
import { Aa as readHashParams, Ca as RemoteBackendUrlInvalidError, Da as RemotePairingTokenMissingError, Ea as RemotePairingTargetError, Ma as resolveRemotePairingTarget, Na as setPairingTokenOnUrl, Oa as RemotePairingUrlInvalidError, Pa as stripPairingTokenFromUrl, Ta as RemotePairingCodeMissingError, ja as readHostedPairingRequest, ka as getPairingTokenFromUrl, wa as RemoteBackendUrlMissingError } from "../shared.js";
|
|
2
2
|
export { RemoteBackendUrlInvalidError, RemoteBackendUrlMissingError, RemotePairingCodeMissingError, RemotePairingTargetError, RemotePairingTokenMissingError, RemotePairingUrlInvalidError, getPairingTokenFromUrl, readHashParams, readHostedPairingRequest, resolveRemotePairingTarget, setPairingTokenOnUrl, stripPairingTokenFromUrl };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as __toESM } from "../rolldown-runtime.js";
|
|
2
|
-
import {
|
|
2
|
+
import { Lk as String, SA as InvalidValue, Uk as decodeTo, fA as Transformation, kM as try_, pA as transformOrFail, pk as require_dist } from "../shared.js";
|
|
3
3
|
//#region upstream-t3code/packages/shared/src/schemaYaml.ts
|
|
4
4
|
var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
|
|
5
5
|
function formatYamlParseError(error) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Qv as ServerSettingsPatch, Yv as ServerSettings, qu as ServerProvider, xy as ModelSelection } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/serverSettings.d.ts
|
|
3
3
|
declare function isModelSelectionProviderEnabled(settings: ServerSettings, selection: ModelSelection): boolean;
|
|
4
4
|
declare function resolveSourceControlWriterModelSelection(settings: ServerSettings, providers?: ReadonlyArray<ServerProvider>): ModelSelection;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DE as isProviderDriverKind, Gk as decodeUnknownOption, Gm as ServerSettings, HN as isSome, Jp as isProviderAvailable, N as createModelSelection, c as resolveBackgroundActivitySettings, g as fromLenientJson, i as getBackgroundActivityBaseProfile, o as normalizeBackgroundActivitySettings, s as normalizeServerBackgroundActivitySettings, u as deepMerge } from "../shared.js";
|
|
2
2
|
const decodeServerSettingsJson = decodeUnknownOption(fromLenientJson(ServerSettings));
|
|
3
3
|
const getLegacyProviderSettings = (settings, provider) => settings.providers[provider];
|
|
4
4
|
function isModelSelectionProviderEnabled(settings, selection) {
|
package/dist/shared/shell.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CA as Path, HM as TaggedError, Kj as fn, Lj as catchTag, Mj as as, TA as FileSystem, VM as currentTimeNanos, fM as orElseSucceed, kN as Reference, w as HostProcessPlatform, x as HostProcessEnvironment, xM as succeed } from "../shared.js";
|
|
2
2
|
import * as NodeOS from "node:os";
|
|
3
3
|
import * as NodeChildProcess from "node:child_process";
|
|
4
4
|
import * as NodeFS from "node:fs";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GD as SourceControlProviderKind, WD as SourceControlProviderInfo } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/sourceControl.d.ts
|
|
3
3
|
interface ChangeRequestPresentation {
|
|
4
4
|
readonly icon: "github" | "gitlab" | "azure-devops" | "bitbucket" | "change-request";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Hk as decodeExit, Qk as toJsonSchemaDocument, g as fromLenientJson, if as T3_PROJECT_FILE_SCHEMA_URL, lN as isSuccess, tf as T3ProjectFile } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/t3ProjectFile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Codec between the raw `t3.json` file contents (lenient JSONC string) and the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pC as TerminalSummary } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/terminalLabels.d.ts
|
|
3
3
|
/** Human-readable label for a terminal tab; matches mobile and web sidebars. */
|
|
4
4
|
declare function getTerminalLabel(terminalId: string): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jm as ToolLifecycleItemType } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/toolActivity.d.ts
|
|
3
3
|
interface ToolActivityPresentationInput {
|
|
4
4
|
readonly itemType?: ToolLifecycleItemType | null | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cl as UsageResolution, Ol as UsageSummaryInput } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/usageFormat.d.ts
|
|
3
3
|
declare function formatUsd(value: number): string;
|
|
4
4
|
declare function formatCount(value: number): string;
|
|
@@ -12,10 +12,23 @@ declare function formatPercent(share: number, digits?: number): string;
|
|
|
12
12
|
declare function formatDayShort(day: string): string;
|
|
13
13
|
/** Inclusive day list between two `YYYY-MM-DD` bounds. */
|
|
14
14
|
declare function enumerateDays(sinceDay: string, untilDay: string): readonly string[];
|
|
15
|
+
/** Every fixed-duration bucket start in an hourly rolling window. */
|
|
16
|
+
declare function enumerateHourStarts(sinceTime: string, untilTime: string): readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* A rolling bucket start rendered in the viewer's requested time zone.
|
|
19
|
+
*
|
|
20
|
+
* Repeated wall-clock hours during a fall-back transition include their short
|
|
21
|
+
* zone name so the two distinct buckets remain distinguishable.
|
|
22
|
+
*/
|
|
23
|
+
declare function formatHourShort(hourStart: string, timeZone?: string): string;
|
|
24
|
+
/** `2026-08-11T14:37:00Z` to `Aug 11, 2 PM` in the requested zone. */
|
|
25
|
+
declare function formatDateTimeShort(instant: string, timeZone?: string): string;
|
|
26
|
+
/** An hourly tooltip label relative to the rolling window's end date. */
|
|
27
|
+
declare function formatRelativeHourShort(hourStart: string, relativeTo: string, timeZone?: string): string;
|
|
15
28
|
/**
|
|
16
29
|
* The window the page requests, expressed in the viewer's own time zone so days
|
|
17
30
|
* line up with what they actually experienced.
|
|
18
31
|
*/
|
|
19
|
-
declare function makeWindow(days: number, now?: Date): UsageSummaryInput;
|
|
32
|
+
declare function makeWindow(days: number, now?: Date, resolution?: UsageResolution): UsageSummaryInput;
|
|
20
33
|
//#endregion
|
|
21
|
-
export { enumerateDays, formatCount, formatDayShort, formatPercent, formatTokens, formatUsd, makeWindow };
|
|
34
|
+
export { enumerateDays, enumerateHourStarts, formatCount, formatDateTimeShort, formatDayShort, formatHourShort, formatPercent, formatRelativeHourShort, formatTokens, formatUsd, makeWindow };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { iu as UsageDay } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/usageFormat.ts
|
|
3
3
|
/**
|
|
4
4
|
* Display formatting for the usage page.
|
|
@@ -66,25 +66,111 @@ function enumerateDays(sinceDay, untilDay) {
|
|
|
66
66
|
for (let cursor = start; cursor <= end; cursor += 864e5) days.push(new Date(cursor).toISOString().slice(0, 10));
|
|
67
67
|
return days;
|
|
68
68
|
}
|
|
69
|
+
const HOUR_MS = 3600 * 1e3;
|
|
70
|
+
/** Every fixed-duration bucket start in an hourly rolling window. */
|
|
71
|
+
function enumerateHourStarts(sinceTime, untilTime) {
|
|
72
|
+
const starts = [];
|
|
73
|
+
const start = Date.parse(sinceTime);
|
|
74
|
+
const end = Date.parse(untilTime);
|
|
75
|
+
if (Number.isNaN(start) || Number.isNaN(end) || end <= start) return starts;
|
|
76
|
+
for (let cursor = start; cursor < end; cursor += HOUR_MS) starts.push(new Date(cursor).toISOString());
|
|
77
|
+
return starts;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A rolling bucket start rendered in the viewer's requested time zone.
|
|
81
|
+
*
|
|
82
|
+
* Repeated wall-clock hours during a fall-back transition include their short
|
|
83
|
+
* zone name so the two distinct buckets remain distinguishable.
|
|
84
|
+
*/
|
|
85
|
+
function formatHourShort(hourStart, timeZone) {
|
|
86
|
+
const instant = new Date(hourStart);
|
|
87
|
+
if (Number.isNaN(instant.getTime())) return hourStart;
|
|
88
|
+
const options = timeZone === void 0 ? {} : { timeZone };
|
|
89
|
+
const hourFormat = new Intl.DateTimeFormat("en-US", {
|
|
90
|
+
...options,
|
|
91
|
+
hour: "numeric"
|
|
92
|
+
});
|
|
93
|
+
const wallHourFormat = new Intl.DateTimeFormat("en-CA", {
|
|
94
|
+
...options,
|
|
95
|
+
year: "numeric",
|
|
96
|
+
month: "2-digit",
|
|
97
|
+
day: "2-digit",
|
|
98
|
+
hour: "2-digit",
|
|
99
|
+
hourCycle: "h23"
|
|
100
|
+
});
|
|
101
|
+
const wallHour = wallHourFormat.format(instant);
|
|
102
|
+
if (![-36e5, HOUR_MS].some((offset) => wallHourFormat.format(new Date(instant.getTime() + offset)) === wallHour)) return hourFormat.format(instant);
|
|
103
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
104
|
+
...timeZone === void 0 ? {} : { timeZone },
|
|
105
|
+
hour: "numeric",
|
|
106
|
+
timeZoneName: "short"
|
|
107
|
+
}).format(instant);
|
|
108
|
+
}
|
|
109
|
+
/** `2026-08-11T14:37:00Z` to `Aug 11, 2 PM` in the requested zone. */
|
|
110
|
+
function formatDateTimeShort(instant, timeZone) {
|
|
111
|
+
const date = new Date(instant);
|
|
112
|
+
if (Number.isNaN(date.getTime())) return instant;
|
|
113
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
114
|
+
...timeZone === void 0 ? {} : { timeZone },
|
|
115
|
+
month: "short",
|
|
116
|
+
day: "numeric",
|
|
117
|
+
hour: "numeric"
|
|
118
|
+
}).format(date);
|
|
119
|
+
}
|
|
120
|
+
/** An hourly tooltip label relative to the rolling window's end date. */
|
|
121
|
+
function formatRelativeHourShort(hourStart, relativeTo, timeZone) {
|
|
122
|
+
const instant = new Date(hourStart);
|
|
123
|
+
const reference = new Date(relativeTo);
|
|
124
|
+
if (Number.isNaN(instant.getTime()) || Number.isNaN(reference.getTime())) return formatDateTimeShort(hourStart, timeZone);
|
|
125
|
+
const dayFormat = new Intl.DateTimeFormat("en-CA", {
|
|
126
|
+
...timeZone === void 0 ? {} : { timeZone },
|
|
127
|
+
year: "numeric",
|
|
128
|
+
month: "2-digit",
|
|
129
|
+
day: "2-digit"
|
|
130
|
+
});
|
|
131
|
+
const instantDay = Date.parse(`${dayFormat.format(instant)}T00:00:00Z`);
|
|
132
|
+
const referenceDay = Date.parse(`${dayFormat.format(reference)}T00:00:00Z`);
|
|
133
|
+
const calendarDaysAgo = Math.round((referenceDay - instantDay) / (24 * HOUR_MS));
|
|
134
|
+
const hour = formatHourShort(hourStart, timeZone);
|
|
135
|
+
if (calendarDaysAgo === 0) return `${hour} today`;
|
|
136
|
+
if (calendarDaysAgo === 1) return `${hour} yesterday`;
|
|
137
|
+
return formatDateTimeShort(hourStart, timeZone);
|
|
138
|
+
}
|
|
69
139
|
/**
|
|
70
140
|
* The window the page requests, expressed in the viewer's own time zone so days
|
|
71
141
|
* line up with what they actually experienced.
|
|
72
142
|
*/
|
|
73
|
-
function makeWindow(days, now = /* @__PURE__ */ new Date()) {
|
|
143
|
+
function makeWindow(days, now = /* @__PURE__ */ new Date(), resolution = "day") {
|
|
74
144
|
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
75
|
-
const
|
|
145
|
+
const format = new Intl.DateTimeFormat("en-CA", {
|
|
76
146
|
timeZone,
|
|
77
147
|
year: "numeric",
|
|
78
148
|
month: "2-digit",
|
|
79
149
|
day: "2-digit"
|
|
80
|
-
})
|
|
150
|
+
});
|
|
151
|
+
const untilDay = format.format(now);
|
|
152
|
+
if (resolution === "hour") {
|
|
153
|
+
const untilTimeMs = Math.floor(now.getTime() / 6e4) * 6e4;
|
|
154
|
+
const sinceTimeMs = untilTimeMs - 24 * HOUR_MS;
|
|
155
|
+
const sinceTime = new Date(sinceTimeMs);
|
|
156
|
+
const untilTime = new Date(untilTimeMs);
|
|
157
|
+
return {
|
|
158
|
+
sinceDay: UsageDay.make(format.format(sinceTime)),
|
|
159
|
+
untilDay: UsageDay.make(format.format(untilTime)),
|
|
160
|
+
timeZone,
|
|
161
|
+
resolution,
|
|
162
|
+
sinceTime: sinceTime.toISOString(),
|
|
163
|
+
untilTime: untilTime.toISOString()
|
|
164
|
+
};
|
|
165
|
+
}
|
|
81
166
|
const [year = 0, month = 1, dayOfMonth = 1] = untilDay.split("-").map((part) => Number.parseInt(part, 10));
|
|
82
167
|
const start = new Date(Date.UTC(year, month - 1, dayOfMonth - (days - 1)));
|
|
83
168
|
return {
|
|
84
169
|
sinceDay: UsageDay.make(start.toISOString().slice(0, 10)),
|
|
85
170
|
untilDay: UsageDay.make(untilDay),
|
|
86
|
-
timeZone
|
|
171
|
+
timeZone,
|
|
172
|
+
resolution
|
|
87
173
|
};
|
|
88
174
|
}
|
|
89
175
|
//#endregion
|
|
90
|
-
export { enumerateDays, formatCount, formatDayShort, formatPercent, formatTokens, formatUsd, makeWindow };
|
|
176
|
+
export { enumerateDays, enumerateHourStarts, formatCount, formatDateTimeShort, formatDayShort, formatHourShort, formatPercent, formatRelativeHourShort, formatTokens, formatUsd, makeWindow };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Dl as UsageSummary, vk as EnvironmentId, xl as UsageProviderKind } from "../shared.js";
|
|
2
2
|
//#region upstream-t3code/packages/shared/src/usageMerge.d.ts
|
|
3
3
|
interface EnvironmentUsage {
|
|
4
4
|
readonly environmentId: EnvironmentId;
|
|
@@ -30,6 +30,16 @@ interface DailyTotals {
|
|
|
30
30
|
totalTokens: number;
|
|
31
31
|
}>;
|
|
32
32
|
}
|
|
33
|
+
interface HourlyTotals {
|
|
34
|
+
readonly day: string;
|
|
35
|
+
readonly hourStart: string;
|
|
36
|
+
readonly costUsd: number;
|
|
37
|
+
readonly totalTokens: number;
|
|
38
|
+
readonly byProvider: ReadonlyMap<UsageProviderKind, {
|
|
39
|
+
costUsd: number;
|
|
40
|
+
totalTokens: number;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
33
43
|
interface CostQuality {
|
|
34
44
|
readonly providerReportedShare: number;
|
|
35
45
|
readonly modelPricedShare: number;
|
|
@@ -49,6 +59,7 @@ interface MergedUsage {
|
|
|
49
59
|
readonly providers: readonly ProviderTotals[];
|
|
50
60
|
readonly models: readonly ModelTotals[];
|
|
51
61
|
readonly daily: readonly DailyTotals[];
|
|
62
|
+
readonly hourly: readonly HourlyTotals[];
|
|
52
63
|
readonly costQuality: CostQuality;
|
|
53
64
|
/** Environments whose data was dropped as a duplicate of another's. */
|
|
54
65
|
readonly duplicateSources: readonly string[];
|
|
@@ -64,4 +75,4 @@ interface MergedUsage {
|
|
|
64
75
|
*/
|
|
65
76
|
declare function mergeUsage(environments: readonly EnvironmentUsage[], expectedContractVersion: number): MergedUsage;
|
|
66
77
|
//#endregion
|
|
67
|
-
export { CostQuality, DailyTotals, EnvironmentUsage, MergedUsage, ModelTotals, ProviderTotals, mergeUsage };
|
|
78
|
+
export { CostQuality, DailyTotals, EnvironmentUsage, HourlyTotals, MergedUsage, ModelTotals, ProviderTotals, mergeUsage };
|
|
@@ -75,6 +75,7 @@ const EMPTY_MERGED = {
|
|
|
75
75
|
providers: [],
|
|
76
76
|
models: [],
|
|
77
77
|
daily: [],
|
|
78
|
+
hourly: [],
|
|
78
79
|
costQuality: {
|
|
79
80
|
providerReportedShare: 0,
|
|
80
81
|
modelPricedShare: 0,
|
|
@@ -113,6 +114,7 @@ function mergeUsage(environments, expectedContractVersion) {
|
|
|
113
114
|
const providerAccumulator = /* @__PURE__ */ new Map();
|
|
114
115
|
const modelAccumulator = /* @__PURE__ */ new Map();
|
|
115
116
|
const dailyAccumulator = /* @__PURE__ */ new Map();
|
|
117
|
+
const hourlyAccumulator = /* @__PURE__ */ new Map();
|
|
116
118
|
const contributingEnvironments = [];
|
|
117
119
|
for (const environment of current) {
|
|
118
120
|
const { buckets, sessions: environmentSessions } = ownedContribution(environment, ownerByFingerprint);
|
|
@@ -165,6 +167,25 @@ function mergeUsage(environments, expectedContractVersion) {
|
|
|
165
167
|
dayProvider.totalTokens += tokens;
|
|
166
168
|
day.byProvider.set(bucket.provider, dayProvider);
|
|
167
169
|
dailyAccumulator.set(bucket.day, day);
|
|
170
|
+
if (bucket.hourStart !== void 0) {
|
|
171
|
+
const hour = hourlyAccumulator.get(bucket.hourStart) ?? {
|
|
172
|
+
day: bucket.day,
|
|
173
|
+
hourStart: bucket.hourStart,
|
|
174
|
+
costUsd: 0,
|
|
175
|
+
totalTokens: 0,
|
|
176
|
+
byProvider: /* @__PURE__ */ new Map()
|
|
177
|
+
};
|
|
178
|
+
hour.costUsd += bucket.costUsd;
|
|
179
|
+
hour.totalTokens += tokens;
|
|
180
|
+
const hourProvider = hour.byProvider.get(bucket.provider) ?? {
|
|
181
|
+
costUsd: 0,
|
|
182
|
+
totalTokens: 0
|
|
183
|
+
};
|
|
184
|
+
hourProvider.costUsd += bucket.costUsd;
|
|
185
|
+
hourProvider.totalTokens += tokens;
|
|
186
|
+
hour.byProvider.set(bucket.provider, hourProvider);
|
|
187
|
+
hourlyAccumulator.set(bucket.hourStart, hour);
|
|
188
|
+
}
|
|
168
189
|
}
|
|
169
190
|
}
|
|
170
191
|
const totalTokens = uncachedInputTokens + cachedInputTokens + cacheCreationTokens + outputTokens;
|
|
@@ -190,6 +211,7 @@ function mergeUsage(environments, expectedContractVersion) {
|
|
|
190
211
|
totalTokens: totals.totalTokens,
|
|
191
212
|
byProvider: totals.byProvider
|
|
192
213
|
})).sort((a, b) => a.day.localeCompare(b.day));
|
|
214
|
+
const hourly = [...hourlyAccumulator.values()].sort((a, b) => a.hourStart.localeCompare(b.hourStart));
|
|
193
215
|
return {
|
|
194
216
|
costUsd,
|
|
195
217
|
uncachedInputTokens,
|
|
@@ -203,6 +225,7 @@ function mergeUsage(environments, expectedContractVersion) {
|
|
|
203
225
|
providers,
|
|
204
226
|
models,
|
|
205
227
|
daily,
|
|
228
|
+
hourly,
|
|
206
229
|
costQuality: {
|
|
207
230
|
providerReportedShare: records === 0 ? 0 : providerReportedRecords / records,
|
|
208
231
|
unpricedShare: records === 0 ? 0 : unpricedRecords / records,
|