dsh-budget 0.1.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/CHANGELOG.md +26 -0
- package/LICENSE +201 -0
- package/README.es.md +140 -0
- package/README.hi.md +140 -0
- package/README.md +140 -0
- package/README.pt.md +140 -0
- package/README.zh.md +140 -0
- package/SECURITY.md +37 -0
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/cordis.patch.yml +73 -0
- package/lib/client.js +4893 -0
- package/lib/client.js.map +1 -0
- package/lib/index.js +1225 -0
- package/lib/typert.host.js +26 -0
- package/lib/types/aggregate/usage.d.ts +112 -0
- package/lib/types/aggregate/usage.d.ts.map +1 -0
- package/lib/types/client/BudgetTab.d.ts +18 -0
- package/lib/types/client/BudgetTab.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +35 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/locales.d.ts +42 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/present.d.ts +19 -0
- package/lib/types/client/present.d.ts.map +1 -0
- package/lib/types/client/remote.d.ts +270 -0
- package/lib/types/client/remote.d.ts.map +1 -0
- package/lib/types/client/styles.d.ts +12 -0
- package/lib/types/client/styles.d.ts.map +1 -0
- package/lib/types/command.d.ts +51 -0
- package/lib/types/command.d.ts.map +1 -0
- package/lib/types/config.d.ts +132 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/estimate/carbon.d.ts +128 -0
- package/lib/types/estimate/carbon.d.ts.map +1 -0
- package/lib/types/estimate/cost.d.ts +71 -0
- package/lib/types/estimate/cost.d.ts.map +1 -0
- package/lib/types/estimate/latency-stats.d.ts +111 -0
- package/lib/types/estimate/latency-stats.d.ts.map +1 -0
- package/lib/types/estimate/models.d.ts +29 -0
- package/lib/types/estimate/models.d.ts.map +1 -0
- package/lib/types/estimate/prices.d.ts +85 -0
- package/lib/types/estimate/prices.d.ts.map +1 -0
- package/lib/types/estimate/sanitize.d.ts +56 -0
- package/lib/types/estimate/sanitize.d.ts.map +1 -0
- package/lib/types/events.d.ts +57 -0
- package/lib/types/events.d.ts.map +1 -0
- package/lib/types/governance.d.ts +67 -0
- package/lib/types/governance.d.ts.map +1 -0
- package/lib/types/index.d.ts +50 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/service.d.ts +67 -0
- package/lib/types/service.d.ts.map +1 -0
- package/lib/types/typert.host.d.ts +258 -0
- package/lib/types/typert.host.d.ts.map +1 -0
- package/lib/types/wire.d.ts +629 -0
- package/lib/types/wire.d.ts.map +1 -0
- package/lib/wire-DVO8yw7L.js +4219 -0
- package/package.json +164 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { t as BUDGET_INVOCATIONS } from "./wire-DVO8yw7L.js";
|
|
2
|
+
//#region src/typert.host.ts
|
|
3
|
+
/**
|
|
4
|
+
* The hand-written Typert HOST manifest for `dsh-budget`, exported as
|
|
5
|
+
* `./typert` so the harness's typert-loader registers the `budget`
|
|
6
|
+
* status/setSettings/unblock invocations automatically when this plugin
|
|
7
|
+
* mounts. Same shape as a generator output (validated by the loader): package
|
|
8
|
+
* face, empty model and schemas, and the canonical invocation list shared
|
|
9
|
+
* with the client Remote contribution (`src/wire.ts`).
|
|
10
|
+
*
|
|
11
|
+
* @module dsh-budget/typert
|
|
12
|
+
*/
|
|
13
|
+
/** Host Typert manifest (validated by `@deepseek-ai/dsh-typert-loader`). */
|
|
14
|
+
const TYPERT = Object.freeze({
|
|
15
|
+
package: "dsh-budget",
|
|
16
|
+
face: "host",
|
|
17
|
+
schemas: Object.freeze([]),
|
|
18
|
+
invocations: BUDGET_INVOCATIONS,
|
|
19
|
+
model: Object.freeze({
|
|
20
|
+
services: Object.freeze([]),
|
|
21
|
+
events: Object.freeze([]),
|
|
22
|
+
objects: Object.freeze([])
|
|
23
|
+
})
|
|
24
|
+
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { TYPERT };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The usage aggregator: turns the session event stream into per-session,
|
|
3
|
+
* per-day, and per-month token/cost/carbon buckets plus per-model latency
|
|
4
|
+
* windows. Pure state and pure accounting — the caller feeds events and the
|
|
5
|
+
* aggregator owns no I/O, no timers, and no Cordis services, so every policy
|
|
6
|
+
* path is unit-testable without a harness.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-budget/aggregate
|
|
9
|
+
*/
|
|
10
|
+
import type { TokenUsage } from '@deepseek-ai/dsh-llm';
|
|
11
|
+
import type { ResolvedConfig } from '../config.ts';
|
|
12
|
+
/** One scope's token buckets (disjoint, mirroring TokenUsage). */
|
|
13
|
+
export interface TokenBuckets {
|
|
14
|
+
inputTokens: number;
|
|
15
|
+
outputTokens: number;
|
|
16
|
+
cacheReadTokens: number;
|
|
17
|
+
cacheWriteTokens: number;
|
|
18
|
+
}
|
|
19
|
+
/** One scope's aggregated usage. */
|
|
20
|
+
export interface ScopeUsage extends TokenBuckets {
|
|
21
|
+
costUsd: number;
|
|
22
|
+
carbonKg: number;
|
|
23
|
+
}
|
|
24
|
+
/** Empty usage record. */
|
|
25
|
+
export declare function emptyUsage(): ScopeUsage;
|
|
26
|
+
/** One model's aggregated usage plus latency statistics. */
|
|
27
|
+
export interface ModelUsage extends ScopeUsage {
|
|
28
|
+
provider: string;
|
|
29
|
+
model: string;
|
|
30
|
+
/** Latency samples kept for this model (ms). */
|
|
31
|
+
latencyMs: readonly number[];
|
|
32
|
+
}
|
|
33
|
+
/** One recorded threshold alert. */
|
|
34
|
+
export interface AlertRecord {
|
|
35
|
+
scope: 'session' | 'daily' | 'monthly';
|
|
36
|
+
kind: 'warn' | 'over';
|
|
37
|
+
at: number;
|
|
38
|
+
usedUsd: number;
|
|
39
|
+
capUsd: number;
|
|
40
|
+
}
|
|
41
|
+
/** UTC day key, e.g. `2026-08-16`. */
|
|
42
|
+
export declare function dayKey(timestamp: number): string;
|
|
43
|
+
/** UTC month key, e.g. `2026-08`. */
|
|
44
|
+
export declare function monthKey(timestamp: number): string;
|
|
45
|
+
/** Everything the panel and the /budget command read (session-attributed via {@link BudgetAggregator.snapshotFor}). */
|
|
46
|
+
export interface BudgetSnapshot {
|
|
47
|
+
session: ScopeUsage;
|
|
48
|
+
today: ScopeUsage;
|
|
49
|
+
thisMonth: ScopeUsage;
|
|
50
|
+
models: readonly ModelUsage[];
|
|
51
|
+
/** Alerts in reverse chronological order. */
|
|
52
|
+
alerts: readonly AlertRecord[];
|
|
53
|
+
blockedScopes: readonly ('session' | 'daily' | 'monthly')[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The runtime aggregator. All methods are synchronous; the caller invokes
|
|
57
|
+
* them from the session-event listener (the event hot path).
|
|
58
|
+
*/
|
|
59
|
+
export declare class BudgetAggregator {
|
|
60
|
+
private readonly config;
|
|
61
|
+
private readonly now;
|
|
62
|
+
private readonly state;
|
|
63
|
+
private readonly table;
|
|
64
|
+
/** @param config - resolved plugin config. @param now - clock (defaults to Date.now). */
|
|
65
|
+
constructor(config: ResolvedConfig, now?: () => number);
|
|
66
|
+
/** Update the current provider/model attribution from a request header. */
|
|
67
|
+
setAttribution(provider: string, model: string): void;
|
|
68
|
+
/** The current provider/model attribution (latest request header). */
|
|
69
|
+
attribution(): {
|
|
70
|
+
provider: string;
|
|
71
|
+
model: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Record one usage payload against the current attribution. Unknown or
|
|
75
|
+
* zero usage is a no-op.
|
|
76
|
+
*
|
|
77
|
+
* @param sessionId - owning session id (string form).
|
|
78
|
+
* @param usage - the token usage payload.
|
|
79
|
+
*/
|
|
80
|
+
recordUsage(sessionId: string, usage: TokenUsage): void;
|
|
81
|
+
/** Record one measured call duration for one model. */
|
|
82
|
+
recordLatency(model: string, durationMs: number): void;
|
|
83
|
+
/** Merge one usage record into a per-model map. */
|
|
84
|
+
private addModel;
|
|
85
|
+
/** Read one session's usage (empty when unknown). */
|
|
86
|
+
sessionUsage(sessionId: string): ScopeUsage;
|
|
87
|
+
/** Read today's usage. */
|
|
88
|
+
todayUsage(): ScopeUsage;
|
|
89
|
+
/** Read this month's usage. */
|
|
90
|
+
monthUsage(): ScopeUsage;
|
|
91
|
+
/** Per-model usage (today) with latency percentiles, sorted by cost. */
|
|
92
|
+
modelUsage(): ModelUsage[];
|
|
93
|
+
/** Record one threshold alert (bounded to the most recent 50). */
|
|
94
|
+
recordAlert(alert: AlertRecord): void;
|
|
95
|
+
/** Milliseconds since the last alert of the same scope+kind (Infinity when none). */
|
|
96
|
+
lastAlertAge(scope: 'session' | 'daily' | 'monthly', kind: 'warn' | 'over', at: number): number;
|
|
97
|
+
/** The current blocked scopes (budget crosses that the user has not lifted). */
|
|
98
|
+
get blockedScopes(): readonly ('session' | 'daily' | 'monthly')[];
|
|
99
|
+
/** Mark one scope blocked (over-limit with block/degrade policy). */
|
|
100
|
+
blockScope(scope: 'session' | 'daily' | 'monthly'): void;
|
|
101
|
+
/** Lift a block (user confirmation through /budget unblock or the panel). */
|
|
102
|
+
unblockScope(scope: 'session' | 'daily' | 'monthly'): void;
|
|
103
|
+
/**
|
|
104
|
+
* The per-scope snapshot for one session (the panel and the command
|
|
105
|
+
* attribute usage to the session that owns the view).
|
|
106
|
+
*
|
|
107
|
+
* @param sessionId - owning session id.
|
|
108
|
+
* @returns the session-attributed snapshot.
|
|
109
|
+
*/
|
|
110
|
+
snapshotFor(sessionId: string): BudgetSnapshot;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../../src/aggregate/usage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** The budget settings tab: usage bars, model breakdown, alerts, cap editors, and unblock actions. */
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
|
+
import type { BudgetStatus } from '../wire.ts';
|
|
5
|
+
/** Registration-side injected face: the budget RPCs (RemoteResult already unwrapped). */
|
|
6
|
+
export interface BudgetTabInjected {
|
|
7
|
+
/** Read the current Host snapshot. */
|
|
8
|
+
status: () => Promise<BudgetStatus>;
|
|
9
|
+
/** Apply runtime budget caps and alert switches. */
|
|
10
|
+
setSettings: (settingsJson: string) => Promise<BudgetStatus>;
|
|
11
|
+
/** Lift one blocked scope after user confirmation. */
|
|
12
|
+
unblock: (scope: string) => Promise<BudgetStatus>;
|
|
13
|
+
}
|
|
14
|
+
/** Full component props assembled by the Settings slot renderer. */
|
|
15
|
+
export type BudgetTabProps = PropsRuntime<'settings.plugins.tab'> & PropsLocale<'settings.budget'> & InjectFace<BudgetTabInjected>;
|
|
16
|
+
/** The budget tab body. */
|
|
17
|
+
export declare function BudgetTab({ status, setSettings, unblock, t }: BudgetTabProps): ReactNode;
|
|
18
|
+
//# sourceMappingURL=BudgetTab.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BudgetTab.d.ts","sourceRoot":"","sources":["../../../src/client/BudgetTab.tsx"],"names":[],"mappings":"AAAA,sGAAsG;AAEtG,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAE7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,yFAAyF;AACzF,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAA;IACnC,oDAAoD;IACpD,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;IAC5D,sDAAsD;IACtD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAA;CAClD;AAED,oEAAoE;AACpE,MAAM,MAAM,cAAc,GACxB,YAAY,CAAC,sBAAsB,CAAC,GAClC,WAAW,CAAC,iBAAiB,CAAC,GAC9B,UAAU,CAAC,iBAAiB,CAAC,CAAA;AAOjC,2BAA2B;AAC3B,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,cAAc,GAAG,SAAS,CAqLxF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `dsh-budget`, browser half: mounts the `budget` Remote contribution, then
|
|
3
|
+
* registers the budget tab into the Plugins settings section
|
|
4
|
+
* (`settings.plugins.tab`, id `budget`). All data arrives through the
|
|
5
|
+
* `remote.budget` namespace — the tab issues no other RPC and holds no state
|
|
6
|
+
* of its own beyond the edit form and the last loaded snapshot.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-budget/client
|
|
9
|
+
*/
|
|
10
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
11
|
+
import { type BudgetLocaleKey } from './locales.ts';
|
|
12
|
+
export type { BudgetTabInjected, BudgetTabProps } from './BudgetTab.tsx';
|
|
13
|
+
export type { BudgetLocaleKey } from './locales.ts';
|
|
14
|
+
export { formatAlertTime, formatMoney, scopePercent, scopeTone } from './present.ts';
|
|
15
|
+
export type { BudgetTone } from './present.ts';
|
|
16
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
17
|
+
interface LocaleNamespaceMap {
|
|
18
|
+
/** Budget settings tab copy. */
|
|
19
|
+
'settings.budget': BudgetLocaleKey;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Dictionary namespace owned by this plugin. */
|
|
23
|
+
export declare const NS = "settings.budget";
|
|
24
|
+
/** Plugin name: matches the package name, the graph row id, and the bundle id. */
|
|
25
|
+
export declare const name = "dsh-budget";
|
|
26
|
+
/** Services the tab reads; `remote.budget` appears once this plugin mounts its contribution. */
|
|
27
|
+
export declare const inject: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Browser plugin body: dictionaries, the scoped stylesheet, the Remote
|
|
30
|
+
* contribution mount, and the settings tab registration.
|
|
31
|
+
*
|
|
32
|
+
* @param ctx - client root context.
|
|
33
|
+
*/
|
|
34
|
+
export declare function apply(ctx: ClientContext): Promise<void>;
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAA;AAM3E,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAM3D,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACxE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACpF,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,gCAAgC;QAChC,iBAAiB,EAAE,eAAe,CAAA;KACnC;CACF;AAED,iDAAiD;AACjD,eAAO,MAAM,EAAE,oBAAoB,CAAA;AAEnC,kFAAkF;AAClF,eAAO,MAAM,IAAI,eAAe,CAAA;AAEhC,gGAAgG;AAChG,eAAO,MAAM,MAAM,UAA4C,CAAA;AAE/D;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B7D"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Copy dictionaries for the budget settings tab (en/zh, matching the locale registry constraint). */
|
|
2
|
+
/** Simplified Chinese dictionary. */
|
|
3
|
+
export declare const zh: {
|
|
4
|
+
readonly tab: "预算";
|
|
5
|
+
readonly loading: "正在读取预算用量…";
|
|
6
|
+
readonly error: "暂时无法读取预算用量。";
|
|
7
|
+
readonly retry: "重试";
|
|
8
|
+
readonly scopes: "预算作用域";
|
|
9
|
+
readonly session: "会话";
|
|
10
|
+
readonly daily: "今日";
|
|
11
|
+
readonly monthly: "本月";
|
|
12
|
+
readonly unlimited: "不限";
|
|
13
|
+
readonly blocked: "已阻断";
|
|
14
|
+
readonly unblock: "解除阻断";
|
|
15
|
+
readonly usage: "用量";
|
|
16
|
+
readonly carbon: "碳足迹";
|
|
17
|
+
readonly models: "模型用量";
|
|
18
|
+
readonly model: "模型";
|
|
19
|
+
readonly cost: "费用";
|
|
20
|
+
readonly tokens: "tokens";
|
|
21
|
+
readonly latency: "p50 延迟";
|
|
22
|
+
readonly alerts: "告警";
|
|
23
|
+
readonly noAlerts: "暂无告警记录。";
|
|
24
|
+
readonly warnAlert: "阈值告警";
|
|
25
|
+
readonly overAlert: "超限告警";
|
|
26
|
+
readonly caps: "预算上限(USD)";
|
|
27
|
+
readonly sessionCap: "会话上限";
|
|
28
|
+
readonly dailyCap: "每日上限";
|
|
29
|
+
readonly monthlyCap: "每月上限";
|
|
30
|
+
readonly capUnlimited: "留空或 0 表示不限";
|
|
31
|
+
readonly alertsEnabled: "启用阈值告警";
|
|
32
|
+
readonly desktopNotifications: "浏览器桌面通知";
|
|
33
|
+
readonly save: "保存";
|
|
34
|
+
readonly saved: "已保存(会话内生效,重载后恢复 cordis.yml 配置)";
|
|
35
|
+
readonly degraded: "已降级至";
|
|
36
|
+
readonly history: "最近告警";
|
|
37
|
+
};
|
|
38
|
+
/** English dictionary (source of truth for keys). */
|
|
39
|
+
export declare const en: Record<keyof typeof zh, string>;
|
|
40
|
+
/** Every dictionary key. */
|
|
41
|
+
export type BudgetLocaleKey = keyof typeof zh;
|
|
42
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,sGAAsG;AAEtG,qCAAqC;AACrC,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCL,CAAA;AAEV,qDAAqD;AACrD,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,EAAE,MAAM,CAkCrC,CAAA;AAEV,4BAA4B;AAC5B,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure presentation helpers for the budget tab: money formatting and one
|
|
3
|
+
* scope row's tone. Pure functions of the wire payload — replay-safe and
|
|
4
|
+
* unit-testable without a browser.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-budget/client/present
|
|
7
|
+
*/
|
|
8
|
+
import type { BudgetStatus, ScopeLine } from '../wire.ts';
|
|
9
|
+
/** One scope row's bar tone. */
|
|
10
|
+
export type BudgetTone = 'ok' | 'warn' | 'over';
|
|
11
|
+
/** Format one USD amount through the snapshot's display currency. */
|
|
12
|
+
export declare function formatMoney(status: BudgetStatus, usd: number): string;
|
|
13
|
+
/** The tone for one scope line. */
|
|
14
|
+
export declare function scopeTone(line: ScopeLine, warnRatio: number, blocked: boolean): BudgetTone;
|
|
15
|
+
/** The bar width (percent, 0..100) for one scope line. */
|
|
16
|
+
export declare function scopePercent(line: ScopeLine): number;
|
|
17
|
+
/** Local wall-clock time for one alert timestamp. */
|
|
18
|
+
export declare function formatAlertTime(at: number): string;
|
|
19
|
+
//# sourceMappingURL=present.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../../src/client/present.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEzD,gCAAgC;AAChC,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;AAE/C,qEAAqE;AACrE,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,mCAAmC;AACnC,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAI1F;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAGpD;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client-side Remote face of the `budget` namespace: the hand-written
|
|
3
|
+
* `TypertRemoteContribution` mounted through `ctx.remote.$mount`, plus the
|
|
4
|
+
* declaration merging that types `ctx.remote.budget`. The descriptor list is
|
|
5
|
+
* shared with the host `./typert` manifest (`../wire.ts`), so the two faces
|
|
6
|
+
* can never drift.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-budget/client/remote
|
|
9
|
+
*/
|
|
10
|
+
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
11
|
+
import type { BudgetStatus } from '../wire.ts';
|
|
12
|
+
declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
13
|
+
interface TypertRemoteNamespace$budget {
|
|
14
|
+
/** Read the current budget snapshot (session-attributed). */
|
|
15
|
+
status: (sessionId?: string) => Promise<RemoteResult<BudgetStatus>>;
|
|
16
|
+
/** Apply runtime budget caps and alert switches (panel). */
|
|
17
|
+
setSettings: (settingsJson: string) => Promise<RemoteResult<BudgetStatus>>;
|
|
18
|
+
/** Lift one blocked scope after user confirmation. */
|
|
19
|
+
unblock: (scope: string) => Promise<RemoteResult<BudgetStatus>>;
|
|
20
|
+
}
|
|
21
|
+
interface TypertRemoteMap {
|
|
22
|
+
'budget/status': (sessionId?: string) => Promise<RemoteResult<BudgetStatus>>;
|
|
23
|
+
'budget/setSettings': (settingsJson: string) => Promise<RemoteResult<BudgetStatus>>;
|
|
24
|
+
'budget/unblock': (scope: string) => Promise<RemoteResult<BudgetStatus>>;
|
|
25
|
+
}
|
|
26
|
+
interface TypertRemoteNamespaceMap {
|
|
27
|
+
budget: TypertRemoteNamespace$budget;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** The client Remote contribution for the `budget` namespace. */
|
|
31
|
+
export declare const BUDGET_REMOTE: Readonly<{
|
|
32
|
+
package: string;
|
|
33
|
+
descriptors: readonly (Readonly<{
|
|
34
|
+
readonly id: "dsh-budget#budget/status";
|
|
35
|
+
readonly service: "budget";
|
|
36
|
+
readonly namespace: "budget";
|
|
37
|
+
readonly method: "status";
|
|
38
|
+
readonly invocation: Readonly<{
|
|
39
|
+
kind: "direct";
|
|
40
|
+
}>;
|
|
41
|
+
readonly parameters: readonly never[];
|
|
42
|
+
readonly result: Readonly<{
|
|
43
|
+
mode: "strict";
|
|
44
|
+
typeSymbol: "dsh-budget/types#BudgetStatus";
|
|
45
|
+
schema: import("zod").ZodObject<{
|
|
46
|
+
scopes: import("zod").ZodArray<import("zod").ZodObject<{
|
|
47
|
+
scope: import("zod").ZodEnum<{
|
|
48
|
+
session: "session";
|
|
49
|
+
daily: "daily";
|
|
50
|
+
monthly: "monthly";
|
|
51
|
+
}>;
|
|
52
|
+
capUsd: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
53
|
+
usedUsd: import("zod").ZodNumber;
|
|
54
|
+
ratio: import("zod").ZodNumber;
|
|
55
|
+
tokens: import("zod").ZodNumber;
|
|
56
|
+
carbonKg: import("zod").ZodNumber;
|
|
57
|
+
}, import("zod/v4/core").$strip>>;
|
|
58
|
+
models: import("zod").ZodArray<import("zod").ZodObject<{
|
|
59
|
+
provider: import("zod").ZodString;
|
|
60
|
+
model: import("zod").ZodString;
|
|
61
|
+
inputTokens: import("zod").ZodNumber;
|
|
62
|
+
outputTokens: import("zod").ZodNumber;
|
|
63
|
+
costUsd: import("zod").ZodNumber;
|
|
64
|
+
carbonKg: import("zod").ZodNumber;
|
|
65
|
+
latency: import("zod").ZodObject<{
|
|
66
|
+
min: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
67
|
+
p50: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
68
|
+
p95: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
69
|
+
max: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
70
|
+
samples: import("zod").ZodNumber;
|
|
71
|
+
}, import("zod/v4/core").$strip>;
|
|
72
|
+
}, import("zod/v4/core").$strip>>;
|
|
73
|
+
alerts: import("zod").ZodArray<import("zod").ZodObject<{
|
|
74
|
+
scope: import("zod").ZodEnum<{
|
|
75
|
+
session: "session";
|
|
76
|
+
daily: "daily";
|
|
77
|
+
monthly: "monthly";
|
|
78
|
+
}>;
|
|
79
|
+
kind: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<"warn">, import("zod").ZodLiteral<"over">]>;
|
|
80
|
+
at: import("zod").ZodNumber;
|
|
81
|
+
usedUsd: import("zod").ZodNumber;
|
|
82
|
+
capUsd: import("zod").ZodNumber;
|
|
83
|
+
}, import("zod/v4/core").$strip>>;
|
|
84
|
+
blockedScopes: import("zod").ZodArray<import("zod").ZodEnum<{
|
|
85
|
+
session: "session";
|
|
86
|
+
daily: "daily";
|
|
87
|
+
monthly: "monthly";
|
|
88
|
+
}>>;
|
|
89
|
+
currency: import("zod").ZodObject<{
|
|
90
|
+
code: import("zod").ZodString;
|
|
91
|
+
rate: import("zod").ZodNumber;
|
|
92
|
+
decimals: import("zod").ZodNumber;
|
|
93
|
+
}, import("zod/v4/core").$strip>;
|
|
94
|
+
alertsEnabled: import("zod").ZodBoolean;
|
|
95
|
+
desktopNotifications: import("zod").ZodBoolean;
|
|
96
|
+
degradedModel: import("zod").ZodNullable<import("zod").ZodString>;
|
|
97
|
+
}, import("zod/v4/core").$strip>;
|
|
98
|
+
}>;
|
|
99
|
+
readonly sourceLocation: Readonly<{
|
|
100
|
+
file: "src/wire.ts";
|
|
101
|
+
line: 1;
|
|
102
|
+
column: 1;
|
|
103
|
+
}>;
|
|
104
|
+
}> | Readonly<{
|
|
105
|
+
readonly id: "dsh-budget#budget/setSettings";
|
|
106
|
+
readonly service: "budget";
|
|
107
|
+
readonly namespace: "budget";
|
|
108
|
+
readonly method: "setSettings";
|
|
109
|
+
readonly invocation: Readonly<{
|
|
110
|
+
kind: "direct";
|
|
111
|
+
}>;
|
|
112
|
+
readonly parameters: readonly Readonly<{
|
|
113
|
+
name: string;
|
|
114
|
+
wire: string;
|
|
115
|
+
source: "json";
|
|
116
|
+
codec: Readonly<{
|
|
117
|
+
mode: "strict";
|
|
118
|
+
typeSymbol: "dsh-budget/types#BudgetSettingsJson";
|
|
119
|
+
schema: import("zod").ZodString;
|
|
120
|
+
}>;
|
|
121
|
+
}>[];
|
|
122
|
+
readonly result: Readonly<{
|
|
123
|
+
mode: "strict";
|
|
124
|
+
typeSymbol: "dsh-budget/types#BudgetStatus";
|
|
125
|
+
schema: import("zod").ZodObject<{
|
|
126
|
+
scopes: import("zod").ZodArray<import("zod").ZodObject<{
|
|
127
|
+
scope: import("zod").ZodEnum<{
|
|
128
|
+
session: "session";
|
|
129
|
+
daily: "daily";
|
|
130
|
+
monthly: "monthly";
|
|
131
|
+
}>;
|
|
132
|
+
capUsd: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
133
|
+
usedUsd: import("zod").ZodNumber;
|
|
134
|
+
ratio: import("zod").ZodNumber;
|
|
135
|
+
tokens: import("zod").ZodNumber;
|
|
136
|
+
carbonKg: import("zod").ZodNumber;
|
|
137
|
+
}, import("zod/v4/core").$strip>>;
|
|
138
|
+
models: import("zod").ZodArray<import("zod").ZodObject<{
|
|
139
|
+
provider: import("zod").ZodString;
|
|
140
|
+
model: import("zod").ZodString;
|
|
141
|
+
inputTokens: import("zod").ZodNumber;
|
|
142
|
+
outputTokens: import("zod").ZodNumber;
|
|
143
|
+
costUsd: import("zod").ZodNumber;
|
|
144
|
+
carbonKg: import("zod").ZodNumber;
|
|
145
|
+
latency: import("zod").ZodObject<{
|
|
146
|
+
min: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
147
|
+
p50: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
148
|
+
p95: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
149
|
+
max: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
150
|
+
samples: import("zod").ZodNumber;
|
|
151
|
+
}, import("zod/v4/core").$strip>;
|
|
152
|
+
}, import("zod/v4/core").$strip>>;
|
|
153
|
+
alerts: import("zod").ZodArray<import("zod").ZodObject<{
|
|
154
|
+
scope: import("zod").ZodEnum<{
|
|
155
|
+
session: "session";
|
|
156
|
+
daily: "daily";
|
|
157
|
+
monthly: "monthly";
|
|
158
|
+
}>;
|
|
159
|
+
kind: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<"warn">, import("zod").ZodLiteral<"over">]>;
|
|
160
|
+
at: import("zod").ZodNumber;
|
|
161
|
+
usedUsd: import("zod").ZodNumber;
|
|
162
|
+
capUsd: import("zod").ZodNumber;
|
|
163
|
+
}, import("zod/v4/core").$strip>>;
|
|
164
|
+
blockedScopes: import("zod").ZodArray<import("zod").ZodEnum<{
|
|
165
|
+
session: "session";
|
|
166
|
+
daily: "daily";
|
|
167
|
+
monthly: "monthly";
|
|
168
|
+
}>>;
|
|
169
|
+
currency: import("zod").ZodObject<{
|
|
170
|
+
code: import("zod").ZodString;
|
|
171
|
+
rate: import("zod").ZodNumber;
|
|
172
|
+
decimals: import("zod").ZodNumber;
|
|
173
|
+
}, import("zod/v4/core").$strip>;
|
|
174
|
+
alertsEnabled: import("zod").ZodBoolean;
|
|
175
|
+
desktopNotifications: import("zod").ZodBoolean;
|
|
176
|
+
degradedModel: import("zod").ZodNullable<import("zod").ZodString>;
|
|
177
|
+
}, import("zod/v4/core").$strip>;
|
|
178
|
+
}>;
|
|
179
|
+
readonly sourceLocation: Readonly<{
|
|
180
|
+
file: "src/wire.ts";
|
|
181
|
+
line: 1;
|
|
182
|
+
column: 1;
|
|
183
|
+
}>;
|
|
184
|
+
}> | Readonly<{
|
|
185
|
+
readonly id: "dsh-budget#budget/unblock";
|
|
186
|
+
readonly service: "budget";
|
|
187
|
+
readonly namespace: "budget";
|
|
188
|
+
readonly method: "unblock";
|
|
189
|
+
readonly invocation: Readonly<{
|
|
190
|
+
kind: "direct";
|
|
191
|
+
}>;
|
|
192
|
+
readonly parameters: readonly Readonly<{
|
|
193
|
+
name: string;
|
|
194
|
+
wire: string;
|
|
195
|
+
source: "json";
|
|
196
|
+
codec: Readonly<{
|
|
197
|
+
mode: "strict";
|
|
198
|
+
typeSymbol: "dsh-budget/types#BudgetUnblockScope";
|
|
199
|
+
schema: import("zod").ZodEnum<{
|
|
200
|
+
session: "session";
|
|
201
|
+
daily: "daily";
|
|
202
|
+
monthly: "monthly";
|
|
203
|
+
}>;
|
|
204
|
+
}>;
|
|
205
|
+
}>[];
|
|
206
|
+
readonly result: Readonly<{
|
|
207
|
+
mode: "strict";
|
|
208
|
+
typeSymbol: "dsh-budget/types#BudgetStatus";
|
|
209
|
+
schema: import("zod").ZodObject<{
|
|
210
|
+
scopes: import("zod").ZodArray<import("zod").ZodObject<{
|
|
211
|
+
scope: import("zod").ZodEnum<{
|
|
212
|
+
session: "session";
|
|
213
|
+
daily: "daily";
|
|
214
|
+
monthly: "monthly";
|
|
215
|
+
}>;
|
|
216
|
+
capUsd: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
217
|
+
usedUsd: import("zod").ZodNumber;
|
|
218
|
+
ratio: import("zod").ZodNumber;
|
|
219
|
+
tokens: import("zod").ZodNumber;
|
|
220
|
+
carbonKg: import("zod").ZodNumber;
|
|
221
|
+
}, import("zod/v4/core").$strip>>;
|
|
222
|
+
models: import("zod").ZodArray<import("zod").ZodObject<{
|
|
223
|
+
provider: import("zod").ZodString;
|
|
224
|
+
model: import("zod").ZodString;
|
|
225
|
+
inputTokens: import("zod").ZodNumber;
|
|
226
|
+
outputTokens: import("zod").ZodNumber;
|
|
227
|
+
costUsd: import("zod").ZodNumber;
|
|
228
|
+
carbonKg: import("zod").ZodNumber;
|
|
229
|
+
latency: import("zod").ZodObject<{
|
|
230
|
+
min: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
231
|
+
p50: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
232
|
+
p95: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
233
|
+
max: import("zod").ZodNullable<import("zod").ZodNumber>;
|
|
234
|
+
samples: import("zod").ZodNumber;
|
|
235
|
+
}, import("zod/v4/core").$strip>;
|
|
236
|
+
}, import("zod/v4/core").$strip>>;
|
|
237
|
+
alerts: import("zod").ZodArray<import("zod").ZodObject<{
|
|
238
|
+
scope: import("zod").ZodEnum<{
|
|
239
|
+
session: "session";
|
|
240
|
+
daily: "daily";
|
|
241
|
+
monthly: "monthly";
|
|
242
|
+
}>;
|
|
243
|
+
kind: import("zod").ZodUnion<readonly [import("zod").ZodLiteral<"warn">, import("zod").ZodLiteral<"over">]>;
|
|
244
|
+
at: import("zod").ZodNumber;
|
|
245
|
+
usedUsd: import("zod").ZodNumber;
|
|
246
|
+
capUsd: import("zod").ZodNumber;
|
|
247
|
+
}, import("zod/v4/core").$strip>>;
|
|
248
|
+
blockedScopes: import("zod").ZodArray<import("zod").ZodEnum<{
|
|
249
|
+
session: "session";
|
|
250
|
+
daily: "daily";
|
|
251
|
+
monthly: "monthly";
|
|
252
|
+
}>>;
|
|
253
|
+
currency: import("zod").ZodObject<{
|
|
254
|
+
code: import("zod").ZodString;
|
|
255
|
+
rate: import("zod").ZodNumber;
|
|
256
|
+
decimals: import("zod").ZodNumber;
|
|
257
|
+
}, import("zod/v4/core").$strip>;
|
|
258
|
+
alertsEnabled: import("zod").ZodBoolean;
|
|
259
|
+
desktopNotifications: import("zod").ZodBoolean;
|
|
260
|
+
degradedModel: import("zod").ZodNullable<import("zod").ZodString>;
|
|
261
|
+
}, import("zod/v4/core").$strip>;
|
|
262
|
+
}>;
|
|
263
|
+
readonly sourceLocation: Readonly<{
|
|
264
|
+
file: "src/wire.ts";
|
|
265
|
+
line: 1;
|
|
266
|
+
column: 1;
|
|
267
|
+
}>;
|
|
268
|
+
}>)[];
|
|
269
|
+
}>;
|
|
270
|
+
//# sourceMappingURL=remote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../../src/client/remote.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,kCAAkC,CAAA;AAE9F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,4BAA4B;QACpC,6DAA6D;QAC7D,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAA;QACnE,4DAA4D;QAC5D,WAAW,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAA;QAC1E,sDAAsD;QACtD,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAA;KAChE;IACD,UAAU,eAAe;QACvB,eAAe,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAA;QAC5E,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAA;QACnF,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAA;KACzE;IACD,UAAU,wBAAwB;QAChC,MAAM,EAAE,4BAA4B,CAAA;KACrC;CACF;AAED,iEAAiE;AACjE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGW,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scoped stylesheet for the budget tab. Standalone client bundles cannot use
|
|
3
|
+
* the in-repo CSS-module pipeline, so the sheet ships as a string and is
|
|
4
|
+
* installed effect-scoped into a `<style data-dsh-budget>` element. Every
|
|
5
|
+
* selector is scoped under `[data-dsh-budget]` and uses theme design tokens
|
|
6
|
+
* only, so it follows both color schemes.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-budget/client/styles
|
|
9
|
+
*/
|
|
10
|
+
/** One `<style>` installation; returns the exact disposer that removes it. */
|
|
11
|
+
export declare function installBudgetStyles(): () => void;
|
|
12
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/client/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAC9E,wBAAgB,mBAAmB,IAAI,MAAM,IAAI,CAQhD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `/budget` command: per-scope overview with aggregated tokens, cost,
|
|
3
|
+
* carbon and latency, plus `unblock <scope>` and `models` subcommands.
|
|
4
|
+
* Output is model-readable and reconstructable from the session log (the
|
|
5
|
+
* `command/run` + `command/done` events record the invocation; the
|
|
6
|
+
* `budget/alert`/`budget/block` events record every threshold transition).
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-budget/command
|
|
9
|
+
*/
|
|
10
|
+
import type { CommandDefinition } from '@deepseek-ai/dsh-commands';
|
|
11
|
+
import { sanitizeText } from './estimate/sanitize.ts';
|
|
12
|
+
import type { BudgetService } from './service.ts';
|
|
13
|
+
import type { BudgetStatus, BudgetScope } from './wire.ts';
|
|
14
|
+
/** Command output language. */
|
|
15
|
+
export type BudgetCommandLanguage = 'en' | 'zh';
|
|
16
|
+
/** Message bundle per language. */
|
|
17
|
+
interface Messages {
|
|
18
|
+
hint: string;
|
|
19
|
+
unlimited: string;
|
|
20
|
+
blocked: string;
|
|
21
|
+
usage: string;
|
|
22
|
+
unknownScope: (scope: string) => string;
|
|
23
|
+
unblocked: (scope: string) => string;
|
|
24
|
+
noModels: string;
|
|
25
|
+
}
|
|
26
|
+
/** Render the overview body for one snapshot. */
|
|
27
|
+
export declare function renderBudgetOverview(status: BudgetStatus, messages: Messages): string;
|
|
28
|
+
/** Parse the raw input after `/budget`. */
|
|
29
|
+
export declare function parseBudgetArgs(rawInput: string): {
|
|
30
|
+
kind: 'overview';
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'unblock';
|
|
33
|
+
scope: BudgetScope;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'models';
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'usage';
|
|
38
|
+
};
|
|
39
|
+
/** Render the per-model breakdown body. */
|
|
40
|
+
export declare function renderBudgetModels(status: BudgetStatus, _messages: Messages): string;
|
|
41
|
+
/**
|
|
42
|
+
* Build the `/budget` command definition.
|
|
43
|
+
*
|
|
44
|
+
* @param service - the budget service (snapshot + unblock).
|
|
45
|
+
* @param language - output language.
|
|
46
|
+
* @returns the command definition.
|
|
47
|
+
*/
|
|
48
|
+
export declare function budgetCommand(service: BudgetService, language?: BudgetCommandLanguage): CommandDefinition;
|
|
49
|
+
/** Sanitize helper re-export for display callers. */
|
|
50
|
+
export { sanitizeText };
|
|
51
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/command.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE1D,+BAA+B;AAC/B,MAAM,MAAM,qBAAqB,GAAG,IAAI,GAAG,IAAI,CAAA;AAE/C,mCAAmC;AACnC,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACpC,QAAQ,EAAE,MAAM,CAAA;CACjB;AA4BD,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAuBrF;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAC5C;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAOpB;AAED,2CAA2C;AAC3C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,GAAG,MAAM,CAMpF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,GAAE,qBAA4B,GAAG,iBAAiB,CAyB/G;AAED,qDAAqD;AACrD,OAAO,EAAE,YAAY,EAAE,CAAA"}
|